From a6cda3752315e24364ece54209e5dd8c6e23f65f Mon Sep 17 00:00:00 2001 From: HayesGordon Date: Mon, 7 Jul 2025 16:37:21 +0000 Subject: [PATCH] feat(flutter): replace old implementation with rive_native for flutter (#10033) b21adb4564 * chore: hack use pub published rive version to sidestep current lottie conversion tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: purge old dart flutter code, tests, and samples * feat!: rive_native updates for rive flutter usage * feat: add rive_native to rive_flutter * chore: update rive flutter example app * docs: update CHANGELOG with migration info * docs: update README feature: scripting in editor (#10086) 7be3a0fe02 feat(webgpu): Finish input attachments for "subpassLoad" mode (#10115) f838e94a95 fix: release nested artboard animation resources when clearing (#10116) e3a68dff11 release nested artboard animation resources when clearing chore(webgpu): Update Wagyu names (#10114) cc9f175c5e feat(vulkan): MSAA (#10107) a9d49ca4e6 Implement the MSAA codepath on Vulkan. This finalizes our Vulkan support because we now can work on core 1.0 with no extensions. Disable timestamp with scroll physics (#10111) d8197feca5 Noticed some inconsistencies with scrolling with the pointerEvent timestamp implementation on desktop and web editor that need investigation. For now, disable using the timestamp passed down to rive native (revert to how it was working before) until I have time to investigate further. feature: add image based conditions (#10108) 247b3b00e8 add image based conditions reafactor(CommandQueue): added dependency map between files->artboards->statemachines (#10106) 1d45c6418d Added dependency between state machines and the artboards they are created from. Added dependency between artboards and the file they are made from Made all dependencies get cleaned up correctly when owning dependency is deleted. feat(CommandQueue): Several needed features (#10097) cf63e43d70 * added way to get default view model for a given artboard * added request Id to errors and mouse events * finished tests * order matter when getting deleted apperently runtime: get rid of the HitTextRun destructor (#10092) fc5abebaec context: https://2dimensions.slack.com/archives/CLLCU09T6/p1751307412381219 Sometimes it causes crashes on Unity. This destructor existed because I was worried the glyph contours could take up a lot of space and computation when the state machine is not playing. But perhaps that's better than crashing runtimes. fix: get text fallback to use clustered unicode points too (#10078) 4d5037b42d test: Render android/vulkan goldens to the device display (#10074) f6623687a8 chore(ci): Turn on ASAN for some golden tests (#10019) 4a81463748 chore(ci): Turn on ASAN for golden tests chore: Simplify testing configs (#10072) b1793e755e Rather than having an explosion of enums for all the different backend configs, us very basic backend enums (gl, vulkan, metal, etc.), and capture all the permutations in the separate BackendParams struct. Nnnn data bind artboards 4 (#10038) 32f0d6d0a0 * add js runtime support feat(gl): Use KHR_blend_equation_advanced (#10067) 308480cf12 We previously only worked with KHR_blend_equation_advanced_coherent, but Samsung Xclipse GPUs only support the noncoherent version. Add a codepath that makes use of the noncoherent extension so we don't have to copy out a dst texture on these GPUs. This improves perf on the "Rope" scene from 5.5fps -> 15.1, which is a decent stopgap, but considering Vulkan currently runs at 108fps, we should probably mostly just focus on switching to Vulkan. fix(gl): Make the clip-plane ban on ANGLE drivers more comprehensive (#10066) d3e42c99b7 Detect ANGLE drivers by checking the GL_VERSION string *and* GL_RENDERER. On some devices, GL_VERSION does not say "ANGLE" but GL_RENDERER does. Block both GL_ANGLE_clip_cull_distance and GL_EXT_clip_cull_distance on ANGLE drivers. This fixes the "disco" bug with dancing triangles on Xclipse devices. test: More comprehensive testing for offscreen gms (#10055) 05d64b548f Rename texture_target_gl* gms to offscreen_render_target*. Implement offscreen render targets for Vulkan testing. Add permutations for a "riveRenderable" flag, which disables input attachment support on vulkan, and will disable UAV support on D3D. fix: rive_native plugin isolation (#10062) ded9340fad * chore: refactor globals for rive_native * feat: flutter renderer starting to work * chore: refactor web for multi window * chore: add multi window example * chore: cleanup * fix: make raw text for multiwindow * feat: support multiple plugin instances in windows * feat: handle multi_window in windows * feat: multi plugin support on iOS and Android * chore: clang format * chore: add get render context to linux * chore: don’t get factory in test * chore: remove multi-window example fix: use reverse iterator (#10057) 4fd30da275 * chore: use reverse iterator * chore: fix iterator * chore: try on github macos * chore: retry docs: Remove Skia from the runtime readme (#10043) 092566581a featt(CommandQueue): Added internal file asset loader (#10040) d13f8c2bf6 * started file asset implementation * asset loader implemented * started adding tests * updated fonts and audio to validate before returning an object. * audio source and font tests * added deleted callback tests for audio source and fonts * fixed compiler issues for non windows clang * updated cargo checks to latest rive_hb * msvc maudio does not support mp3. use wav instead * Updated based on PR comments chore: update list related classes to use RCP (#10032) 23c446feb4 * finish artboard component list rcp featue: add artboard data bind support (#9996) be0b691d9b * add artboard data bind support feat(CommandQueue): Added error messages for each type of error that could happen (#10020) 9af17212ca * started implementing error messages * send errors to command q as well as print to cerr * started adding tests for error messages * started file error tests * file error tests * render image error tests * state machine error tets * PR suggestion to convert template function to helper class * prevent mixup for 32 bit platforms feature(CommandQueue): View Model Properties finished (#9993) 1d144e0d61 * added renderimagehandle and fileLoaded and enumsListe * coded out lists * added tests for list * property subscriptions complete * Added abililty to fire triggers * added tests code cov vaught * better name * ASAN for unit tests (#9997) chore: enable asan * changes requested by PR comments * addressed PR comment * enum renames * feat: add asan for tests * chore: missed lua file * chore: remove windows asan for now * remove extra ref * update print text Use Flutter's PointerEvent timeStamp to compute elapsed time for scrolling (#10013) 94ee0804b8 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. feat: add hash to rcp (#10018) 22e314a8df feat: add has to rcp Nnnn separate clear and unbind (#9888) f22462bd78 Nnnn separate clear and unbind second batch of fixes (#10014) 3c09bb1e7f rcp file assets (#10016) ecdf58f54b * feat: rcp_file_asset feature: add support for comparing with self (#9984) f0da7e9f27 * add support for comparing with self fix: rectangles to contour heap use after free (#10005) 67811c029d fix memory issues with data binding (#10002) ca0963da48 * fix memory issues with data binding fix: recursively duplicate instances when creating view models from a… (#9995) 8cf21b7fee * fix: recursively duplicate instances when creating view models from a number to list converter Initialize pointer to nullptr (#9989) e35082ebdc Fix scroll continued acceleration (#9994) 7e9d2b610f Fixes a bug (#9985) where clicking after a scroll could result in continual scrolling when the mouse isn't moved. chore(webgpu): Replace JS bindings with Wagyu (#9986) c05ef4daaa add color custom property (#9181) de384615b2 * add color custom property fix: Fix WebGPU sampler bindings (#9976) 6e3a82253a Samplers broke on WebGPU because we didn't have CI testing. Fix the samplers and set up a CI job to run through the WebGPU tests on Dawn to ensure we don't break this again. chore: refactor databind update cycle (#9863) 891f65794c * advance data binds per artboard update keys (#9949) 88befa489b * update keys * update file for test Fix feathering assertion from padding double cusps (#9940) d5140c06b9 add list to length converter (#9930) 3d3767270c test: Update fuzzer to support real GPU backends (#9931) 6734d748c8 The fuzzer used to only support our null render context. We should also be fuzzing our graphics backends though. Update the fuzzer to use TestingWindow and support real GPUs. Also add a null testing window so the fuzzer can continue using a null render context if chosen. pass unordered map by reference (#9945) c793892950 Nnnn data binding images and lists updates (#9932) 8363df8fb6 * add support for addInstanceAt in list * fix istanceAt with index overflow * fix: advanced triggers for lists * enable resetting embedded images by passing null * fix: correctly delete selected data components feat(CommandQueue) Get / Set Basic Properties (#9929) 6d8f034217 * Added initial property set / get for view models * added nested view models set fix: crash with active title (#9928) 5a1a0b5637 Fix: tess renderer & nuke old viewer (#9927) c2ec689eb6 feat(CommandQueue)Server side Cursor Math (#9916) 8bf9682caa * added math and pointer event struct to easily translate cursor events * better comment feat(CommandQueue) View Models and View Model Instances (#9908) f4960cff48 * added viewmodels and started tests * creating and destroying viewmodels and isntances * listViewModels * view model listeners finished * added bindViewModelInstance * added more tests * addressed PR comments * updated api to not use ViewModelHandles and have a more consice api fix: static analysis fixes (#9918) c71be9b1a2 * fix: static analysis fixes * Update packages/runtime/src/file.cpp * chore: checking if glyph coverage broke test * chore: try a different fix Nnnn data bind images updates (#9911) 3aa5b93199 * add missing types to runtime * add support for setting image to null fix(webgpu): Don't allocate unnecessary textures (#9909) dde1897bb7 We were allocating textures for clip, scratch, and coverage even when PixelLocalStorageType was EXT_shader_pixel_local_storage. This was just a waste of memory since PLS keeps this data explicit tiled memory. Don't allocate these textures in EXT_shader_pixel_local_storage mode! fix: crash when text is in a solo (#9915) 747c3ea77a * using debug * fix: initialize m_text to nullptr * chore: undo previous change fix: check for empty id when exporting data binds (#9912) 7293b15461 fix: check for empty id when exporting data binds fix: check for null for m_text fix crash on unset listener change (#9907) 8edd84d2a3 fix: isTargetOpaque override (#9901) 7c8352ad63 library: allow passing view model instances of a nested library to a library artboard (#9878) 052a4984ef fixes: https://github.com/rive-app/rive/issues/9781 Imagine this situation. 1. File1 -> publishes vm1, and a artboard1 that understands vm1 2. File2 -> publishes artboard2 that has a nested artboard of artboard1 (imported from library) 3. File3 -> wants to use artboard2 (from File2), and supply it with vm1's instance. This should work, which is what this PR does. There are two main sectors of changes 1. I created a library asset manager, and uplifts all caching stuff to the 'file' level instead of on the 'libraryAsset' level. This is because ID's like libraryArtboard.viewModelId need to be able to refer to another libraryAsset. Same goes for viewModel.propertyEnum or propertyViewModel. 2. In runtime_exporter, I'm changing how we add to the fileIndexMapper for library components. Before this PR, I was doing this lazily. E.g. if a nestedArtboard refers to an artboardId that's from the library, I remap that to the actual Artboard's index at the time of write. However, this is getting a bit confusing. I thinnnnk it's safe to just map all LibraryComponents before writing anything. I also fixed path_fiddle for databinding, which is how I've been inspecting databinding in runtimes. I added a test for this. fix: Scroll index not considering gap (#9889) aca08e662c Scroll index values need to account for gap in when the convert to/from scroll offset. data bind fixes 16 ffe3a20c95 * fix image sampler missing argument * add support for comparing integers to floats in cpp feat(Command Queue): Pointer Events (#9881) ab11082212 Adds pointer events to the command queue. Also fixes an errant callback name. refactor(CommandQueue) removed erase in `processMessage` to avoid double erase (#9887) e296e14c35 removed erase in processMessage to avoid double erase fix(editor): add additional index checks for Lists (#9870) 89ffb92b57 Add additional index checks to prevent out of range errors in List access. refactor(vk): Add a vkutil::Texture2D class (#9862) 5779effa92 vkutil::Texture2D wraps a VkImage AND a VkImageView so we don't have to manage both of these objects separately when we just want a simple 2D texture. It also subsumes TextureVulkanImpl, allowing us to simplify things further and remove that class. vkutil::Texture & vkutil::TextureView are renamed to vkutil::Image & vkutil::ImageView, in order to reflect the fact that they are just very thin wrappers around VkImage & VkImageView. runtime list updates (#9855) f660dea549 * runtime list updates removed generation of reqeust ids (#9859) b8bfaaf5e7 * removed generation of reqeust ids * removed request id type added advance state machine and settle callback (#9857) 58ece530ef * added advance state machine and settle callback * better tests * address pr comments Add gate for modifying dirty layouts set (#9856) 465d37f48e Add a gate to prevent m_dirtyLayout from being modified while it's being iterated. Also adds some additional logging. fix(renderer): Gracefully handle compilation failures (#9755) c09b771645 Ensure that rendering still succeeds when compilations fail (e.g., by falling back on an uber shader or at least not crashing). Valid compilations may fail in the real world if the device is pressed for resources or in a bad state. fix(CommandQueue) (#9845) 6582d5bf02 fix command buffer example to use the correct syntax for file asset loaders feat(CommandQueue)File asset loader (#9799) 77172ea62b * added file asset loader * tests for asset loader * made asset loader rcp * addressed pr comments feat(CommandQueue) Added request Ids associated with jobs (#9796) 5aedcdc61f * added request ids that are associated with callbacks for the command queue * modified tests to check for request id feat: TextInput - refactor shapes for runtime text input (#9836) 455374455c * chore: updating runtime defs * chore: refactor TextStyle into TextStylePaint * chore: missed hpp files * chore: missed cpp files * chore: fix clone of text_style_paint * feat: more text input at runtime * chore: cleanup * chore: add typed child iterator * chore: missed files * chore: running runtime input in editor * feat: completing integration with editor * chore: missed file * chore: fix builds with text disabled * chore: use child for test * tests: adding more tests for text input * chore: missed test file * chore: more coverage for child iterator * chore: using clipping on text input * chore: test text input selected text * chore: dry up iterator Revert "bad driver detection for clip planes (#9714)" (#9775) c62bdb256e Revert "fix: Make bad driver detection more specific for clip planes (#9714)" This reverts commit 3ab91e096d9d27a5b8f4cc50737a70eef25d2558. Sadly, the mini-test could pass on Galaxy S24 SM-S921B, only to have the clip planes crash later. This should hoepfully go away with Vulkan. feat(Image sampler filters) Adds Image filter options for rendering images (#9309) 930facea3f * added filter type to draw batch * c++ implementation of ImageSamplerOptions * image sampler options now pushes correct for RiveRenderPaint * wip * OpenGL uses correct sample options * now only one filter option that accounts for mip map * d3d now uses sampler states options * better way to get the filter option * added mirror and inverse mirror options * started using helper functions for retreiving sampler optiojnhs * workaround for vulkn semaphore issue * wip * added filter type to draw batch * c++ implementation of ImageSamplerOptions * image sampler options now pushes correct for RiveRenderPaint * wip * OpenGL uses correct sample options * now only one filter option that accounts for mip map * d3d now uses sampler states options * better way to get the filter option * added mirror and inverse mirror options * started using helper functions for retreiving sampler optiojnhs * workaround for vulkn semaphore issue * wip * undo deleting empty descriptor * properly packed image options * removed uneeded checks * more unit tests * unreal image_filter_options integration, gm for image filters * properly implement new draw functions for cgrender * finish mege conflicts * merge vulkan sampler options * cherry-picked vulkan imp into branch * initial metal * clang-format * d3d12 image filter options * fixed d3d * clang-format * fixed mip filter for metal * made every filter option act as similiar as possible * addressed pr changes * fixed tests * empty commit to fix github * fix: webgl renderers * started addressing PR comments * metal change for pr * more pr stuff * final PR address * shader update per PR request * rhi updat e * added gm requested in pr * made d3d12 work with more then 2000 sampler changes per flush * pr comments chore: add data binding set of tests (#9821) 6a3aa2cbfd * add data binding set of tests library: export used artboards from library files only (#9816) 127097dac4 # Description Before this PR, we export all artboards from library files in runtime_exporter. This PR makes sure we only include what's directly or indirectly used by the host file. # Details While working on the runtime exporter, I'm realizing that we have a lot of arguments on the exportOneFile function that can be simplified, so I changed the api a little there too. I tried to separate out this in the first two commits. For DataEnums, before this PR, there are 2 sources of 'filter' on what to export. One comes from 'usage', and the other comes from `requiredDataEnums` in the mappingContext. With this PR, I'm consolidating this into just using `requiredDataEnums`, so the usage of the current file is folded into this too. For ViewModels, it's very similar. Before this PR, there's the argument `viewModels`, and the context view models coming from `requiredViewModels` in the mapping context. I've found this to be a little redundant, so I again folded the former into the latter. For Artboards, there's already `exportArtboards` in the mapping context, but this represents what's exported by each file. The nested artboards rendering logic uses this directly. We don't have a way to communicate, for every file, what's required by other files. As such, I created a `requiredArtboards` concept, that's similar to the `requiredDataEnums` and the `requiredViewModels` above. This tracks the Artboards that every library file needs to export. Fixes: https://github.com/rive-app/rive/issues/9434 feat(apple): add mac catalyst support (#9759) e6b052eed9 fix: add missing symbol property when creating view model instance (#9827) 3277968b6d fix: extend unbinding to data bind dependencies (#9817) 0e1fce36c3 Nnnn enable data bind images ff early access (#9808) f91f517f32 * data bind images fixes * enable data bind images in early access add tests (#9807) b21cda7564 feature(CommandQeue) Message Queue (#9704) 5b253d0b0b * added message queue for receiving information back from server * addressed some issues * renamed everything to listeners, manage lifetime of listeners implcictly, modified tests to match and updated example to use listeners. * updated to match naming convention we talked about * addressed PR * added delete messages for file,artboard and statemachine * fix dumb dumb * Update packages/runtime/include/rive/command_queue.hpp * more pr changes * nested listener classes * addressed pr requests fix: cpp modulo to match dart (#9757) 6c03dca01d * fix cpp modulo to match dart fix: skia loses the fill type after a rewind (#9741) 8f5a30ac7c fix: Make bad driver detection more specific for clip planes (#9714) 3ab91e096d Some ANGLE drivers don't support clip planes correctly. But ather than making a blanket ban on ANGLE clip planes, compile a mini-test and see if the failure repros before banning the extension. fix(gl): Fix a memory leak in TextureGLImpl (#9663) 9e3db1f98f It appears that we were never deleting the underlying GL texture for image textures (×_×) fix: Memory issues in TrivialObjectStream (#9731) 5661461ca8 The idea of addressing full objects inside a deque of bytes is fundamentally broken, because std::deque does not have contiguous storage. To fix this, use std::copy et. al. to move the bytes in and out of the deque, instead of trying to dereference them. Change our requirements to POD and rename it PODStream. fix: Find a workaround to compiler bug on Pixel 3 (#9729) 5ed9258760 Pixel 3's GLSL compiler didn't like a recent change we made. Find a workaround. fix: ensure data bind refs and unrefs its source when binding and unb… (#9738) 0d0f9cd7d9 fix: ensure data bind refs and unrefs its source when binding and unbinding fix: scrollIndex on Lists (#9732) d46676d8d1 Setting/getting scrollIndex on a ScrollConstraint that contained an Artboard List was not updating the scroll offset properly. We add a layoutBoundsForNode(index) to allow accessing proper layout bounds for every layout in a LayoutNodeProvider. feat: List Artboard Reuse (#9691) 74188ce8cc Modifies the List DataBinding classes to cache ViewModelInstanceListItems rather than doing a full replacement, which makes it easier to reuse Artboards that have already been mapped to a ViewModelInstanceListItem. This PR also clears the List when the state machine is paused (when DataBinding in design mode is turned off) refactor(CommandQueue) moved drawloop to be driven from commandQueue rather than from the server (#9692) 203b35111d * moved drawloop to be driven from commandQue rather then from the server * made pollMessages and waitMessages return !M_disconnect * removed drawloop added drawkey added stopmessage * addressed PR comments fix(unreal):missing decoders (#9637) b46446c172 * Update premake to include decoders for Unreal builds. fix: get rid of unused build.sh (#9710) 6be784f0dc * fix: get rid of unused build.sh * fix: unit tests on msvc and linux * chore: fix again * chore: use cirrus labs for linux unit tests * fix: linux test * fix gvec polyfill * chore: fix linux * chore: linux again * fix: don’t let ratio go below 0 test: Add a threshold parameter to check_golds.sh (#9670) 4c2a6633c1 update riv to reflect the new core ids (#9711) e2e4f1e226 Nnnn data bind assets bkp 2 (#9705) e6782a6bfb data bind images library: remove references to LibraryStateMachineInput (#9701) 5f34d5e684 Note we removed creating them in ec0c2b2#diff-4ace8b8bb73f8a7f225de6e4452a88a5af27d860d807ad64c1e1b2fe40321c12 Not sure if we still wanna resolver still? I kept them in for now. We have a runtime test that's failing, that's what got me to notice that we still have inputs... https://github.com/rive-app/rive/actions/runs/15053446609/job/42313583695 SORRY!!!!!! fix: ViewModelInstanceListItem memory leak (#9699) e399210e17 Fixes a memory leak where we were double reffing core instances of ViewModelInstanceListItem. Unit tests now pass. fix unit test make (#9698) 2e0c905455 merge skipping the pending tests library: make sure host artboards always get exported first (#9686) 7c7035d035 # Description In a .riv file that doesn't import from libraries, we expect that the first Artboard is the default one. Our runtime API's expect this. E.g. riveFile->artboard(0) is used extensively. Before this PR, because we export files in a DFS fashion, artboards from the library actually gets exported first. This breaks the above assumption. # Details This PR makes sure that the assumption holds. The way I implemented this is by having files export Artboards to a different buffer, then write that buffer after the host's objects are written. Here's how I expect the objects to get written, on a file that makes use of 2 libraries. Host's Backboard Lib1's file assets Lib1's dataenums, viewmodels and their instances Lib2's file assets Lib2's dataenums, viewmodels and their instances Host's file assets Host's dataenums, viewmodels and their instances Host's Artboards, animations Lib1's Artboards, animations Lib2's Artboards, animations If Host doesn't have libraries, then it'll just be a removal of all the Lib lines, so we get, Host's Backboard Host's file assets Host's dataenums, viewmodels and their instances Host's Artboards, animations fixes: https://github.com/rive-app/rive/issues/9537 chore: fix clang-17 compiler (#9666) 8a1f3286b9 * chore: fix clang-17 compiler * chore: adding missing file * fix: rive_native builds * chore: remove no runtime linking on linux * chore: more fixes * chore: removing rive_common * chore: use build_rive.sh for ios * chore: use rive_build.sh for recorder * chore: fix fill missing version * chore: add rive_build.sh to path * chore: add rive_build.sh to pr_ios_tests.yaml * chore: add rive_build to the recorder tests * chore: drop rive_flutter tests * chore: fixing ios tests * fix misspelled * chore: cleanup * chore: use latest zlib * chore: premake5.lua redirects to premake5_v2 * fix: tvos and ios builds * fix: unreal build path for miniaudio refactor(TestHarness) Test harness stacktrace's (#9642) c0844f01b5 * added stack trace and signal handling for windows * added stack trace unwinding for mac / linux * refactored into seperate file * add file * builds for non windows * addressed some pr comments library: view model support (#9630) 16c30e956a This PR allows drag+drop a ViewModel from a library asset into a host file. I tried to keep it readable via commits. The approach is pretty similar to how DataEnums work with libraries. I've wrapped every view model property into a library version, which would also contain a componentId that contains the ID of that property in the original library file's core. I've added LibraryArtboard.viewModelId that's similar to Artboard.viewModelId. This is inferred from interalCore when the library file loads (in LibraryAsset.decode, `_updateVms`). The runtime exporter's context needs to keep track of the instances we want to export from the host file. This is b/c view model instances have to be exported with view models, so the host's instances need to be passed back to the library file and exported with its view models. (mapping_context, `requiredVmInstances`). Because runtime is extremely order sensitive, I've also added support for DataEnumValue.order and ViewModelProperty.propertyIndex in this PR. QoL improvements: I refactored the caching logic to account for Library components that are removed, and it's now more generalized (this is tested). Testing: I also added to the import export test in the editor and C++ Demo: https://2dimensions.slack.com/archives/C07M7DQL4F2/p1746745186933889 Fixes: https://github.com/rive-app/rive/issues/9461 Fixes: https://github.com/rive-app/rive/issues/9345 Fixes: https://github.com/rive-app/rive/issues/9570 Fixes: https://github.com/rive-app/rive/issues/9588 add support for symbol index for formula and operation converters (#9655) fbbd128426 feat: Editor text input (#9644) 4aefd8c646 * feat: working on text input in the editor * feat: adding raw_text_input to input * feature: text input starting to work in the editor * feat: text input * feat: text input sizing rules * fix: handle empty lines * chore: fixing dupe core ids * chore: removing old menu system * chore: working on crash * feat: generate text input artboard * fix: setting source artboard hug correctly * fix: failing test * chore: missed popup button file * chore: fix tests * chore: remove no longer valid test * chore: fix more tests * chore: fix more tests * chore: cleanup * chore: fix clashing ids feat: Support js arch in build_rive.sh (#9617) 9763df3872 refactor(webgpu): Delete write_texture and write_buffer helpers (#9640) 527fb53e7f Number to List Converter (#9622) 3a43815502 Adds a data converter to convert a number to a set of List items. This converter is a quick way to generate list items. It can be assigned a ViewModel, and the converter will generate ViewModelInstanceListItems using the ViewModel's default instance. The ArtboardComponentList inspector now displays ViewModelPropertyLists and ViewModelPropertyNumbers in the combobox which can be selected or pickwhipped. refactor(tvos): fallback to libwebp if cg fails (#9534) d3b61cf628 chore: wrap layout nodes for editor (#9641) 6af68fed8b feature: add list index symbol for view model lists (#9643) 2b1a85fa6f * add list index symbol for view model lists fix(gl): Fix uninitialized pixel local storage (#9638) fac712cc41 The GL_EXT_shader_pixel_local_storage extension makes a vague hint in Issue #4 that one could clear PLS to 0 by issuing a glClear with a zero clear value: "This makes the value effectively undefined unless the framebuffer has been cleared to zero." However, Issue #5 may go back on the suggestion from #4 and require applications to always initialize PLS with a fullscreen draw. https://registry.khronos.org/OpenGL/extensions/EXT/EXT_shader_pixel_local_storage.txt Either way, we are observing on some older ARM Mali devices that the glClear approach does not always initialize PLS, resulting in a rainbow-colored QR-code-like pattern of uninitialized tile memory. Always initializing PLS with a draw instead of glClear fixes the issue. Fixes https://github.com/rive-app/rive-react-native/issues/279 Fix Artboard List crash when layout siblings come before it (#9633) 18c9402bc3 A crash was reported with Artboard Lists which occurred when Artboard List had any sibling layouts and starting and stopping the state machine a number of times. Additionally it only occurred if the Artboard List wasn't the first layout child. feat: First draft of a CommandQueue (#9620) 18dc7c390b * feat: First draft of a RiveCommandBuffer RiveCommandBuffer hopes to eventually become the basic high-level Rive API. It's an asynchronous command queue that hides the data behind handles and executes on a separate thread. This initial example is just something to get started. We will evolve the API as we feel out what is needed in the various backends. * More testing * AutoLockAndNotify * CommandQueue * Fix linux build fix(webgl): Work around a crash on Chrome 136 (#9623) 82c66ee251 Chrome 136 crashes when trying to run Rive because it attempts to enable blending on the tessellation texture, which is invalid for an integer render target. The workaround is to use a floating-point tessellation texture. https://issues.chromium.org/issues/416294709 Remove artboardId & useLinkedArtboard props from List Items (#9605) 99534c2749 In order to make ViewModelInstanceListItems more generic in preparation for supporting other types of "Lists" in the future, we are removing Artboard specific properties from this core object. Instead, we infer the Artboard based on the ViewModel applied to the List Item (we use the first Artboard we find that has a ViewModel bound to it that matches the List Item's ViewModel) fix: do not clone converters at resolve time (#9616) ade06e3c79 fix: do not clone converters on import fix(renderer): Gracefully handle null image textures (#9600) 7dd9f91b4a Core problem: The android runtime updates out-of-band assets on the main thread, while rendering and texture updates happen on the worker thread. This led to a race condition where the RenderImage could still have a pending texture update while drawing a frame, meaning its current texture was null. Short term fix: Just don't draw RiveRenderImages if their texture is null. NOTE: This doesn't fix the general race condition where data is simultaneously being read and written by different threads, but as long as we cross our fingers and hope that pointer writes are atomic (an assumption that must also be true for other types of OOB assets being written), the null check will help us limp by until we rearchitect the threading model, which is now a very high priority item. editor: DataEnum in library (#9603) 3df92e66a4 Please review commit-by-commit :) This PR adds DataEnum as a publishable component. Then in the host file, you can drag the DataEnum into the stage. This DataEnum will appear in the Data sidebar, but will be read-only (no re-ordering or adding new values) ![image](https://github.com/user-attachments/assets/09007ca1-0ed4-46de-a87f-88010b0895bc) ![image](https://github.com/user-attachments/assets/2eda4c1e-8e41-46d1-9ddb-c01562bcc1bc) Then, in a view model in the host, you can use this DataEnum as if it's defined locally. Some notes 1. A LibraryDataEnum extends DataEnum. The only difference is that it has an asset ID and a component ID. I think this approach makes it such that existing UI's will just work. 2. The runtime exporter now has a concept of what DataEnums are required from each file. This makes sure we always include the DataEnum's needed by the host file. 3. I changed the ID resolving logic into the runtime exporter's bindable hooks. Going forward, this is a unified place to remap ID's. Tests: 1. I added some tests, and also manually verified that transitions understands library data enums. Here's a video: https://2dimensions.slack.com/archives/C07M7DQL4F2/p1746486246058399 Component list refactor pt1 (#9595) 126c53a0f5 Some reworking of ArtboardComponentList and related vm/db classes: - Refactors ArtboardComponentList to accept ViewModelInstanceListItems rather than ContextValueListItem - Adds DataValueList. - Consolidates update and apply functions into a single ContextValue.apply - Fixes a couple of crashes fix(scripts)Fixes down stream dirs (#9601) 343f00ae33 now works with downstream dirs feature: support bindable position units (#9598) 0cadb00a87 support bindable position units test(unreal) added tests and build scripts for unreal static build anylysis (#9553) 7a9da23d19 * added tests and build scripts for unreal static build anylysis * added helpers scripts for building the plugin and platform binaries * now build plugin as well as static analyze it * now builds gm/golden app in CI * build fix for unreal * wip * script fixes Fix clamped scroll drag accumulation (#9596) a596ba0966 When using the clamped scroll constraint in the runtimes it was noticed that when dragging, the scroll offset would continue to increase when you scroll beyond the start or end. Visually the scroll was constrained properly, however, this resulted in having to drag in the opposite direction by the amount that was "overdragged" before it would start moving again in that direction. This behavior was not seen in Dart (nor with the elastic scroll) fix(rive-runtime)moved scripts to be in downstream (#9593) e9fce7bba1 moved scripts to be in downstream Component list js runtime ca744236fb Component list js runtime feat: Move the alpha portion of MSAA blend modes to the blend unit (#9576) 4f9625183f Move the alpha portion of MSAA blend modes to the blend unit The advanced blend modes can be split algebraically into two distinct operations: color and alpha. The color portion has all the custom logic that needs to run in the shader. The alpha portion is run-of-the-mill source-over blending. For the MSAA backend, move the alpha portion of the operation into the hardware blend coefficients instead of doing it in the shader. This gives smoother antialiasing because the blend unit does the blend at each sample separately, whereas the shader runs once per fragment against a single (resolved) destination color. refactor(build scripts) updated setup_windows_dev.bat to act like the ps1 variant (#9577) 7051d2685f updated setup_windows_dev.bat to act like the ps1 variant fix: downstream rive-cpp tests (#9575) 32041efdc7 * fix: downstream cpp * chore: skip input tests when there’s no rive text fix: do not draw fully transparent shape paints (#9573) 6082e56f65 feat: RawTextInput in rive_native (#9564) 5adbd3311d * fix: wrong return type * adding make raw text input * feat: adding some rawtextinput bindings * feat: more raw text input apis * finish bindings * chore: cleanup * feat: expose cursor visual position * chore: allow drag passed bottom * chore: add comments * chore: fixing cast * fix: wrong return types in rive_binding * chore: missed tests checkin Expose Transforms for DataBinding (#9538) cc09ee1983 Exposing transform values of Rive objects to databinding has been highly requested. This exposes values such as x, y, width, height as read only bindable fields. Add Layout scale type to System Enums (#9560) 4ba64bae05 This PR adds the Layout scale type options (Fixed, Fill, Hug) as system enums for data binding. The scale type options enums are necessary for enabling ViewModels to bind to the scale type options. This is particularly important when it comes to Component Lists where Artboards are instantiated dynamically so scale type can't be set at edit time. feature(Dx12 backend) (#9520) b4a317b254 * path_fiddle d3d12 and start of d3d12 imple * converted to precompiled hlsl for tess, grad and atlas. Fixed sampler issue in d3d11 * started implementing resource managment * working state with grad,tess and atlas draws coded. GPUResource mangement also in * draws in with another set of validation fixes * atomic mode working * textures now upload correctly, atomics now have barriers and index/vertex buffers are properly bound * typo fix * made work with gms, uniforms updated correctly now, coelesed and resolve now works * passing golds? * proper que dependencies * added some comments around passing command lists for d3d12, if no copy is given, use direct for both * rename * added golden pr * refactor pulling out all shader compiling to a shared D3DPipelineManager class * pre comments * fixed workflow syntax error fix: pass correct data context to state machine (#9545) 68262f2f3f * fix: pass correct data context to state machine * remove unused var RawTextInput (#9540) 85e8a5681f * starting to add cursor tests * working on cursor positions * two ways to compute location the cursor * working on adding a fully_shaped_text abstraction * improving cursor movement with bidi * adding selection * use rectangles to contour * cursor movement and tests * adding selection caching * adding getting/setting text * test for setting text * adding home/end * feature: word + subword movement and tests * Adding word selection * feat: undo/redo for text input * removing time from text input * separate selection text * chore: remove print statement * chore: clean up * chore: remove printf * chore: do not compile cursor when rive text is disabled * chore: do not use fully shaped text when not compiling in text * chore: strip text selection path when not using rive text * chore: remove unused variables * chore: add changed goldens due to different transform method * chore: rebaseline iphone se * chore: remove unused vars * chore: more unused variables removed feat(vulkan_unity): adding vulkan support to unity (#9544) 38d5ae8571 * starting to add vulkan support * Vulkan works! * use build_rive.sh * fix premake and remove unused var * get lunar sdk * install glslang * all components * Use new sync method for vulkan! * getting vulkan rendering working when color buffer pointer is 0 * frame delay coroutine * fix: crash swapping native texture pointer * feat: linux unity support * chore: adding missed meta file. * chore: adding build downstream for linux unity * install glslang * chore: remove unused code * chore: addressing PR feedback! * chore: add SPIR-V tools back feat(vulkan): Support all render target formats (#9527) 1014fd7fa4 Refactor the Vulkan backend to support render passes of any format, rather than hard-coding RGBA8 or BGRA8. To test this, add a "vksrgb" config just for fun. Shaders aren't generating linear color (yet), but the SRGB attachment works. Fix layout alignment space between (#9526) 59b55d281f When moving between row & column, if alignment was set to Expanded (start, center or end), it would not render at the correct position. This was masked at edit time because when you set the alignment using the grid UX, it switches to an non-Expanded alignment (left/center/right and top/middle/bottom), which causes the alignment to fix itself before clicking again to set it to Expanded. fix(vulkan): Fix input attachmens on AMD (#9513) e5dc0b989c Feedback loops are valid in Vulkan as long as you don't issue overlapping geometry, but we were issuing overlaps and using atomics to disdcard all but one. This seemed valid, but didn't work on AMD. However, if we emit color values of "0" and instead rely on blending to make sure the color buffer doesn't change, it works on AMD ¯\_(ツ)_/¯. refactor(vulkan): Move shaders to a different cpp file (#9504) 598ad6c62e RenderContextVulkanImpl is getting so big that it's hard to navigate and my editor is starting to get bogged down. Move the SPIRV array definitions and shader-building logic to its own cpp file. feat(vulkan): Implement coalesced resolve (#9497) ea1b51f970 Not all swapchains can be bound as input attachments, and Unity doesn't appear to have a way to request VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT for its textures either. Adding the target texture to the render pass and doing a coalesced resolve should be almost as fast as if the color attachment had VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT to begin with. fix: update data binds when events from children are notified (#9499) a21d95735d # Description when a nested artboard notifies events, we need to update data bound objects because those events might trigger changes on values that need to be synced Component List in CPP (#9408) db11b46e96 # Description This PR implements Component Lists in the CPP runtime. # Details Mirrors the Component List Dart functionality in C++. Allows generation of Artboard Instances at runtime through ViewModelInstanceLists. This PR does not implement virtualization. feat(vulkan): Use VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (#9495) 4ddcd7f9c2 When there is no advanced blend, we can use VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL for the color attachment instead of VK_IMAGE_LAYOUT_GENERAL, which is theoretically slightly more performant. refactor(vulkan): Make RenderTargetVulkan more generic (#9494) 21820c5a7a Rather than just setting & getting low-level information about a texture, add methods to RenderTargetVulkanImpl that explicitly access the target and offscreen textures. These methods require specific layouts and access flags, and will perform barriers if necessary. Also split out a virtual RenderTargetVulkan class that Unity can override and provide its own access mechanism for its internal VkImage objects. In addition to helping with the Unity effort, this greatly simplifies some of the barrier work going on and makes the code more robust. fix: 32-bit Vulkan builds on Android (#9491) f9adbe2746 fix: Fix release build (#9437) 459688c69c Also add two CI workflows to build release on mac & windows to make sure we don't break it again. refactor: Put blend state in PipelineState (#9482) 2d03eba653 Move more pipeline logic up to the higher level and introduce some static pipeline states for the basic draws inside flush. library: allow loading library that uses another library (#9480) bcdfcda330 This PR lazily decodes libraries referred to by other libraries. Fixes: https://github.com/rive-app/rive/issues/9457 Before this PR, a host file will only load the FileAssets referred in itself. If that FileAsset is a LibraryAsset, we don't go look for other libraries it refers. This PR changes that to lazily loading whichever LibraryAssets are needed in the export process. This is manually verified and I also wrote a test for it. refactor: Work out low level barriers at the RenderContext level (#9474) 0ebca777f4 Determine all the barriers at a higher level so that the individual backends don't have to duplicate this work. This also prepares us for another refactor that will move the blend state into PipelineState, and to start supporting "blend barriers" that we can use with non-coherent advanced blend extensions. fix: data converter range mapper argument order (#9467) e5fc8db9e0 # Description data converter range mapper in dart was using the arguments in the wrong order # Details This PR also includes an optimization to avoid a bidirectional data bind to add dirt to itself when it changes the view model value by suppressing dirt while it modifies the view model value fix: access enums data (#9460) 9a843dc27a # Description some fixes related to view models and enums # Details two main fixes: - export system enum names - make sure that viewmodels and enums can outlive the file as long as a view model instance is alive fix: stroke effects not updating with text modifiers (#9463) 2c52089bde # Description fix: stroke effects not updating with text modifiers # Details when text modifiers add paint dirt to the text, we have to invalidate stroke effects so they get redrawn refactor(renderer): pulled out decodeImage from context helper and made it platform decode (#9448) e7b0480e4e # Description made decode Image implantation in `RenderContextHelperImpl` now defined in `RenderContext` # Details We were copy pasting the code for decoding into several places. Moving it to `RenderContext` allows us to have it in one spot and just be used by default. fix: contour bugs with new RectanglesToContour (#9450) 53131428a6 # Description - I caught a bug with multiple contours due to the inclusion setter always using the first rect, so it would fail on rects that would create multiple contours. - Also fixes an issue with the unique point sorter not using the stored vectors. I messed something up when rebasing that previous pr. Adds a test for the multiple contour issue. fix crash if operation stack is 0 in a malformed formula (#9435) b4066558a1 # Description fix crash if operation stack is 0 in a malformed formula Make RectanglesToContour more memory efficient (particularly for re-runs). (#9438) 5c4e83502f # Description In the text input branch I realized I needed to re-use RectanglesToContour and that it would be called often when moving selection ranged cursors. The existing implementation closely matches our Dart one which is not very memory efficient, mostly due to it just being Dart. # Details - Try to store re-used containers on the RectanglesToContour class so allocation can happen less frequently when re-using the RectanglesToContour. - Try to avoid any forced heap allocation (although some is still bound to happen). - We had a lot of Vectors of Vectors. In almost all cases these got simplified to linear vectors or vectors of structs/classes. Because each vector does its own heap allocation, vector>> can cause a lot of memory re-alloc when adding/removing elements. - The boolean inclusion vector got converted to a bitset which is also stored on the class so it can be re-used. - Nuke Rect as we have the same functionality in AABB. - Massaged the API a bit to have names match the updated API a little more closely. I'll add more comments inline below... adds a text listener silver (#9444) 922b445f21 # Description Adds a silver for text run listeners. Creates two frames, one at the start: ![CleanShot 2025-04-14 at 10 51 41@2x](https://github.com/user-attachments/assets/8499a054-f7d0-4071-b1b1-398bfc12380a) And one when hovered over the run: ![CleanShot 2025-04-14 at 10 51 49@2x](https://github.com/user-attachments/assets/12ab939a-78d5-4680-bb21-697fd8a49e40) fix coverage reports (#9446) c07021b43b # Description Re-enables building coverage data. This got nuked when different argument handling was added to test.sh libraries: serialize library artboards as local artboards (#9419) e75974b896 Fixes https://github.com/orgs/rive-app/projects/15/views/1?pane=issue&itemId=104718681&issue=rive-app%7Crive%7C9356 Fixes https://github.com/rive-app/rive/issues/9324#issue-2966381868 ### Overview Currently we do not export LibraryArtboards to runtime, as C++ won't understand them. As such, currently, if you have ArtboardX that contains NestedArtboard_ofALibraryArtboard, a NestedArtboard that points to ArtboardX won't work. This PR makes it such that a NestedArtboard to ArtboardX would show. Moreover, its statemachine will play too. ### There are a few main changes 1. LibraryAsset: cached library artboards in LibraryAsset are referenced by ID instead of by name. This ID is the original artboard's ID in the library asset file, and is persisted in our schema as LibraryArtboard.artboardId. Same same with caching statemachines and linear animations. I've added LibraryStateMachine.animationId and LibraryLinearAnimation.animationId. 2. NestedArtboard: before this PR, there was logic that checks whether the source artboard was a LibraryArtboard or just an Artboard. Now, it's just Artboard, because the runtime exporter only exports Artboards. 3. Runtime exporter: I've created the idea of MappedContext, which maps a library identifier to its various remaps, like globalIndexMapper, nestedIds, eventIds, etc. ### The mapping NestedArtboard.artboardId -> LibraryArtboard.id LibraryArtboard.artboardId -> LibraryAsset's rev file's Artboard.id NestedStateMachine.animationId -> LibraryStateMachine.id LibraryStateMachine.animationId -> LibraryAsset's rev file's State Machine.id ### Order of export Currently, when we export we only go over the host file, and the order looks like Backboard_ofHost FileAssets_ofHost DataModels_ofHost Artboard1_ofHost Artboard1_components_ofHost (e.g. paints, nested artboards, state machines, etc.) Now, I'm recursively also exporting the library files. So the order looks like Backboard_ofHost [XXX] **--FileAssets_ofLibrary --DataModels_ofLibrary --Artboard1_ofLibrary --Artboard1_components_ofLibrary** FileAssets_ofHost DataModels_ofHost Artboard1_ofHost Artboard1_components_ofHost Basically, we insert the indented section, which represents the library file. And if Library uses other library assets, it should go into the [XXX] section. Tho we currently don't support this, as we don't decode library assets used from a library asset. If we aggregate all the artboards, [0, total count) is the range of valid artboard indices in C++. ### Tests I'll fix the TODO's in the tests refactor(renderer): Consolidate MSAA depth/stencil settings (#9436) 689a455e67 log error with missing components (#9431) 099d761edd # Description print errors at the cpp level so they are surfaced on our higher level runtimes # Details In order to provide users with more information about errors, we're relying on the fprintf method from cpp. This is a temporary solution until we build a more robust error message model. chore: flush rive runtime change (#9428) 59d5d4d658 Add silvers without lfs (#9425) f2968887ec # Description re-add silvers, no lfs to keep ios/spm happy chore: temporarily remove silvers (#9424) eabc82a4c2 # Description get rid of silvers for now, to be added back in outside of lfs refactor(vulkan): Lift lifecycle management (#9410) 6cce6709cb Refactor Vulkan lifecycle management into more organized, non-templated classes. Lift them to the renderer level, where D3D12 and Metal can also start taking advantage of the 'safeFrameNumber' paradigm. refactor(renderer): Send map sizes to unmap functions as well (#9407) 7f5e51f4b4 Vulkan was having to track the mapping size from the map() function in order to know how much to flush in the unmap() function. Update the higher level code to just pass the map size to unmap() as well. This also found a bug where we were mapping the entire size of the buffer, rather than just the amount we were going to write. This will most likely make no difference on most platforms, where this is all coherent anyway, but it's good to fix. # Description # Details Metal fiddle context assert fix (#9393) 43d6ac25e6 # Description Fixed Fiddle context drawableSize # Details Now properly set the correct `drawableSize` so that `CAMetalLayer` gives us the correct size Fix GL buffer race condition (#9387) 93d4fda5a2 Fix rendering corruption from nested clipIDs (#9383) 373238831d add support for joystick time based dependents (#9272) 038bd34aee # Description fix for joystick controlled timelines not updating the time # Details If a state machine has a timeline controlling a nested remapped animation through keyframes, and that timeline is itself controlled by a joystick our update cycle would not apply the time updated by the joystick because the advance cycle has passed. This PR looks for joystick controlled animations, and stores which objects are nested remapped animations to advance them while they are being applied. Switch image textures to premultiplied alpha (#9377) a70f0f84dd The renderer intentionally chose unmultiplied alpha for gradients, in order to not lose color information with transparent stops. But for this very same reason, we need *premultiplied* alpha for image textures. Otherwise, the (transparent) background color can bleed into edges. Switch image textures to premultiplied, while keeping gradients unmultiplied. rive-runtime pull silver rivs (#9384) 9d516a9ece # Description rive-runtime is building, but now its failing on the silvers. I **think** it could be because we need to git pull lfs the srivs so trying that. Fix glfw working path (#9382) bd512ec1d9 # Description Previous PR to fix rive-runtime test had the path relative to mono, not relative to rive-runtime. Fix Rive-runtime tests (#9381) 92a4d0a287 # Description Mac unit tests for the downstream rive-runtime have been failing for some time. Looks like glfw wasn't being built in the downstream workflow. # Details This PR adds the Build glfw step that we do in our mono repo into the rive-runtime test workflow. Ran it locally, was able to repro the test error and this fixes the issue locally. ``` ../../../../renderer/path_fiddle/fiddle_context_gl.cpp:23:10: fatal error: 'GLFW/glfw3.h' file not found hb-ot-map.cc #include "GLFW/glfw3.h" ^~~~~~~~~~~~~~ ``` Nnnn conditionnally export images and artboards (#9376) c4dcac3232 # Description add support for three features: - set images as guide layers - select which additional artboards are exported with the riv file - select which additional images are exported with the riv file Component Lists (Dart) (#9278) 55918df404 # Description This is a first pass at the Dart implementation of Component Lists (dynamically generated lists). In this iteration, the Component List items can be built up using ViewModel list items together with Artboards. # Details ArtboardComponentList is a new type of Drawable that builds up and renders MountedArtboards in a similar way to how NestedArtboards work. To use it with DataBinding, perform the following steps: 1. Create a ViewModel to contain your list 2. Create another ViewModel representing your List item. You can also add properties to this viewmodel that are bound to properties in an artboard to be used as a list item. 3. In the ViewModel created in step 1, add a List property from the popout 4. Select the List property and in the inspector, add List items. These items should be tied to instances of the ViewModel created in step 2 and the Artboard to be used as your list items. 5. Bind the ViewModel from step 1 to the Artboard where you are adding the Component List (ie Main Artboard) 6. On the main artboard, select either the Artboard itself or create a layout and select the layout. In the inspector, click **Add Artboard List**. The Component List will be added as a child of the selected Artboard/Layout. 7. Select the Component List, then bind the ViewModel's list property to the Source field (either via pickwhip or right click) 8. Play the state machine Notes: - (UPDATE: workarounds have been removed and it now works with design mode DB)There are a couple of workarounds to get this to work because the ViewModels don't get "applied" until the State machine starts playback (this will change soon with Design time DataBinding). Those are pointed out in the comments. - (UPDATE: crash has been resolved)There is also a temp workaround for a crash I was seeing. Need to investigate further. - Editor UX still needs work - CPP implementation to follow in a seperate PR check for msbuild so we know if we need to load the vs environment (#9374) 762485768a # Description Fixes build_rive.ps1 so that it no longer eventually breaks PATH # Details added a check that only loads the VS environment when `msbuild` is not found Update ANGLE_shader_pixel_local_storage usage (#9367) 85cdb31022 Update our bindings, definitions, and usage to reflect the latest updates to the extension. Notably, we can now compile programs while PLS is active, so no need for the duplicated logic inside and outside of PLS being active. Libraries (#9255) 9d8a7e81fa feature: core definitions for libraries feature: basic editor ui for libraries feature: basic library backend api integration feat: return string reference from vm instance runtime name (#9366) f359c918e0 Changed `ViewModelInstanceRuntime::name()` to return a const reference instead of a string copy, making Unity marshalling a bit easier. Listener Silver and How to make a Silver (#9321) 8bdedb6b19 # Description Small example tutorial for how to make a silver, also adds a silver in the process. # Details Details/tutorial here: https://www.notion.so/rive-app/Make-a-new-Silver-1c95da0b06d9808e9fbbe6bdf6219df4?pvs=4 Revisit numeric stability for colordodge and colorburn (#9313) 1e42beac24 A previously-solved issue had crept back in, where unmultiplying "color == alpha" did not yield precisely 1.0. Fix the issue (again) and set up full blown unit tests for the glsl code to ensure this doesn't regress again. Nnnn viewmodel runtime updates (#9300) 5dba17ac5d # Description - add support for binding an artboard through a state machine - implements callbacks per view model instance instead of using the root instance - fixes some memory issues - adds a first set of tests Nnnn data bind fixes 9 (#9314) 8bb6aa6311 # Description Four small fixes: - reset playbackValues when syncing view models - rename Boolean Negate to Boolean Toggle - pad hex values in to string converter - expose js viewModelCount getter Silvers (#9281) b329a96f26 # Description This adds the ability to serialize draw commands to .sriv file via a SerializingFactory which can be used by the unit tests in place of the NoOpFactory. # Details You can use the SerializingFactory to initialize your .riv and annotate the serialization with things like frame size and new frame/frame begin. This makes it possible to drop the generated .sriv into the Flutter viewer which will perform the serialized rendering commands to show exactly what the runtime is doing, high level rendering-wise. It can also diff two .sriv files if they are dropped in one drag/drop op. When adding new "Silver" tests make sure to rebaseline the silvers by doing: ``` cd rive/packages/runtime/tests/unit_tests ./test.sh rebaseline ``` You can now modify the runtime and re-run the tests to make sure the silvers still match: ``` ./test.sh ``` The important function to call at the end of your test is ::matches on the SerializingFactory. This will either save or check for equality of the existing silver. ``` TEST_CASE("juice silver", "[file]") { SerializingFactory silver; // .. actually use the factory CHECK(silver.matches("juice")); } ``` Remove a spurious print from WebGPU mipmap generation (#9306) f346d7b933 Make elastic scroll properties bindable (#9304) 1673c55a6c # Description Making elastic physics properties Friction, Speed Multiplier and Elastic factor bindable. # Details Also added a few unit tests for ScrollConstraint. Will add more. More WebGPU fixups (#9187) ea9f89e682 Use an empty bind group instead of a null bind group when an index is unused. Make the base instance uniform more flexible. Nnnn data bind mode design (#9279) 305920643b # Description Adds support for data binding in design mode. Implement mipmaps in WebGPU (#9302) de583e7000 Mipmaps had not been implemented yet because WebGPU doesn't provide an easy mechanism to generate them. Generate mipmaps by literally rendering higher levels into lower levels. Fix for layoutstyle dirt continually being added in nested artboards (#9298) 05d87692bb # Description Noticed when using scrollbar constraints in a nested artboard that LayoutStyle can continue to be dirtied. # Details Continual LayoutStyle dirt was the result of a recent change related to Layout Direction. With layout direction, we needed the cascade of direction information to result in calculateLayout and updateLayoutBounds, so we forced that to happen in nested artboards. However, this caused a side effect with continual dirt. The fix now checks to see if the cascade resulted in any changes, in which case we call calculateLayout and updateLayoutBounds. Improve numeric stability of blend modes (#9290) 2ed28d20e6 Turns out it was possible for src and dst to fall outside the range 0..1. The blend math relies strictly on these values both being within said range, so clamp them. Rearrange the COLOR_DODGE and COLOR_BURN formulae to no longer rely on receiving appropriately signed IEEE Inf values from dividing by zero. The spec mandates this behavior, but it's too dangerous to rely on it. Fix Layout issue with image when N-slice applied (#9283) c118df3ccb # Description Images were not respecting their parent layout's size when an N-slice was was applied as a mesh (runtime only). # Details This bug was introduced as part of another fix (https://github.com/rive-app/rive/pull/8840) where the correct value of type was not being applied for n-slice meshes. Accept a raw VkImageView in the Vulkan renderTarget (#9286) f103ee589e Now that the client is fully in charge of synchronization, we don't need to bridge awkwardly between the client's data and Rive's internal resource management (i.e., VulkanContext::makeExternalTextureView()). The client can just give us a VkImageView and make sure they don't delete it until they've waited for that same frame's fence. Only call gms_build_registry() once (#9289) 0122594822 Looks like these were accidentally being run twice each. We only need one run. Overhaul Vulkan synchronization (#9280) 335ed61d42 The Vulkan backend has been requiring the client to pass fences along from queue submissions, and then it waits on these fences on its own timeline. This is hard to work with, bug prone, not optimal for performance, and just isn't very Vulkany. This change removes all CPU-GPU synchronization from Rive's backend. Instead, the client is responsible for waiting on its own fences (which, realistically, it was already doing anyway). Instead of passing in fences, it just passes in two lifecycle counters currentFrameNumber and safeFrameNumber. Resources used during the flush belong to 'currentFrameNumber'. Resources last used on or before 'safeFrameNumber' are safe for Rive to be release or recycle. Begin rework of Vulkan synchronization (#9275) 051f5a7411 Final vision: Client takes full responsibility for their app's Vulkan synchronization; Rive never touches a fence or semaphore. In this PR: Update just the testing backends to synchronize on their own fences instead of passing them along to Rive. Factor out a rive_vkb::Swapchain class that encapsulates the common functionality from all the Vulkan testing backends. This update alone fixes the Vulkan crashes we were seeing on Android, so also turn Vulkan CI testing back on! ...And also fix some bugs to get us running on ARM GPUs. More cleanups for Vulkan bootstrapping (#9270) 0d2bfd8f72 * Pass around fewer pointers to vkGetDeviceProcAddr. * Use more modern Vulkan instance versions in non-vkcore configs. Reduce the # of arguments required for Vulkan context creation (#9265) d1602f07cd Don't ask for things we can query ourselves. Make it easier on the client calling us. Supporting binding of Layout enums (#9247) f5975ce890 # Description Adds support for Layout enums as system enums to allow DataBinding. # Details Adds binding support for the following Layout enums: - Flex Direction - Wrap - Direction (LTR/RTL) - Alignment - Show/hide - Absolute/relative Also updates some of the core widgets to display the DB border more consistently. This includes ComboBox, MultiToggle and custom alignment widget. editor: fix using feather with opacity in a text modifier (#9233) ae422c57fb When using a text modifier with opacity settings, we go through a different route for rendering. In the render function for the shape paint, we apply an override render paint to it that copies over the color of the shape's original render paint, but with opacity overrides (this is the `applyTo` call). We currently do not apply the original render paint's feather attributes. This PR does that. Some details: 1. Previously, linear gradients didn't account for the text modifier's opacity overrides. This PR accounts for it. 2. Inner feathers depend on a text style's _renderPath for its bounds calculations, so we need to make sure this is updated even if it's not used for rendering as-is. 3. I added a golden test before in editor+nested artboard ![image](https://github.com/user-attachments/assets/f6a681e4-f900-4280-b22a-7e245de6ce40) after: ![image](https://github.com/user-attachments/assets/18b91586-cdef-492f-978c-670a8226fc1e) Nnnn data bind fixes 8 (#9239) 8d15312404 # Description change default view model color to 0xFF000000 use checkbox for view model booleans during playback More Build Options (#9240) ff4d47326e # Description Added Build and Platform Options define rive::math::pi to be the same as m_pi (#9241) a201088666 # Description make `rive::math::pi` the same number as `M_PI` so that `M_PI` is no longer needed. fix lists and viewmodel instances (#9236) 0bd3aad9ec # Description fix view model instances destroyed fix view model instances not being reused # Details When lists were created, we were wrapping them unnecessarily in an rcp which would cause the instance to be destroyed when it went out of scope. This PR also fixes a scenario where, if the original view model instance tree had multiple branches pointing to the same view model instance, the copy would create new copies for each branch instead of reusing the same cloned one. Nnnn data bind tests (#9180) c8441a6f67 first batch of data bind tests it covers converterts, binding properties and state machine conditions also fix some deletion of instances surfaced by tests add support for replacing view model instances and improve memory man… (#9206) 70bb6bd0f7 add support for replacing view model instances and improve memory management # Description Adds support for replacing view model instances in a view model instance sub tree # Details We have heard requests to replace or reuse view model instances across multiple files. This PR addresses both cases by exposing an appropriate API and handles memory as needed. fix: include artboard data bindings when cloning an artboard instance (#9215) 1833d63ebb # Description data bindings targeting artboard properties were not being cloned when generating an artboard instance # Details since artboards are cloned separately, cloning their data bindings was missing Fix layout isDisplayHidden check in CPP (#9223) cf1026cb7f # Description A file containing 50 levels of nested layouts would hang when opening. # Details There was a recursion bug discovered in the CPP LayoutComponent causing the freeze. The fix was tested with layouts 100 levels deep on the main artboard and nested artboards and performed without any problems. Added a couple of additional optimizations after chatting with @bodymovin. Renderer - move draw limit check to run before draw resource allocation occurs (#9200) e97d77938d Renderer - There is an issue where resource allocation for draws (which currently refers to only coverage buffer and feather atlas allocations) from within allocateResourcesAndSubpasses() can succeed, but be followed by a failed check for hitting an internal draw limit. This causes the draw that was attempted to be submitted/pushed to reattempt to push a second time, and then make a second allocation. This PR rearranges the limit check and splits out the subpass determination to avoid this issue, although the code is still fragile as-is. Vulkan - Atlas texture barrier fix (#9212) 48b57c6062 Renderer, Vulkan backend bug fix: The barrier that occurs after the atlas texture render pass was incorrectly performing the barrier on the tessellation vertex texture. This barrier could cause corrupted data in the tess texture. make slicer width and height bindable (#9209) d48e9c8513 # Description add two missing bindable properties # Details allow width and height of n-slicer to be bindable n-slicing: update path when removing n-slicing (#9211) cecd189934 The Path needs to recompute its render path to update the positions of its vertices on the screen. When an NSlicedNode is becoming irrelevant to a Path, e.g. when we ungroup it, or when we drag a shape out of the hierarchy, Path needs to update. However, currently it doesn't because update() happens after a core component's onRemoved. This means, deformer from the Path's perspective will be null. This PR tells Path to update whenever Dirt.nslicer is propagated, regardless of whether it's currently under the effect of one. But it will only recalculate path on worldTransform dirt if a deformer is valid. I verified that when we ungroup or drag a shape out of a NSlicedNode, the most updated path is shown. Layout Direction Left/Right Logical Properties (#9202) 6cd55f8411 # Description Adds support for treating left/right based layout property values as logical values, similar to how HTML start/end logical properties work. These include: - Left/right Padding - Left/right Margin - Absolute left/right Position - Left/right Corner Radius # Details The initial commit to support Layout direction only included relative layout child position (and text), but it was pointed out that it would be useful to also support the above property values. Adding support for these by default, but they can also be overridden for any particular layout if desired by setting its own Direction to either LTR or RTL since we support direction as a cascading layout style. We also updated the Direction combobox so that it always appears on a layout flex inspector regardless of whether it has layout children or not, since it may contain a text child which can also have its direction set using this property. Golden test included. clear bindable property when used (#9198) e3cd39b754 # Description fix: If a bindable property is used in multiple places it causes invalid states and can lead to a crash # Details a bindable property has a single owner responsible of its lifecycle, so we need to clear its value once it's used runtime golden: add support for databinding (#9188) c21188ef26 This PR adds support for databinding in the runtime golden test framework (not the flutter one). I also added a test: image I also added support for the skia viewer app and path fiddle, and verified that the .riv file added in this PR renders well in both those places. fix warnings reported by a client (#9192) 66b36fc42e Reported here: https://2dimensions.slack.com/archives/C08BQSENP08/p1741376439219539 Definitely seems like this is undefined behavior: https://en.cppreference.com/w/cpp/string/basic_string/basic_string Fix bit rotting in WebGPU (#9183) 3eae4e45b0 Update Dawn integration and peg the build script at a specific commit. Implement feathering. Fix image textures. editor+runtime: text follow path orient, strength, and trim path props (#9177) 7fe2e81969 These properties take inspiration from Rive's other features. E.g. the creative time are used to manipulating the start+end+offset in trim path, and the follow path constraint has strength and orient. For trim path, I'm noticing that the stroke always wraps. However, I thought it'd be kinda cool to intentionally not wrap if the range is <100% on a closed path. Then you can get a cool kinda effect with tangents (e.g. the penultimate row on the golden test below). This is the new UI (in a popout): ![image](https://github.com/user-attachments/assets/952e0bc0-8c0e-47b0-8f6a-03ba67eb6349) I added a golden test that looks like this: image Co-authored-by: Gordon Co-authored-by: hernan --- .rive_head | 2 +- CHANGELOG.md | 40 +- README.md | 104 +- analysis_options.yaml | 119 +- example/assets/button.riv | Bin 0 -> 806209 bytes example/assets/databinding_images.riv | Bin 0 -> 11227 bytes .../assets/electrified_button_nested_text.riv | Bin 0 -> 16804 bytes example/assets/fonts/JetBrains Mono.ttf | Bin 0 -> 187208 bytes example/assets/images/databound_image_1.jpg | Bin 0 -> 13243 bytes example/assets/images/databound_image_2.jpg | Bin 0 -> 15205 bytes example/assets/layout_test.riv | Bin 0 -> 809041 bytes .../{rating_animation.riv => rating.riv} | Bin example/assets/rewards.riv | Bin 0 -> 216579 bytes example/lib/artboard_nested_inputs.dart | 96 - example/lib/basic_text.dart | 22 - example/lib/carousel.dart | 99 - example/lib/custom_asset_loading.dart | 208 - example/lib/custom_controller.dart | 46 - example/lib/event_open_url_button.dart | 70 - example/lib/event_star_rating.dart | 75 - example/lib/example_state_machine.dart | 79 - example/lib/examples/animation_painter.dart | 59 + example/lib/examples/databinding.dart | 105 + example/lib/examples/databinding_images.dart | 106 + example/lib/examples/events.dart | 81 + example/lib/examples/examples.dart | 17 + example/lib/examples/hit_test_behaviour.dart | 168 + example/lib/examples/inputs.dart | 93 + example/lib/examples/network_asset.dart | 41 + example/lib/examples/out_of_band_assets.dart | 232 + .../out_of_band_assets_cached.dart} | 225 +- example/lib/examples/responsive_layouts.dart | 47 + example/lib/examples/rive_audio.dart | 46 + example/lib/examples/rive_widget.dart | 56 + example/lib/examples/rive_widget_builder.dart | 59 + .../lib/examples/state_machine_painter.dart | 67 + example/lib/examples/text_runs.dart | 88 + example/lib/examples/ticker_mode.dart | 67 + example/lib/examples/time_dilation.dart | 43 + example/lib/examples/todo.dart | 12 + example/lib/liquid_download.dart | 79 - example/lib/little_machine.dart | 89 - example/lib/main.dart | 461 +- example/lib/play_one_shot_animation.dart | 52 - example/lib/play_pause_animation.dart | 54 - example/lib/rive_audio.dart | 20 - example/lib/rive_audio_out_of_band.dart | 48 - example/lib/simple_animation.dart | 22 - example/lib/simple_animation_network.dart | 23 - example/lib/simple_machine_listener.dart | 27 - example/lib/simple_state_machine.dart | 57 - example/lib/skinning_demo.dart | 105 - example/lib/state_machine_skills.dart | 83 - example/macos/Podfile.lock | 28 + .../xcshareddata/xcschemes/Runner.xcscheme | 1 + example/macos/Runner/AppDelegate.swift | 4 + .../macos/Runner/DebugProfile.entitlements | 2 + example/macos/Runner/Release.entitlements | 2 + example/pubspec.yaml | 8 +- lib/components.dart | 3 - lib/math.dart | 1 - lib/rive.dart | 74 +- lib/rive_web.dart | 16 - lib/src/animation_list.dart | 20 - lib/src/asset.dart | 75 - lib/src/asset_list.dart | 21 - lib/src/asset_loader.dart | 212 - lib/src/blend_animations.dart | 20 - lib/src/container_children.dart | 20 - .../linear_animation_controller.dart | 47 - lib/src/controllers/one_shot_controller.dart | 51 - lib/src/controllers/simple_controller.dart | 63 - .../controllers/state_machine_controller.dart | 231 - lib/src/core/core.dart | 177 - lib/src/core/field_types/core_bool_type.dart | 7 - lib/src/core/field_types/core_bytes_type.dart | 12 - .../core/field_types/core_callback_type.dart | 16 - lib/src/core/field_types/core_color_type.dart | 7 - .../core/field_types/core_double_type.dart | 7 - lib/src/core/field_types/core_field_type.dart | 7 - lib/src/core/field_types/core_int_type.dart | 7 - .../core/field_types/core_string_type.dart | 14 - lib/src/core/field_types/core_uint_type.dart | 7 - .../artboard_import_stack_object.dart | 8 - lib/src/core/importers/artboard_importer.dart | 43 - .../core/importers/backboard_importer.dart | 45 - .../core/importers/file_asset_importer.dart | 38 - .../core/importers/keyed_object_importer.dart | 14 - .../importers/keyed_property_importer.dart | 17 - .../core/importers/layer_state_importer.dart | 36 - .../importers/linear_animation_importer.dart | 13 - .../nested_state_machine_importer.dart | 21 - .../importers/state_machine_importer.dart | 13 - ...tate_machine_layer_component_importer.dart | 12 - .../state_machine_layer_importer.dart | 41 - .../state_machine_listener_importer.dart | 12 - .../importers/state_transition_importer.dart | 30 - .../viewmodel_instance_importer.dart | 12 - lib/src/data_enum_values.dart | 20 - lib/src/debug.dart | 9 - .../dynamic_library_helper_ffi.dart | 2 - .../dynamic_library_helper_stub.dart | 3 - .../dynamic_library_helper_web.dart | 2 - lib/src/errors.dart | 45 + lib/src/event_list.dart | 20 - lib/src/extensions.dart | 27 - lib/src/file_loader.dart | 121 + .../animation/advanceable_state_base.dart | 49 - .../generated/animation/animation_base.dart | 45 - .../animation/animation_state_base.dart | 54 - .../generated/animation/any_state_base.dart | 18 - .../animation/blend_animation_1d_base.dart | 45 - .../animation/blend_animation_base.dart | 46 - .../blend_animation_direct_base.dart | 99 - .../animation/blend_state_1d_base.dart | 54 - .../generated/animation/blend_state_base.dart | 18 - .../animation/blend_state_direct_base.dart | 21 - .../blend_state_transition_base.dart | 52 - .../cubic_ease_interpolator_base.dart | 18 - .../animation/cubic_interpolator_base.dart | 114 - .../cubic_interpolator_component_base.dart | 114 - .../cubic_value_interpolator_base.dart | 18 - .../animation/elastic_interpolator_base.dart | 97 - .../generated/animation/entry_state_base.dart | 18 - .../generated/animation/exit_state_base.dart | 18 - .../interpolating_keyframe_base.dart | 75 - .../animation/keyed_object_base.dart | 45 - .../animation/keyed_property_base.dart | 46 - .../generated/animation/keyframe_base.dart | 45 - .../animation/keyframe_bool_base.dart | 49 - .../animation/keyframe_callback_base.dart | 14 - .../animation/keyframe_color_base.dart | 49 - .../animation/keyframe_double_base.dart | 49 - .../generated/animation/keyframe_id_base.dart | 49 - .../animation/keyframe_interpolator_base.dart | 13 - .../animation/keyframe_string_base.dart | 49 - .../animation/keyframe_uint_base.dart | 49 - .../generated/animation/layer_state_base.dart | 45 - .../animation/linear_animation_base.dart | 225 - .../animation/listener_action_base.dart | 13 - .../animation/listener_align_target_base.dart | 74 - .../animation/listener_bool_change_base.dart | 51 - .../animation/listener_fire_event_base.dart | 47 - .../animation/listener_input_change_base.dart | 73 - .../listener_number_change_base.dart | 51 - .../listener_trigger_change_base.dart | 18 - .../listener_viewmodel_change_base.dart | 14 - .../generated/animation/nested_bool_base.dart | 47 - .../animation/nested_input_base.dart | 46 - .../nested_linear_animation_base.dart | 55 - .../animation/nested_number_base.dart | 50 - .../nested_remap_animation_base.dart | 55 - .../nested_simple_animation_base.dart | 80 - .../animation/nested_state_machine_base.dart | 21 - .../animation/nested_trigger_base.dart | 24 - .../animation/state_machine_base.dart | 13 - .../animation/state_machine_bool_base.dart | 49 - .../state_machine_component_base.dart | 47 - .../animation/state_machine_double_base.dart | 40 - .../animation/state_machine_event_base.dart | 70 - .../state_machine_fire_event_base.dart | 72 - .../animation/state_machine_input_base.dart | 14 - .../animation/state_machine_layer_base.dart | 14 - .../state_machine_layer_component_base.dart | 14 - .../state_machine_listener_base.dart | 98 - .../animation/state_machine_number_base.dart | 49 - .../animation/state_machine_trigger_base.dart | 18 - .../animation/state_transition_base.dart | 202 - .../transition_artboard_condition_base.dart | 19 - .../transition_bool_condition_base.dart | 20 - .../animation/transition_comparator_base.dart | 13 - .../animation/transition_condition_base.dart | 13 - .../transition_double_condition_base.dart | 40 - .../transition_input_condition_base.dart | 47 - .../transition_number_condition_base.dart | 51 - ...ion_property_artboard_comparator_base.dart | 54 - .../transition_property_comparator_base.dart | 16 - ...on_property_viewmodel_comparator_base.dart | 20 - .../transition_trigger_condition_base.dart | 18 - ...nsition_value_boolean_comparator_base.dart | 50 - ...ransition_value_color_comparator_base.dart | 50 - .../transition_value_comparator_base.dart | 14 - .../transition_value_condition_base.dart | 51 - ...transition_value_enum_comparator_base.dart | 52 - ...ansition_value_number_comparator_base.dart | 50 - ...ansition_value_string_comparator_base.dart | 50 - .../transition_viewmodel_condition_base.dart | 101 - lib/src/generated/artboard_base.dart | 182 - lib/src/generated/asset_base.dart | 12 - lib/src/generated/assets/asset_base.dart | 44 - .../generated/assets/audio_asset_base.dart | 19 - .../generated/assets/drawable_asset_base.dart | 73 - .../generated/assets/export_audio_base.dart | 48 - lib/src/generated/assets/file_asset_base.dart | 96 - .../assets/file_asset_contents_base.dart | 45 - lib/src/generated/assets/folder_base.dart | 12 - lib/src/generated/assets/font_asset_base.dart | 14 - .../generated/assets/image_asset_base.dart | 19 - lib/src/generated/audio_event_base.dart | 52 - lib/src/generated/backboard_base.dart | 12 - lib/src/generated/bones/bone_base.dart | 54 - .../generated/bones/cubic_weight_base.dart | 114 - lib/src/generated/bones/root_bone_base.dart | 83 - .../bones/skeletal_component_base.dart | 22 - lib/src/generated/bones/skin_base.dart | 172 - lib/src/generated/bones/tendon_base.dart | 195 - lib/src/generated/bones/weight_base.dart | 66 - lib/src/generated/component_base.dart | 70 - .../constraints/constraint_base.dart | 46 - .../constraints/distance_constraint_base.dart | 79 - .../follow_path_constraint_base.dart | 106 - .../constraints/ik_constraint_base.dart | 82 - .../constraints/rotation_constraint_base.dart | 24 - .../constraints/scale_constraint_base.dart | 26 - .../constraints/targeted_constraint_base.dart | 52 - .../transform_component_constraint_base.dart | 233 - ...transform_component_constraint_y_base.dart | 184 - .../transform_constraint_base.dart | 80 - .../transform_space_constraint_base.dart | 80 - .../translation_constraint_base.dart | 26 - .../generated/container_component_base.dart | 14 - lib/src/generated/custom_property_base.dart | 12 - .../custom_property_boolean_base.dart | 50 - .../custom_property_number_base.dart | 50 - .../custom_property_string_base.dart | 50 - .../data_bind/bindable_property_base.dart | 13 - .../bindable_property_boolean_base.dart | 48 - .../bindable_property_color_base.dart | 48 - .../bindable_property_enum_base.dart | 48 - .../bindable_property_number_base.dart | 48 - .../bindable_property_string_base.dart | 48 - .../converters/data_converter_base.dart | 45 - .../generated/data_bind/data_bind_base.dart | 95 - .../data_bind/data_bind_context_base.dart | 47 - lib/src/generated/draw_rules_base.dart | 51 - lib/src/generated/draw_target_base.dart | 71 - lib/src/generated/drawable_base.dart | 79 - lib/src/generated/event_base.dart | 23 - lib/src/generated/joystick_base.dart | 310 - .../layout/grid_track_sizing_group_base.dart | 129 - .../layout/layout_component_style_base.dart | 1773 ------ .../layout/track_sizing_function_base.dart | 175 - .../layout_component_absolute_base.dart | 22 - lib/src/generated/layout_component_base.dart | 127 - lib/src/generated/nested_animation_base.dart | 51 - lib/src/generated/nested_artboard_base.dart | 134 - lib/src/generated/node_base.dart | 79 - lib/src/generated/open_url_event_base.dart | 78 - lib/src/generated/rive_core_context.dart | 5526 ----------------- .../generated/shapes/clipping_shape_base.dart | 94 - .../shapes/contour_mesh_vertex_base.dart | 22 - .../shapes/cubic_asymmetric_vertex_base.dart | 108 - .../shapes/cubic_detached_vertex_base.dart | 134 - .../shapes/cubic_mirrored_vertex_base.dart | 82 - .../generated/shapes/cubic_vertex_base.dart | 23 - lib/src/generated/shapes/ellipse_base.dart | 27 - .../generated/shapes/forced_edge_base.dart | 67 - lib/src/generated/shapes/image_base.dart | 108 - lib/src/generated/shapes/mesh_base.dart | 48 - .../generated/shapes/mesh_vertex_base.dart | 77 - lib/src/generated/shapes/paint/fill_base.dart | 50 - .../shapes/paint/gradient_stop_base.dart | 67 - .../shapes/paint/linear_gradient_base.dart | 141 - .../shapes/paint/radial_gradient_base.dart | 20 - .../shapes/paint/shape_paint_base.dart | 49 - .../shapes/paint/solid_color_base.dart | 44 - .../generated/shapes/paint/stroke_base.dart | 121 - .../shapes/paint/trim_path_base.dart | 113 - .../shapes/parametric_path_base.dart | 134 - lib/src/generated/shapes/path_base.dart | 54 - .../generated/shapes/path_composer_base.dart | 13 - .../generated/shapes/path_vertex_base.dart | 20 - .../generated/shapes/points_path_base.dart | 59 - lib/src/generated/shapes/polygon_base.dart | 86 - lib/src/generated/shapes/rectangle_base.dart | 165 - lib/src/generated/shapes/shape_base.dart | 25 - lib/src/generated/shapes/star_base.dart | 63 - .../shapes/straight_vertex_base.dart | 56 - lib/src/generated/shapes/triangle_base.dart | 27 - lib/src/generated/shapes/vertex_base.dart | 75 - lib/src/generated/solo_base.dart | 57 - lib/src/generated/text/text_base.dart | 329 - .../generated/text/text_modifier_base.dart | 12 - .../text/text_modifier_group_base.dart | 234 - .../text/text_modifier_range_base.dart | 282 - .../text/text_shape_modifier_base.dart | 18 - .../generated/text/text_style_axis_base.dart | 67 - lib/src/generated/text/text_style_base.dart | 119 - .../text/text_style_feature_base.dart | 69 - .../generated/text/text_value_run_base.dart | 71 - .../text/text_variation_modifier_base.dart | 74 - .../generated/transform_component_base.dart | 97 - .../generated/viewmodel/data_enum_base.dart | 13 - .../viewmodel/data_enum_value_base.dart | 70 - .../generated/viewmodel/viewmodel_base.dart | 48 - .../viewmodel/viewmodel_component_base.dart | 46 - .../viewmodel/viewmodel_instance_base.dart | 46 - .../viewmodel_instance_boolean_base.dart | 51 - .../viewmodel_instance_color_base.dart | 49 - .../viewmodel_instance_enum_base.dart | 49 - .../viewmodel_instance_list_base.dart | 15 - .../viewmodel_instance_list_item_base.dart | 124 - .../viewmodel_instance_number_base.dart | 49 - .../viewmodel_instance_string_base.dart | 49 - .../viewmodel_instance_value_base.dart | 48 - .../viewmodel_instance_viewmodel_base.dart | 51 - .../viewmodel/viewmodel_property_base.dart | 14 - .../viewmodel_property_boolean_base.dart | 18 - .../viewmodel_property_color_base.dart | 18 - .../viewmodel_property_enum_base.dart | 51 - .../viewmodel_property_list_base.dart | 18 - .../viewmodel_property_number_base.dart | 18 - .../viewmodel_property_string_base.dart | 18 - .../viewmodel_property_viewmodel_base.dart | 52 - .../world_transform_component_base.dart | 49 - lib/src/layer_component_events.dart | 22 - lib/src/listener_actions.dart | 20 - lib/src/local_file_io.dart | 5 - lib/src/local_file_web.dart | 5 - lib/src/models/artboard_selector.dart | 69 + lib/src/models/data_bind.dart | 114 + lib/src/models/state_machine_selector.dart | 69 + lib/src/painters/widget_controller.dart | 183 + lib/src/platform.dart | 6 - lib/src/platform_native.dart | 10 - lib/src/platform_web.dart | 8 - lib/src/rive.dart | 402 -- .../animation/advanceable_state.dart | 7 - lib/src/rive_core/animation/animation.dart | 32 - .../animation/animation_reset_factory.dart | 284 - .../rive_core/animation/animation_state.dart | 60 - .../animation/animation_state_instance.dart | 36 - lib/src/rive_core/animation/any_state.dart | 9 - .../rive_core/animation/blend_animation.dart | 47 - .../animation/blend_animation_1d.dart | 7 - .../animation/blend_animation_direct.dart | 39 - lib/src/rive_core/animation/blend_state.dart | 21 - .../rive_core/animation/blend_state_1d.dart | 52 - .../animation/blend_state_1d_instance.dart | 106 - .../animation/blend_state_direct.dart | 10 - .../blend_state_direct_instance.dart | 30 - .../animation/blend_state_instance.dart | 65 - .../animation/blend_state_transition.dart | 32 - .../animation/cubic_ease_interpolator.dart | 50 - .../animation/cubic_interpolator.dart | 140 - .../cubic_interpolator_component.dart | 57 - .../animation/cubic_value_interpolator.dart | 63 - .../animation/elastic_interpolator.dart | 133 - lib/src/rive_core/animation/entry_state.dart | 9 - lib/src/rive_core/animation/exit_state.dart | 9 - .../animation/interpolating_keyframe.dart | 68 - lib/src/rive_core/animation/interpolator.dart | 12 - lib/src/rive_core/animation/keyed_object.dart | 119 - .../rive_core/animation/keyed_property.dart | 236 - lib/src/rive_core/animation/keyframe.dart | 49 - .../rive_core/animation/keyframe_bool.dart | 23 - .../animation/keyframe_callback.dart | 14 - .../rive_core/animation/keyframe_color.dart | 43 - .../rive_core/animation/keyframe_double.dart | 34 - lib/src/rive_core/animation/keyframe_id.dart | 23 - .../animation/keyframe_interpolation.dart | 29 - .../animation/keyframe_interpolator.dart | 26 - .../rive_core/animation/keyframe_string.dart | 23 - .../rive_core/animation/keyframe_uint.dart | 23 - lib/src/rive_core/animation/layer_state.dart | 45 - .../rive_core/animation/linear_animation.dart | 170 - .../animation/linear_animation_instance.dart | 246 - .../rive_core/animation/listener_action.dart | 31 - .../animation/listener_align_target.dart | 42 - .../animation/listener_bool_change.dart | 42 - .../animation/listener_fire_event.dart | 22 - .../animation/listener_input_change.dart | 60 - .../animation/listener_number_change.dart | 22 - .../animation/listener_trigger_change.dart | 21 - .../animation/listener_viewmodel_change.dart | 11 - lib/src/rive_core/animation/loop.dart | 12 - lib/src/rive_core/animation/nested_bool.dart | 17 - lib/src/rive_core/animation/nested_input.dart | 49 - .../animation/nested_linear_animation.dart | 49 - .../rive_core/animation/nested_number.dart | 17 - .../animation/nested_remap_animation.dart | 24 - .../animation/nested_simple_animation.dart | 33 - .../animation/nested_state_machine.dart | 111 - .../rive_core/animation/nested_trigger.dart | 20 - .../rive_core/animation/state_instance.dart | 35 - .../rive_core/animation/state_machine.dart | 27 - .../animation/state_machine_bool.dart | 10 - .../animation/state_machine_component.dart | 59 - .../animation/state_machine_fire_event.dart | 39 - .../animation/state_machine_input.dart | 21 - .../animation/state_machine_layer.dart | 44 - .../state_machine_layer_component.dart | 29 - .../animation/state_machine_listener.dart | 94 - .../animation/state_machine_number.dart | 7 - .../animation/state_machine_trigger.dart | 9 - .../rive_core/animation/state_transition.dart | 253 - .../transition_artboard_condition.dart | 5 - .../animation/transition_bool_condition.dart | 24 - .../animation/transition_comparator.dart | 40 - .../animation/transition_condition.dart | 34 - .../animation/transition_input_condition.dart | 35 - .../transition_number_condition.dart | 40 - .../transition_property_comparator.dart | 6 - ...nsition_property_viewmodel_comparator.dart | 20 - .../transition_trigger_condition.dart | 23 - .../transition_value_boolean_comparator.dart | 23 - .../transition_value_color_comparator.dart | 23 - .../transition_value_comparator.dart | 6 - .../animation/transition_value_condition.dart | 11 - .../transition_value_enum_comparator.dart | 22 - .../transition_value_number_comparator.dart | 23 - .../transition_value_string_comparator.dart | 23 - .../transition_viewmodel_condition.dart | 27 - lib/src/rive_core/artboard.dart | 843 --- lib/src/rive_core/assets/asset.dart | 14 - lib/src/rive_core/assets/audio_asset.dart | 47 - lib/src/rive_core/assets/drawable_asset.dart | 11 - lib/src/rive_core/assets/export_audio.dart | 7 - lib/src/rive_core/assets/file_asset.dart | 116 - .../rive_core/assets/file_asset_contents.dart | 33 - lib/src/rive_core/assets/folder.dart | 4 - lib/src/rive_core/assets/font_asset.dart | 77 - lib/src/rive_core/assets/image_asset.dart | 47 - lib/src/rive_core/audio_event.dart | 43 - lib/src/rive_core/audio_player.dart | 130 - lib/src/rive_core/backboard.dart | 33 - lib/src/rive_core/bones/bone.dart | 79 - lib/src/rive_core/bones/cubic_weight.dart | 21 - lib/src/rive_core/bones/root_bone.dart | 14 - .../rive_core/bones/skeletal_component.dart | 4 - lib/src/rive_core/bones/skin.dart | 178 - lib/src/rive_core/bones/skinnable.dart | 36 - lib/src/rive_core/bones/tendon.dart | 78 - lib/src/rive_core/bones/weight.dart | 50 - lib/src/rive_core/bones/weighted_vertex.dart | 158 - lib/src/rive_core/bounds_provider.dart | 13 - lib/src/rive_core/component.dart | 293 - lib/src/rive_core/component_dirt.dart | 62 - lib/src/rive_core/component_flags.dart | 16 - lib/src/rive_core/constraints/constraint.dart | 49 - .../constraints/distance_constraint.dart | 64 - .../constraints/follow_path_constraint.dart | 179 - .../rive_core/constraints/ik_constraint.dart | 306 - .../constraints/rotation_constraint.dart | 104 - .../constraints/scale_constraint.dart | 109 - .../constraints/targeted_constraint.dart | 43 - .../transform_component_constraint.dart | 33 - .../transform_component_constraint_y.dart | 23 - .../constraints/transform_constraint.dart | 78 - .../transform_space_constraint.dart | 23 - .../constraints/translation_constraint.dart | 93 - lib/src/rive_core/container_component.dart | 92 - lib/src/rive_core/custom_property.dart | 8 - .../rive_core/custom_property_boolean.dart | 8 - lib/src/rive_core/custom_property_number.dart | 8 - lib/src/rive_core/custom_property_string.dart | 8 - .../data_bind/bindable_property.dart | 19 - .../data_bind/bindable_property_boolean.dart | 8 - .../data_bind/bindable_property_color.dart | 8 - .../data_bind/bindable_property_enum.dart | 8 - .../data_bind/bindable_property_number.dart | 8 - .../data_bind/bindable_property_string.dart | 8 - .../data_bind/context/context_value.dart | 10 - .../context/context_value_boolean.dart | 25 - .../context/context_value_color.dart | 25 - .../data_bind/context/context_value_enum.dart | 17 - .../data_bind/context/context_value_list.dart | 17 - .../context/context_value_number.dart | 25 - .../context/context_value_string.dart | 25 - lib/src/rive_core/data_bind/data_bind.dart | 79 - .../data_bind/data_bind_context.dart | 78 - lib/src/rive_core/data_bind/data_context.dart | 54 - lib/src/rive_core/data_bind_flags.dart | 14 - lib/src/rive_core/dependency_helper.dart | 27 - lib/src/rive_core/draw_rules.dart | 62 - lib/src/rive_core/draw_target.dart | 48 - lib/src/rive_core/drawable.dart | 95 - lib/src/rive_core/enum_helper.dart | 3 - lib/src/rive_core/event.dart | 59 - lib/src/rive_core/joystick.dart | 256 - lib/src/rive_core/layer_state_flags.dart | 7 - .../layout/layout_component_style.dart | 516 -- lib/src/rive_core/layout_component.dart | 700 --- lib/src/rive_core/nested_animation.dart | 25 - lib/src/rive_core/nested_artboard.dart | 355 -- lib/src/rive_core/node.dart | 26 - lib/src/rive_core/notifier.dart | 7 - lib/src/rive_core/open_url_event.dart | 26 - lib/src/rive_core/open_url_target.dart | 2 - .../rive_core/rive_animation_controller.dart | 32 - .../rive_core/rive_core_singleton_test.dart | 36 - .../rive_format_error_exception.dart | 8 - .../rive_unsupported_version_exception.dart | 19 - lib/src/rive_core/runtime/runtime_header.dart | 92 - lib/src/rive_core/shapes/clipping_shape.dart | 95 - .../rive_core/shapes/contour_mesh_vertex.dart | 4 - .../shapes/cubic_asymmetric_vertex.dart | 97 - .../shapes/cubic_detached_vertex.dart | 96 - .../shapes/cubic_mirrored_vertex.dart | 76 - lib/src/rive_core/shapes/cubic_vertex.dart | 31 - lib/src/rive_core/shapes/ellipse.dart | 52 - lib/src/rive_core/shapes/image.dart | 160 - lib/src/rive_core/shapes/mesh.dart | 154 - lib/src/rive_core/shapes/mesh_vertex.dart | 20 - lib/src/rive_core/shapes/paint/fill.dart | 43 - .../rive_core/shapes/paint/gradient_stop.dart | 42 - .../shapes/paint/linear_gradient.dart | 175 - .../shapes/paint/radial_gradient.dart | 12 - .../rive_core/shapes/paint/shape_paint.dart | 91 - .../shapes/paint/shape_paint_mutator.dart | 36 - .../rive_core/shapes/paint/solid_color.dart | 52 - lib/src/rive_core/shapes/paint/stroke.dart | 91 - .../rive_core/shapes/paint/stroke_effect.dart | 6 - lib/src/rive_core/shapes/paint/trim_path.dart | 98 - .../shapes/paint/trim_path_drawing.dart | 143 - lib/src/rive_core/shapes/parametric_path.dart | 73 - lib/src/rive_core/shapes/path.dart | 547 -- lib/src/rive_core/shapes/path_composer.dart | 117 - lib/src/rive_core/shapes/path_vertex.dart | 12 - lib/src/rive_core/shapes/points_path.dart | 85 - lib/src/rive_core/shapes/polygon.dart | 35 - lib/src/rive_core/shapes/rectangle.dart | 50 - lib/src/rive_core/shapes/shape.dart | 327 - .../shapes/shape_paint_container.dart | 77 - lib/src/rive_core/shapes/star.dart | 41 - lib/src/rive_core/shapes/straight_vertex.dart | 48 - lib/src/rive_core/shapes/triangle.dart | 26 - lib/src/rive_core/shapes/vertex.dart | 63 - lib/src/rive_core/solo.dart | 69 - .../rive_core/state_machine_controller.dart | 1076 ---- lib/src/rive_core/state_transition_flags.dart | 20 - lib/src/rive_core/text/styled_text.dart | 46 - lib/src/rive_core/text/text.dart | 935 --- lib/src/rive_core/text/text_modifier.dart | 8 - .../rive_core/text/text_modifier_group.dart | 322 - .../rive_core/text/text_modifier_range.dart | 434 -- .../rive_core/text/text_shape_modifier.dart | 12 - lib/src/rive_core/text/text_style.dart | 320 - lib/src/rive_core/text/text_style_axis.dart | 20 - .../rive_core/text/text_style_container.dart | 65 - .../rive_core/text/text_style_feature.dart | 20 - lib/src/rive_core/text/text_value_run.dart | 69 - .../text/text_variation_modifier.dart | 31 - lib/src/rive_core/transform_component.dart | 236 - lib/src/rive_core/transform_space.dart | 1 - lib/src/rive_core/viewmodel/data_enum.dart | 11 - .../rive_core/viewmodel/data_enum_value.dart | 17 - lib/src/rive_core/viewmodel/viewmodel.dart | 65 - .../viewmodel/viewmodel_component.dart | 14 - .../viewmodel/viewmodel_instance.dart | 79 - .../viewmodel/viewmodel_instance_boolean.dart | 11 - .../viewmodel/viewmodel_instance_color.dart | 11 - .../viewmodel/viewmodel_instance_enum.dart | 11 - .../viewmodel/viewmodel_instance_list.dart | 29 - .../viewmodel_instance_list_item.dart | 23 - .../viewmodel/viewmodel_instance_number.dart | 11 - .../viewmodel/viewmodel_instance_string.dart | 11 - .../viewmodel/viewmodel_instance_value.dart | 27 - .../viewmodel_instance_viewmodel.dart | 20 - .../viewmodel/viewmodel_property.dart | 11 - .../viewmodel/viewmodel_property_boolean.dart | 5 - .../viewmodel/viewmodel_property_color.dart | 5 - .../viewmodel/viewmodel_property_enum.dart | 8 - .../viewmodel/viewmodel_property_list.dart | 5 - .../viewmodel/viewmodel_property_number.dart | 5 - .../viewmodel/viewmodel_property_string.dart | 5 - .../viewmodel_property_viewmodel.dart | 10 - .../rive_core/world_transform_component.dart | 31 - lib/src/rive_extensions.dart | 18 + lib/src/rive_file.dart | 508 -- lib/src/rive_render_box.dart | 421 -- lib/src/rive_scene.dart | 109 - lib/src/runtime_artboard.dart | 260 - lib/src/runtime_event.dart | 105 - lib/src/runtime_mounted_artboard.dart | 168 - lib/src/runtime_nested_artboard.dart | 170 - lib/src/state_machine_components.dart | 20 - lib/src/state_transition_conditions.dart | 20 - lib/src/state_transitions.dart | 19 - lib/src/utilities/utilities.dart | 64 - lib/src/viewmodel_list_items.dart | 21 - lib/src/viewmodel_properties.dart | 20 - lib/src/widgets/rive_animation.dart | 374 -- lib/src/widgets/rive_builder.dart | 192 + lib/src/widgets/rive_widget.dart | 113 + platform_considerations.md | 8 +- pubspec.yaml | 25 +- shared_lib/build_shared.sh | 59 - test/artboard_test.dart | 48 +- test/asset_gc_test.dart | 71 - test/asset_test.dart | 274 - test/assets/batch_rivs/circle-fui.riv | 3 - test/assets/batch_rivs/danger-quarantine.riv | 3 - test/assets/batch_rivs/fire-skull.riv | 3 - .../assets/batch_rivs/joystick-demos-fish.riv | 3 - test/assets/batch_rivs/polito.riv | 3 - test/assets/cdn_image.riv | 3 - test/assets/component_discovery.riv | 3 - test/assets/electrified_button_simple.riv | 3 - test/assets/event_on_listener.riv | 3 - test/assets/events_from_trigger_test.riv | 3 - test/assets/events_on_states.riv | 3 - test/assets/file.png | 3 - test/assets/follow_path_path.riv | 3 - test/assets/follow_path_shapes.riv | 3 - test/assets/follow_path_solos.riv | 3 - test/assets/hit_test_consume.riv | 3 - test/assets/hit_test_pass_through.riv | 3 - test/assets/image_asset_prod.riv | 3 - test/assets/image_asset_uat.riv | 3 - test/assets/joystick_handle_source.riv | 3 - test/assets/off_road_car.riv | 3 - test/assets/rive-flutter-test-asset.riv | 3 - test/assets/runtime_nested_inputs.riv | 3 - test/assets/sample_image.riv | 3 - test/assets/skins_demo.riv | 3 - test/assets/spilled_time.riv | 3 - test/component_find_test.dart | 76 - .../batch_tests/golden_batch_test.dart | 72 - .../batch_tests/images/circle-fui.riv-01.png | 3 - .../batch_tests/images/circle-fui.riv-02.png | 3 - .../batch_tests/images/circle-fui.riv-03.png | 3 - .../images/danger-quarantine.riv-01.png | 3 - .../images/danger-quarantine.riv-02.png | 3 - .../images/danger-quarantine.riv-03.png | 3 - .../batch_tests/images/fire-skull.riv-01.png | 3 - .../batch_tests/images/fire-skull.riv-02.png | 3 - .../batch_tests/images/fire-skull.riv-03.png | 3 - .../images/joystick-demos-fish.riv-01.png | 3 - .../images/joystick-demos-fish.riv-02.png | 3 - .../images/joystick-demos-fish.riv-03.png | 3 - .../batch_tests/images/polito.riv-01.png | 3 - .../batch_tests/images/polito.riv-02.png | 3 - .../batch_tests/images/polito.riv-03.png | 3 - .../golden_follow_path_solos_test.dart | 59 - .../follow_path/golden_follow_path_test.dart | 100 - .../images/follow_path_over_time_01.png | 3 - .../images/follow_path_over_time_02.png | 3 - .../images/follow_path_over_time_03.png | 3 - .../images/follow_path_over_time_04.png | 3 - .../images/follow_path_path_01.png | 3 - .../images/follow_path_path_02.png | 3 - .../images/follow_path_path_03.png | 3 - .../images/follow_path_solos_01.png | 3 - .../images/follow_path_solos_02.png | 3 - .../images/follow_path_solos_03.png | 3 - .../images/follow_path_solos_04.png | 3 - test/goldens/golden_comparator.dart | 62 - .../joysticks/golden_joysticks_test.dart | 64 - .../images/joystick_handle_source_01.png | 3 - .../images/joystick_handle_source_02.png | 3 - .../images/joystick_handle_source_03.png | 3 - .../images/joystick_handle_source_04.png | 3 - .../golden_simple_animations_test.dart | 96 - .../images/mixed_animations_01.png | 3 - .../images/mixed_animations_02.png | 3 - .../images/play_first_animation_found.png | 3 - .../play_provided_animation_controller_01.png | 3 - .../play_provided_animation_controller_02.png | 3 - .../golden_skins_opacity_test.dart | 82 - .../skins_opacity/images/skins_opacity_01.png | 3 - .../skins_opacity/images/skins_opacity_02.png | 3 - .../skins_opacity/images/skins_opacity_03.png | 3 - .../skins_opacity/images/skins_opacity_04.png | 3 - .../skins_opacity/images/skins_opacity_05.png | 3 - .../spilled_time/images/spilled_time_00.png | 3 - .../spilled_time/images/spilled_time_01.png | 3 - .../spilled_time/images/spilled_time_02.png | 3 - .../spilled_time/images/spilled_time_03.png | 3 - .../spilled_time/images/spilled_time_04.png | 3 - .../spilled_time/images/spilled_time_05.png | 3 - .../images/spilled_time_exact_00.png | 3 - .../images/spilled_time_exact_01.png | 3 - .../images/spilled_time_exact_02.png | 3 - .../images/spilled_time_overshoot_00.png | 3 - .../images/spilled_time_overshoot_01.png | 3 - .../images/spilled_time_overshoot_02.png | 3 - .../spilled_time/spilled_time_test.dart | 151 - test/goldens/text/golden_text_test.dart | 64 - .../text/images/text_bones_constraint_01.png | 3 - .../text/images/text_bones_constraint_02.png | 3 - .../text/images/text_bones_constraint_03.png | 3 - .../text/images/text_bones_constraint_04.png | 3 - .../ticker_mode/golden_ticker_mode_test.dart | 127 - .../ticker_mode/images/ticker_mode_false.png | 3 - .../ticker_mode/images/ticker_mode_true_1.png | 3 - .../ticker_mode/images/ticker_mode_true_2.png | 3 - .../images/ticker_mode_true_paused_state.png | 3 - test/hit_test.dart | 158 - test/linear_animation_instance_test.dart | 68 - test/mocks/fakes.dart | 19 - test/mocks/mocks.dart | 10 - test/nested_input_test.dart | 62 - test/rive_animation_test.dart | 352 -- test/rive_file_test.dart | 36 - test/rive_network_test.dart | 60 - test/simple_animation_test.dart | 57 - test/src/network.dart | 43 - test/src/utils.dart | 45 - 699 files changed, 3027 insertions(+), 46353 deletions(-) create mode 100644 example/assets/button.riv create mode 100644 example/assets/databinding_images.riv create mode 100644 example/assets/electrified_button_nested_text.riv create mode 100644 example/assets/fonts/JetBrains Mono.ttf create mode 100644 example/assets/images/databound_image_1.jpg create mode 100644 example/assets/images/databound_image_2.jpg create mode 100644 example/assets/layout_test.riv rename example/assets/{rating_animation.riv => rating.riv} (100%) create mode 100644 example/assets/rewards.riv delete mode 100644 example/lib/artboard_nested_inputs.dart delete mode 100644 example/lib/basic_text.dart delete mode 100644 example/lib/carousel.dart delete mode 100644 example/lib/custom_asset_loading.dart delete mode 100644 example/lib/custom_controller.dart delete mode 100644 example/lib/event_open_url_button.dart delete mode 100644 example/lib/event_star_rating.dart delete mode 100644 example/lib/example_state_machine.dart create mode 100644 example/lib/examples/animation_painter.dart create mode 100644 example/lib/examples/databinding.dart create mode 100644 example/lib/examples/databinding_images.dart create mode 100644 example/lib/examples/events.dart create mode 100644 example/lib/examples/examples.dart create mode 100644 example/lib/examples/hit_test_behaviour.dart create mode 100644 example/lib/examples/inputs.dart create mode 100644 example/lib/examples/network_asset.dart create mode 100644 example/lib/examples/out_of_band_assets.dart rename example/lib/{custom_cached_asset_loading.dart => examples/out_of_band_assets_cached.dart} (55%) create mode 100644 example/lib/examples/responsive_layouts.dart create mode 100644 example/lib/examples/rive_audio.dart create mode 100644 example/lib/examples/rive_widget.dart create mode 100644 example/lib/examples/rive_widget_builder.dart create mode 100644 example/lib/examples/state_machine_painter.dart create mode 100644 example/lib/examples/text_runs.dart create mode 100644 example/lib/examples/ticker_mode.dart create mode 100644 example/lib/examples/time_dilation.dart create mode 100644 example/lib/examples/todo.dart delete mode 100644 example/lib/liquid_download.dart delete mode 100644 example/lib/little_machine.dart delete mode 100644 example/lib/play_one_shot_animation.dart delete mode 100644 example/lib/play_pause_animation.dart delete mode 100644 example/lib/rive_audio.dart delete mode 100644 example/lib/rive_audio_out_of_band.dart delete mode 100644 example/lib/simple_animation.dart delete mode 100644 example/lib/simple_animation_network.dart delete mode 100644 example/lib/simple_machine_listener.dart delete mode 100644 example/lib/simple_state_machine.dart delete mode 100644 example/lib/skinning_demo.dart delete mode 100644 example/lib/state_machine_skills.dart create mode 100644 example/macos/Podfile.lock delete mode 100644 lib/components.dart delete mode 100644 lib/math.dart delete mode 100644 lib/rive_web.dart delete mode 100644 lib/src/animation_list.dart delete mode 100644 lib/src/asset.dart delete mode 100644 lib/src/asset_list.dart delete mode 100644 lib/src/asset_loader.dart delete mode 100644 lib/src/blend_animations.dart delete mode 100644 lib/src/container_children.dart delete mode 100644 lib/src/controllers/linear_animation_controller.dart delete mode 100644 lib/src/controllers/one_shot_controller.dart delete mode 100644 lib/src/controllers/simple_controller.dart delete mode 100644 lib/src/controllers/state_machine_controller.dart delete mode 100644 lib/src/core/core.dart delete mode 100644 lib/src/core/field_types/core_bool_type.dart delete mode 100644 lib/src/core/field_types/core_bytes_type.dart delete mode 100644 lib/src/core/field_types/core_callback_type.dart delete mode 100644 lib/src/core/field_types/core_color_type.dart delete mode 100644 lib/src/core/field_types/core_double_type.dart delete mode 100644 lib/src/core/field_types/core_field_type.dart delete mode 100644 lib/src/core/field_types/core_int_type.dart delete mode 100644 lib/src/core/field_types/core_string_type.dart delete mode 100644 lib/src/core/field_types/core_uint_type.dart delete mode 100644 lib/src/core/importers/artboard_import_stack_object.dart delete mode 100644 lib/src/core/importers/artboard_importer.dart delete mode 100644 lib/src/core/importers/backboard_importer.dart delete mode 100644 lib/src/core/importers/file_asset_importer.dart delete mode 100644 lib/src/core/importers/keyed_object_importer.dart delete mode 100644 lib/src/core/importers/keyed_property_importer.dart delete mode 100644 lib/src/core/importers/layer_state_importer.dart delete mode 100644 lib/src/core/importers/linear_animation_importer.dart delete mode 100644 lib/src/core/importers/nested_state_machine_importer.dart delete mode 100644 lib/src/core/importers/state_machine_importer.dart delete mode 100644 lib/src/core/importers/state_machine_layer_component_importer.dart delete mode 100644 lib/src/core/importers/state_machine_layer_importer.dart delete mode 100644 lib/src/core/importers/state_machine_listener_importer.dart delete mode 100644 lib/src/core/importers/state_transition_importer.dart delete mode 100644 lib/src/core/importers/viewmodel_instance_importer.dart delete mode 100644 lib/src/data_enum_values.dart delete mode 100644 lib/src/debug.dart delete mode 100644 lib/src/dynamic_library_helper/dynamic_library_helper_ffi.dart delete mode 100644 lib/src/dynamic_library_helper/dynamic_library_helper_stub.dart delete mode 100644 lib/src/dynamic_library_helper/dynamic_library_helper_web.dart create mode 100644 lib/src/errors.dart delete mode 100644 lib/src/event_list.dart delete mode 100644 lib/src/extensions.dart create mode 100644 lib/src/file_loader.dart delete mode 100644 lib/src/generated/animation/advanceable_state_base.dart delete mode 100644 lib/src/generated/animation/animation_base.dart delete mode 100644 lib/src/generated/animation/animation_state_base.dart delete mode 100644 lib/src/generated/animation/any_state_base.dart delete mode 100644 lib/src/generated/animation/blend_animation_1d_base.dart delete mode 100644 lib/src/generated/animation/blend_animation_base.dart delete mode 100644 lib/src/generated/animation/blend_animation_direct_base.dart delete mode 100644 lib/src/generated/animation/blend_state_1d_base.dart delete mode 100644 lib/src/generated/animation/blend_state_base.dart delete mode 100644 lib/src/generated/animation/blend_state_direct_base.dart delete mode 100644 lib/src/generated/animation/blend_state_transition_base.dart delete mode 100644 lib/src/generated/animation/cubic_ease_interpolator_base.dart delete mode 100644 lib/src/generated/animation/cubic_interpolator_base.dart delete mode 100644 lib/src/generated/animation/cubic_interpolator_component_base.dart delete mode 100644 lib/src/generated/animation/cubic_value_interpolator_base.dart delete mode 100644 lib/src/generated/animation/elastic_interpolator_base.dart delete mode 100644 lib/src/generated/animation/entry_state_base.dart delete mode 100644 lib/src/generated/animation/exit_state_base.dart delete mode 100644 lib/src/generated/animation/interpolating_keyframe_base.dart delete mode 100644 lib/src/generated/animation/keyed_object_base.dart delete mode 100644 lib/src/generated/animation/keyed_property_base.dart delete mode 100644 lib/src/generated/animation/keyframe_base.dart delete mode 100644 lib/src/generated/animation/keyframe_bool_base.dart delete mode 100644 lib/src/generated/animation/keyframe_callback_base.dart delete mode 100644 lib/src/generated/animation/keyframe_color_base.dart delete mode 100644 lib/src/generated/animation/keyframe_double_base.dart delete mode 100644 lib/src/generated/animation/keyframe_id_base.dart delete mode 100644 lib/src/generated/animation/keyframe_interpolator_base.dart delete mode 100644 lib/src/generated/animation/keyframe_string_base.dart delete mode 100644 lib/src/generated/animation/keyframe_uint_base.dart delete mode 100644 lib/src/generated/animation/layer_state_base.dart delete mode 100644 lib/src/generated/animation/linear_animation_base.dart delete mode 100644 lib/src/generated/animation/listener_action_base.dart delete mode 100644 lib/src/generated/animation/listener_align_target_base.dart delete mode 100644 lib/src/generated/animation/listener_bool_change_base.dart delete mode 100644 lib/src/generated/animation/listener_fire_event_base.dart delete mode 100644 lib/src/generated/animation/listener_input_change_base.dart delete mode 100644 lib/src/generated/animation/listener_number_change_base.dart delete mode 100644 lib/src/generated/animation/listener_trigger_change_base.dart delete mode 100644 lib/src/generated/animation/listener_viewmodel_change_base.dart delete mode 100644 lib/src/generated/animation/nested_bool_base.dart delete mode 100644 lib/src/generated/animation/nested_input_base.dart delete mode 100644 lib/src/generated/animation/nested_linear_animation_base.dart delete mode 100644 lib/src/generated/animation/nested_number_base.dart delete mode 100644 lib/src/generated/animation/nested_remap_animation_base.dart delete mode 100644 lib/src/generated/animation/nested_simple_animation_base.dart delete mode 100644 lib/src/generated/animation/nested_state_machine_base.dart delete mode 100644 lib/src/generated/animation/nested_trigger_base.dart delete mode 100644 lib/src/generated/animation/state_machine_base.dart delete mode 100644 lib/src/generated/animation/state_machine_bool_base.dart delete mode 100644 lib/src/generated/animation/state_machine_component_base.dart delete mode 100644 lib/src/generated/animation/state_machine_double_base.dart delete mode 100644 lib/src/generated/animation/state_machine_event_base.dart delete mode 100644 lib/src/generated/animation/state_machine_fire_event_base.dart delete mode 100644 lib/src/generated/animation/state_machine_input_base.dart delete mode 100644 lib/src/generated/animation/state_machine_layer_base.dart delete mode 100644 lib/src/generated/animation/state_machine_layer_component_base.dart delete mode 100644 lib/src/generated/animation/state_machine_listener_base.dart delete mode 100644 lib/src/generated/animation/state_machine_number_base.dart delete mode 100644 lib/src/generated/animation/state_machine_trigger_base.dart delete mode 100644 lib/src/generated/animation/state_transition_base.dart delete mode 100644 lib/src/generated/animation/transition_artboard_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_bool_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_double_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_input_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_number_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_property_artboard_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_property_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_property_viewmodel_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_trigger_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_value_boolean_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_value_color_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_value_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_value_condition_base.dart delete mode 100644 lib/src/generated/animation/transition_value_enum_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_value_number_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_value_string_comparator_base.dart delete mode 100644 lib/src/generated/animation/transition_viewmodel_condition_base.dart delete mode 100644 lib/src/generated/artboard_base.dart delete mode 100644 lib/src/generated/asset_base.dart delete mode 100644 lib/src/generated/assets/asset_base.dart delete mode 100644 lib/src/generated/assets/audio_asset_base.dart delete mode 100644 lib/src/generated/assets/drawable_asset_base.dart delete mode 100644 lib/src/generated/assets/export_audio_base.dart delete mode 100644 lib/src/generated/assets/file_asset_base.dart delete mode 100644 lib/src/generated/assets/file_asset_contents_base.dart delete mode 100644 lib/src/generated/assets/folder_base.dart delete mode 100644 lib/src/generated/assets/font_asset_base.dart delete mode 100644 lib/src/generated/assets/image_asset_base.dart delete mode 100644 lib/src/generated/audio_event_base.dart delete mode 100644 lib/src/generated/backboard_base.dart delete mode 100644 lib/src/generated/bones/bone_base.dart delete mode 100644 lib/src/generated/bones/cubic_weight_base.dart delete mode 100644 lib/src/generated/bones/root_bone_base.dart delete mode 100644 lib/src/generated/bones/skeletal_component_base.dart delete mode 100644 lib/src/generated/bones/skin_base.dart delete mode 100644 lib/src/generated/bones/tendon_base.dart delete mode 100644 lib/src/generated/bones/weight_base.dart delete mode 100644 lib/src/generated/component_base.dart delete mode 100644 lib/src/generated/constraints/constraint_base.dart delete mode 100644 lib/src/generated/constraints/distance_constraint_base.dart delete mode 100644 lib/src/generated/constraints/follow_path_constraint_base.dart delete mode 100644 lib/src/generated/constraints/ik_constraint_base.dart delete mode 100644 lib/src/generated/constraints/rotation_constraint_base.dart delete mode 100644 lib/src/generated/constraints/scale_constraint_base.dart delete mode 100644 lib/src/generated/constraints/targeted_constraint_base.dart delete mode 100644 lib/src/generated/constraints/transform_component_constraint_base.dart delete mode 100644 lib/src/generated/constraints/transform_component_constraint_y_base.dart delete mode 100644 lib/src/generated/constraints/transform_constraint_base.dart delete mode 100644 lib/src/generated/constraints/transform_space_constraint_base.dart delete mode 100644 lib/src/generated/constraints/translation_constraint_base.dart delete mode 100644 lib/src/generated/container_component_base.dart delete mode 100644 lib/src/generated/custom_property_base.dart delete mode 100644 lib/src/generated/custom_property_boolean_base.dart delete mode 100644 lib/src/generated/custom_property_number_base.dart delete mode 100644 lib/src/generated/custom_property_string_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_boolean_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_color_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_enum_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_number_base.dart delete mode 100644 lib/src/generated/data_bind/bindable_property_string_base.dart delete mode 100644 lib/src/generated/data_bind/converters/data_converter_base.dart delete mode 100644 lib/src/generated/data_bind/data_bind_base.dart delete mode 100644 lib/src/generated/data_bind/data_bind_context_base.dart delete mode 100644 lib/src/generated/draw_rules_base.dart delete mode 100644 lib/src/generated/draw_target_base.dart delete mode 100644 lib/src/generated/drawable_base.dart delete mode 100644 lib/src/generated/event_base.dart delete mode 100644 lib/src/generated/joystick_base.dart delete mode 100644 lib/src/generated/layout/grid_track_sizing_group_base.dart delete mode 100644 lib/src/generated/layout/layout_component_style_base.dart delete mode 100644 lib/src/generated/layout/track_sizing_function_base.dart delete mode 100644 lib/src/generated/layout_component_absolute_base.dart delete mode 100644 lib/src/generated/layout_component_base.dart delete mode 100644 lib/src/generated/nested_animation_base.dart delete mode 100644 lib/src/generated/nested_artboard_base.dart delete mode 100644 lib/src/generated/node_base.dart delete mode 100644 lib/src/generated/open_url_event_base.dart delete mode 100644 lib/src/generated/rive_core_context.dart delete mode 100644 lib/src/generated/shapes/clipping_shape_base.dart delete mode 100644 lib/src/generated/shapes/contour_mesh_vertex_base.dart delete mode 100644 lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart delete mode 100644 lib/src/generated/shapes/cubic_detached_vertex_base.dart delete mode 100644 lib/src/generated/shapes/cubic_mirrored_vertex_base.dart delete mode 100644 lib/src/generated/shapes/cubic_vertex_base.dart delete mode 100644 lib/src/generated/shapes/ellipse_base.dart delete mode 100644 lib/src/generated/shapes/forced_edge_base.dart delete mode 100644 lib/src/generated/shapes/image_base.dart delete mode 100644 lib/src/generated/shapes/mesh_base.dart delete mode 100644 lib/src/generated/shapes/mesh_vertex_base.dart delete mode 100644 lib/src/generated/shapes/paint/fill_base.dart delete mode 100644 lib/src/generated/shapes/paint/gradient_stop_base.dart delete mode 100644 lib/src/generated/shapes/paint/linear_gradient_base.dart delete mode 100644 lib/src/generated/shapes/paint/radial_gradient_base.dart delete mode 100644 lib/src/generated/shapes/paint/shape_paint_base.dart delete mode 100644 lib/src/generated/shapes/paint/solid_color_base.dart delete mode 100644 lib/src/generated/shapes/paint/stroke_base.dart delete mode 100644 lib/src/generated/shapes/paint/trim_path_base.dart delete mode 100644 lib/src/generated/shapes/parametric_path_base.dart delete mode 100644 lib/src/generated/shapes/path_base.dart delete mode 100644 lib/src/generated/shapes/path_composer_base.dart delete mode 100644 lib/src/generated/shapes/path_vertex_base.dart delete mode 100644 lib/src/generated/shapes/points_path_base.dart delete mode 100644 lib/src/generated/shapes/polygon_base.dart delete mode 100644 lib/src/generated/shapes/rectangle_base.dart delete mode 100644 lib/src/generated/shapes/shape_base.dart delete mode 100644 lib/src/generated/shapes/star_base.dart delete mode 100644 lib/src/generated/shapes/straight_vertex_base.dart delete mode 100644 lib/src/generated/shapes/triangle_base.dart delete mode 100644 lib/src/generated/shapes/vertex_base.dart delete mode 100644 lib/src/generated/solo_base.dart delete mode 100644 lib/src/generated/text/text_base.dart delete mode 100644 lib/src/generated/text/text_modifier_base.dart delete mode 100644 lib/src/generated/text/text_modifier_group_base.dart delete mode 100644 lib/src/generated/text/text_modifier_range_base.dart delete mode 100644 lib/src/generated/text/text_shape_modifier_base.dart delete mode 100644 lib/src/generated/text/text_style_axis_base.dart delete mode 100644 lib/src/generated/text/text_style_base.dart delete mode 100644 lib/src/generated/text/text_style_feature_base.dart delete mode 100644 lib/src/generated/text/text_value_run_base.dart delete mode 100644 lib/src/generated/text/text_variation_modifier_base.dart delete mode 100644 lib/src/generated/transform_component_base.dart delete mode 100644 lib/src/generated/viewmodel/data_enum_base.dart delete mode 100644 lib/src/generated/viewmodel/data_enum_value_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_component_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_boolean_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_color_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_enum_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_list_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_list_item_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_number_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_string_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_value_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_boolean_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_color_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_enum_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_list_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_number_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_string_base.dart delete mode 100644 lib/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart delete mode 100644 lib/src/generated/world_transform_component_base.dart delete mode 100644 lib/src/layer_component_events.dart delete mode 100644 lib/src/listener_actions.dart delete mode 100644 lib/src/local_file_io.dart delete mode 100644 lib/src/local_file_web.dart create mode 100644 lib/src/models/artboard_selector.dart create mode 100644 lib/src/models/data_bind.dart create mode 100644 lib/src/models/state_machine_selector.dart create mode 100644 lib/src/painters/widget_controller.dart delete mode 100644 lib/src/platform.dart delete mode 100644 lib/src/platform_native.dart delete mode 100644 lib/src/platform_web.dart delete mode 100644 lib/src/rive.dart delete mode 100644 lib/src/rive_core/animation/advanceable_state.dart delete mode 100644 lib/src/rive_core/animation/animation.dart delete mode 100644 lib/src/rive_core/animation/animation_reset_factory.dart delete mode 100644 lib/src/rive_core/animation/animation_state.dart delete mode 100644 lib/src/rive_core/animation/animation_state_instance.dart delete mode 100644 lib/src/rive_core/animation/any_state.dart delete mode 100644 lib/src/rive_core/animation/blend_animation.dart delete mode 100644 lib/src/rive_core/animation/blend_animation_1d.dart delete mode 100644 lib/src/rive_core/animation/blend_animation_direct.dart delete mode 100644 lib/src/rive_core/animation/blend_state.dart delete mode 100644 lib/src/rive_core/animation/blend_state_1d.dart delete mode 100644 lib/src/rive_core/animation/blend_state_1d_instance.dart delete mode 100644 lib/src/rive_core/animation/blend_state_direct.dart delete mode 100644 lib/src/rive_core/animation/blend_state_direct_instance.dart delete mode 100644 lib/src/rive_core/animation/blend_state_instance.dart delete mode 100644 lib/src/rive_core/animation/blend_state_transition.dart delete mode 100644 lib/src/rive_core/animation/cubic_ease_interpolator.dart delete mode 100644 lib/src/rive_core/animation/cubic_interpolator.dart delete mode 100644 lib/src/rive_core/animation/cubic_interpolator_component.dart delete mode 100644 lib/src/rive_core/animation/cubic_value_interpolator.dart delete mode 100644 lib/src/rive_core/animation/elastic_interpolator.dart delete mode 100644 lib/src/rive_core/animation/entry_state.dart delete mode 100644 lib/src/rive_core/animation/exit_state.dart delete mode 100644 lib/src/rive_core/animation/interpolating_keyframe.dart delete mode 100644 lib/src/rive_core/animation/interpolator.dart delete mode 100644 lib/src/rive_core/animation/keyed_object.dart delete mode 100644 lib/src/rive_core/animation/keyed_property.dart delete mode 100644 lib/src/rive_core/animation/keyframe.dart delete mode 100644 lib/src/rive_core/animation/keyframe_bool.dart delete mode 100644 lib/src/rive_core/animation/keyframe_callback.dart delete mode 100644 lib/src/rive_core/animation/keyframe_color.dart delete mode 100644 lib/src/rive_core/animation/keyframe_double.dart delete mode 100644 lib/src/rive_core/animation/keyframe_id.dart delete mode 100644 lib/src/rive_core/animation/keyframe_interpolation.dart delete mode 100644 lib/src/rive_core/animation/keyframe_interpolator.dart delete mode 100644 lib/src/rive_core/animation/keyframe_string.dart delete mode 100644 lib/src/rive_core/animation/keyframe_uint.dart delete mode 100644 lib/src/rive_core/animation/layer_state.dart delete mode 100644 lib/src/rive_core/animation/linear_animation.dart delete mode 100644 lib/src/rive_core/animation/linear_animation_instance.dart delete mode 100644 lib/src/rive_core/animation/listener_action.dart delete mode 100644 lib/src/rive_core/animation/listener_align_target.dart delete mode 100644 lib/src/rive_core/animation/listener_bool_change.dart delete mode 100644 lib/src/rive_core/animation/listener_fire_event.dart delete mode 100644 lib/src/rive_core/animation/listener_input_change.dart delete mode 100644 lib/src/rive_core/animation/listener_number_change.dart delete mode 100644 lib/src/rive_core/animation/listener_trigger_change.dart delete mode 100644 lib/src/rive_core/animation/listener_viewmodel_change.dart delete mode 100644 lib/src/rive_core/animation/loop.dart delete mode 100644 lib/src/rive_core/animation/nested_bool.dart delete mode 100644 lib/src/rive_core/animation/nested_input.dart delete mode 100644 lib/src/rive_core/animation/nested_linear_animation.dart delete mode 100644 lib/src/rive_core/animation/nested_number.dart delete mode 100644 lib/src/rive_core/animation/nested_remap_animation.dart delete mode 100644 lib/src/rive_core/animation/nested_simple_animation.dart delete mode 100644 lib/src/rive_core/animation/nested_state_machine.dart delete mode 100644 lib/src/rive_core/animation/nested_trigger.dart delete mode 100644 lib/src/rive_core/animation/state_instance.dart delete mode 100644 lib/src/rive_core/animation/state_machine.dart delete mode 100644 lib/src/rive_core/animation/state_machine_bool.dart delete mode 100644 lib/src/rive_core/animation/state_machine_component.dart delete mode 100644 lib/src/rive_core/animation/state_machine_fire_event.dart delete mode 100644 lib/src/rive_core/animation/state_machine_input.dart delete mode 100644 lib/src/rive_core/animation/state_machine_layer.dart delete mode 100644 lib/src/rive_core/animation/state_machine_layer_component.dart delete mode 100644 lib/src/rive_core/animation/state_machine_listener.dart delete mode 100644 lib/src/rive_core/animation/state_machine_number.dart delete mode 100644 lib/src/rive_core/animation/state_machine_trigger.dart delete mode 100644 lib/src/rive_core/animation/state_transition.dart delete mode 100644 lib/src/rive_core/animation/transition_artboard_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_bool_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_input_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_number_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_property_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_property_viewmodel_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_trigger_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_value_boolean_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_value_color_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_value_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_value_condition.dart delete mode 100644 lib/src/rive_core/animation/transition_value_enum_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_value_number_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_value_string_comparator.dart delete mode 100644 lib/src/rive_core/animation/transition_viewmodel_condition.dart delete mode 100644 lib/src/rive_core/artboard.dart delete mode 100644 lib/src/rive_core/assets/asset.dart delete mode 100644 lib/src/rive_core/assets/audio_asset.dart delete mode 100644 lib/src/rive_core/assets/drawable_asset.dart delete mode 100644 lib/src/rive_core/assets/export_audio.dart delete mode 100644 lib/src/rive_core/assets/file_asset.dart delete mode 100644 lib/src/rive_core/assets/file_asset_contents.dart delete mode 100644 lib/src/rive_core/assets/folder.dart delete mode 100644 lib/src/rive_core/assets/font_asset.dart delete mode 100644 lib/src/rive_core/assets/image_asset.dart delete mode 100644 lib/src/rive_core/audio_event.dart delete mode 100644 lib/src/rive_core/audio_player.dart delete mode 100644 lib/src/rive_core/backboard.dart delete mode 100644 lib/src/rive_core/bones/bone.dart delete mode 100644 lib/src/rive_core/bones/cubic_weight.dart delete mode 100644 lib/src/rive_core/bones/root_bone.dart delete mode 100644 lib/src/rive_core/bones/skeletal_component.dart delete mode 100644 lib/src/rive_core/bones/skin.dart delete mode 100644 lib/src/rive_core/bones/skinnable.dart delete mode 100644 lib/src/rive_core/bones/tendon.dart delete mode 100644 lib/src/rive_core/bones/weight.dart delete mode 100644 lib/src/rive_core/bones/weighted_vertex.dart delete mode 100644 lib/src/rive_core/bounds_provider.dart delete mode 100644 lib/src/rive_core/component.dart delete mode 100644 lib/src/rive_core/component_dirt.dart delete mode 100644 lib/src/rive_core/component_flags.dart delete mode 100644 lib/src/rive_core/constraints/constraint.dart delete mode 100644 lib/src/rive_core/constraints/distance_constraint.dart delete mode 100644 lib/src/rive_core/constraints/follow_path_constraint.dart delete mode 100644 lib/src/rive_core/constraints/ik_constraint.dart delete mode 100644 lib/src/rive_core/constraints/rotation_constraint.dart delete mode 100644 lib/src/rive_core/constraints/scale_constraint.dart delete mode 100644 lib/src/rive_core/constraints/targeted_constraint.dart delete mode 100644 lib/src/rive_core/constraints/transform_component_constraint.dart delete mode 100644 lib/src/rive_core/constraints/transform_component_constraint_y.dart delete mode 100644 lib/src/rive_core/constraints/transform_constraint.dart delete mode 100644 lib/src/rive_core/constraints/transform_space_constraint.dart delete mode 100644 lib/src/rive_core/constraints/translation_constraint.dart delete mode 100644 lib/src/rive_core/container_component.dart delete mode 100644 lib/src/rive_core/custom_property.dart delete mode 100644 lib/src/rive_core/custom_property_boolean.dart delete mode 100644 lib/src/rive_core/custom_property_number.dart delete mode 100644 lib/src/rive_core/custom_property_string.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property_boolean.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property_color.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property_enum.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property_number.dart delete mode 100644 lib/src/rive_core/data_bind/bindable_property_string.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_boolean.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_color.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_enum.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_list.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_number.dart delete mode 100644 lib/src/rive_core/data_bind/context/context_value_string.dart delete mode 100644 lib/src/rive_core/data_bind/data_bind.dart delete mode 100644 lib/src/rive_core/data_bind/data_bind_context.dart delete mode 100644 lib/src/rive_core/data_bind/data_context.dart delete mode 100644 lib/src/rive_core/data_bind_flags.dart delete mode 100644 lib/src/rive_core/dependency_helper.dart delete mode 100644 lib/src/rive_core/draw_rules.dart delete mode 100644 lib/src/rive_core/draw_target.dart delete mode 100644 lib/src/rive_core/drawable.dart delete mode 100644 lib/src/rive_core/enum_helper.dart delete mode 100644 lib/src/rive_core/event.dart delete mode 100644 lib/src/rive_core/joystick.dart delete mode 100644 lib/src/rive_core/layer_state_flags.dart delete mode 100644 lib/src/rive_core/layout/layout_component_style.dart delete mode 100644 lib/src/rive_core/layout_component.dart delete mode 100644 lib/src/rive_core/nested_animation.dart delete mode 100644 lib/src/rive_core/nested_artboard.dart delete mode 100644 lib/src/rive_core/node.dart delete mode 100644 lib/src/rive_core/notifier.dart delete mode 100644 lib/src/rive_core/open_url_event.dart delete mode 100644 lib/src/rive_core/open_url_target.dart delete mode 100644 lib/src/rive_core/rive_animation_controller.dart delete mode 100644 lib/src/rive_core/rive_core_singleton_test.dart delete mode 100644 lib/src/rive_core/runtime/exceptions/rive_format_error_exception.dart delete mode 100644 lib/src/rive_core/runtime/exceptions/rive_unsupported_version_exception.dart delete mode 100644 lib/src/rive_core/runtime/runtime_header.dart delete mode 100644 lib/src/rive_core/shapes/clipping_shape.dart delete mode 100644 lib/src/rive_core/shapes/contour_mesh_vertex.dart delete mode 100644 lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart delete mode 100644 lib/src/rive_core/shapes/cubic_detached_vertex.dart delete mode 100644 lib/src/rive_core/shapes/cubic_mirrored_vertex.dart delete mode 100644 lib/src/rive_core/shapes/cubic_vertex.dart delete mode 100644 lib/src/rive_core/shapes/ellipse.dart delete mode 100644 lib/src/rive_core/shapes/image.dart delete mode 100644 lib/src/rive_core/shapes/mesh.dart delete mode 100644 lib/src/rive_core/shapes/mesh_vertex.dart delete mode 100644 lib/src/rive_core/shapes/paint/fill.dart delete mode 100644 lib/src/rive_core/shapes/paint/gradient_stop.dart delete mode 100644 lib/src/rive_core/shapes/paint/linear_gradient.dart delete mode 100644 lib/src/rive_core/shapes/paint/radial_gradient.dart delete mode 100644 lib/src/rive_core/shapes/paint/shape_paint.dart delete mode 100644 lib/src/rive_core/shapes/paint/shape_paint_mutator.dart delete mode 100644 lib/src/rive_core/shapes/paint/solid_color.dart delete mode 100644 lib/src/rive_core/shapes/paint/stroke.dart delete mode 100644 lib/src/rive_core/shapes/paint/stroke_effect.dart delete mode 100644 lib/src/rive_core/shapes/paint/trim_path.dart delete mode 100644 lib/src/rive_core/shapes/paint/trim_path_drawing.dart delete mode 100644 lib/src/rive_core/shapes/parametric_path.dart delete mode 100644 lib/src/rive_core/shapes/path.dart delete mode 100644 lib/src/rive_core/shapes/path_composer.dart delete mode 100644 lib/src/rive_core/shapes/path_vertex.dart delete mode 100644 lib/src/rive_core/shapes/points_path.dart delete mode 100644 lib/src/rive_core/shapes/polygon.dart delete mode 100644 lib/src/rive_core/shapes/rectangle.dart delete mode 100644 lib/src/rive_core/shapes/shape.dart delete mode 100644 lib/src/rive_core/shapes/shape_paint_container.dart delete mode 100644 lib/src/rive_core/shapes/star.dart delete mode 100644 lib/src/rive_core/shapes/straight_vertex.dart delete mode 100644 lib/src/rive_core/shapes/triangle.dart delete mode 100644 lib/src/rive_core/shapes/vertex.dart delete mode 100644 lib/src/rive_core/solo.dart delete mode 100644 lib/src/rive_core/state_machine_controller.dart delete mode 100644 lib/src/rive_core/state_transition_flags.dart delete mode 100644 lib/src/rive_core/text/styled_text.dart delete mode 100644 lib/src/rive_core/text/text.dart delete mode 100644 lib/src/rive_core/text/text_modifier.dart delete mode 100644 lib/src/rive_core/text/text_modifier_group.dart delete mode 100644 lib/src/rive_core/text/text_modifier_range.dart delete mode 100644 lib/src/rive_core/text/text_shape_modifier.dart delete mode 100644 lib/src/rive_core/text/text_style.dart delete mode 100644 lib/src/rive_core/text/text_style_axis.dart delete mode 100644 lib/src/rive_core/text/text_style_container.dart delete mode 100644 lib/src/rive_core/text/text_style_feature.dart delete mode 100644 lib/src/rive_core/text/text_value_run.dart delete mode 100644 lib/src/rive_core/text/text_variation_modifier.dart delete mode 100644 lib/src/rive_core/transform_component.dart delete mode 100644 lib/src/rive_core/transform_space.dart delete mode 100644 lib/src/rive_core/viewmodel/data_enum.dart delete mode 100644 lib/src/rive_core/viewmodel/data_enum_value.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_component.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_boolean.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_color.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_enum.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_list.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_list_item.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_number.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_string.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_value.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_boolean.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_color.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_enum.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_list.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_number.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_string.dart delete mode 100644 lib/src/rive_core/viewmodel/viewmodel_property_viewmodel.dart delete mode 100644 lib/src/rive_core/world_transform_component.dart create mode 100644 lib/src/rive_extensions.dart delete mode 100644 lib/src/rive_file.dart delete mode 100644 lib/src/rive_render_box.dart delete mode 100644 lib/src/rive_scene.dart delete mode 100644 lib/src/runtime_artboard.dart delete mode 100644 lib/src/runtime_event.dart delete mode 100644 lib/src/runtime_mounted_artboard.dart delete mode 100644 lib/src/runtime_nested_artboard.dart delete mode 100644 lib/src/state_machine_components.dart delete mode 100644 lib/src/state_transition_conditions.dart delete mode 100644 lib/src/state_transitions.dart delete mode 100644 lib/src/utilities/utilities.dart delete mode 100644 lib/src/viewmodel_list_items.dart delete mode 100644 lib/src/viewmodel_properties.dart delete mode 100644 lib/src/widgets/rive_animation.dart create mode 100644 lib/src/widgets/rive_builder.dart create mode 100644 lib/src/widgets/rive_widget.dart delete mode 100755 shared_lib/build_shared.sh delete mode 100644 test/asset_gc_test.dart delete mode 100644 test/asset_test.dart delete mode 100644 test/assets/batch_rivs/circle-fui.riv delete mode 100644 test/assets/batch_rivs/danger-quarantine.riv delete mode 100644 test/assets/batch_rivs/fire-skull.riv delete mode 100644 test/assets/batch_rivs/joystick-demos-fish.riv delete mode 100644 test/assets/batch_rivs/polito.riv delete mode 100644 test/assets/cdn_image.riv delete mode 100644 test/assets/component_discovery.riv delete mode 100644 test/assets/electrified_button_simple.riv delete mode 100644 test/assets/event_on_listener.riv delete mode 100644 test/assets/events_from_trigger_test.riv delete mode 100644 test/assets/events_on_states.riv delete mode 100644 test/assets/file.png delete mode 100644 test/assets/follow_path_path.riv delete mode 100644 test/assets/follow_path_shapes.riv delete mode 100644 test/assets/follow_path_solos.riv delete mode 100644 test/assets/hit_test_consume.riv delete mode 100644 test/assets/hit_test_pass_through.riv delete mode 100644 test/assets/image_asset_prod.riv delete mode 100644 test/assets/image_asset_uat.riv delete mode 100644 test/assets/joystick_handle_source.riv delete mode 100644 test/assets/off_road_car.riv delete mode 100644 test/assets/rive-flutter-test-asset.riv delete mode 100644 test/assets/runtime_nested_inputs.riv delete mode 100644 test/assets/sample_image.riv delete mode 100644 test/assets/skins_demo.riv delete mode 100644 test/assets/spilled_time.riv delete mode 100644 test/component_find_test.dart delete mode 100644 test/goldens/batch_tests/golden_batch_test.dart delete mode 100644 test/goldens/batch_tests/images/circle-fui.riv-01.png delete mode 100644 test/goldens/batch_tests/images/circle-fui.riv-02.png delete mode 100644 test/goldens/batch_tests/images/circle-fui.riv-03.png delete mode 100644 test/goldens/batch_tests/images/danger-quarantine.riv-01.png delete mode 100644 test/goldens/batch_tests/images/danger-quarantine.riv-02.png delete mode 100644 test/goldens/batch_tests/images/danger-quarantine.riv-03.png delete mode 100644 test/goldens/batch_tests/images/fire-skull.riv-01.png delete mode 100644 test/goldens/batch_tests/images/fire-skull.riv-02.png delete mode 100644 test/goldens/batch_tests/images/fire-skull.riv-03.png delete mode 100644 test/goldens/batch_tests/images/joystick-demos-fish.riv-01.png delete mode 100644 test/goldens/batch_tests/images/joystick-demos-fish.riv-02.png delete mode 100644 test/goldens/batch_tests/images/joystick-demos-fish.riv-03.png delete mode 100644 test/goldens/batch_tests/images/polito.riv-01.png delete mode 100644 test/goldens/batch_tests/images/polito.riv-02.png delete mode 100644 test/goldens/batch_tests/images/polito.riv-03.png delete mode 100644 test/goldens/follow_path/golden_follow_path_solos_test.dart delete mode 100644 test/goldens/follow_path/golden_follow_path_test.dart delete mode 100644 test/goldens/follow_path/images/follow_path_over_time_01.png delete mode 100644 test/goldens/follow_path/images/follow_path_over_time_02.png delete mode 100644 test/goldens/follow_path/images/follow_path_over_time_03.png delete mode 100644 test/goldens/follow_path/images/follow_path_over_time_04.png delete mode 100644 test/goldens/follow_path/images/follow_path_path_01.png delete mode 100644 test/goldens/follow_path/images/follow_path_path_02.png delete mode 100644 test/goldens/follow_path/images/follow_path_path_03.png delete mode 100644 test/goldens/follow_path/images/follow_path_solos_01.png delete mode 100644 test/goldens/follow_path/images/follow_path_solos_02.png delete mode 100644 test/goldens/follow_path/images/follow_path_solos_03.png delete mode 100644 test/goldens/follow_path/images/follow_path_solos_04.png delete mode 100644 test/goldens/golden_comparator.dart delete mode 100644 test/goldens/joysticks/golden_joysticks_test.dart delete mode 100644 test/goldens/joysticks/images/joystick_handle_source_01.png delete mode 100644 test/goldens/joysticks/images/joystick_handle_source_02.png delete mode 100644 test/goldens/joysticks/images/joystick_handle_source_03.png delete mode 100644 test/goldens/joysticks/images/joystick_handle_source_04.png delete mode 100644 test/goldens/simple_animations/golden_simple_animations_test.dart delete mode 100644 test/goldens/simple_animations/images/mixed_animations_01.png delete mode 100644 test/goldens/simple_animations/images/mixed_animations_02.png delete mode 100644 test/goldens/simple_animations/images/play_first_animation_found.png delete mode 100644 test/goldens/simple_animations/images/play_provided_animation_controller_01.png delete mode 100644 test/goldens/simple_animations/images/play_provided_animation_controller_02.png delete mode 100644 test/goldens/skins_opacity/golden_skins_opacity_test.dart delete mode 100644 test/goldens/skins_opacity/images/skins_opacity_01.png delete mode 100644 test/goldens/skins_opacity/images/skins_opacity_02.png delete mode 100644 test/goldens/skins_opacity/images/skins_opacity_03.png delete mode 100644 test/goldens/skins_opacity/images/skins_opacity_04.png delete mode 100644 test/goldens/skins_opacity/images/skins_opacity_05.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_00.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_01.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_02.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_03.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_04.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_05.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_exact_00.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_exact_01.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_exact_02.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_overshoot_00.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_overshoot_01.png delete mode 100644 test/goldens/spilled_time/images/spilled_time_overshoot_02.png delete mode 100644 test/goldens/spilled_time/spilled_time_test.dart delete mode 100644 test/goldens/text/golden_text_test.dart delete mode 100644 test/goldens/text/images/text_bones_constraint_01.png delete mode 100644 test/goldens/text/images/text_bones_constraint_02.png delete mode 100644 test/goldens/text/images/text_bones_constraint_03.png delete mode 100644 test/goldens/text/images/text_bones_constraint_04.png delete mode 100644 test/goldens/ticker_mode/golden_ticker_mode_test.dart delete mode 100644 test/goldens/ticker_mode/images/ticker_mode_false.png delete mode 100644 test/goldens/ticker_mode/images/ticker_mode_true_1.png delete mode 100644 test/goldens/ticker_mode/images/ticker_mode_true_2.png delete mode 100644 test/goldens/ticker_mode/images/ticker_mode_true_paused_state.png delete mode 100644 test/hit_test.dart delete mode 100644 test/linear_animation_instance_test.dart delete mode 100644 test/mocks/fakes.dart delete mode 100644 test/mocks/mocks.dart delete mode 100644 test/nested_input_test.dart delete mode 100644 test/rive_animation_test.dart delete mode 100644 test/rive_file_test.dart delete mode 100644 test/rive_network_test.dart delete mode 100644 test/simple_animation_test.dart delete mode 100644 test/src/network.dart delete mode 100644 test/src/utils.dart diff --git a/.rive_head b/.rive_head index 3544aa6..a7b6fa0 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f99c5665ceb9de1780e91483c082b190d49839f6 +b21adb45646d34fd7ea1850e5802ce63afc937aa diff --git a/CHANGELOG.md b/CHANGELOG.md index e11f616..f0f9628 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,45 @@ +## 0.14.0-dev.1 + +This is a significant update for Rive Flutter. We've completely removed all of the Dart code that was used for the Rive runtime and replaced it with our underlying [C++ Runtime](https://github.com/rive-app/rive-runtime). + +This has resulted in significant changes to the underlying API. + +Please see the [migration guide](https://rive.app/docs/runtimes/flutter/migration-guide), [Rive Flutter documentation](https://rive.app/docs/runtimes/flutter/flutter), and the updated example app for more information. + +### What's New in 0.14.0 + +This release of Rive Flutter adds: + +- The [Rive Renderer](https://rive.app/renderer) +- Support for [Data Binding](https://rive.app/docs/editor/data-binding/overview) +- Support for [Layouts](https://rive.app/docs/editor/layouts/layouts-overview) +- Support for [Scrolling](https://rive.app/docs/editor/layouts/scrolling) +- Support for N-[Slicing](https://rive.app/docs/editor/layouts/n-slicing) +- Support for [Vector Feathering](https://rive.app/blog/introducing-vector-feathering) +- All other features added to Rive that did not make it to the previous versions of Rive Flutter +- Includes the latest fixes and improvements for the Rive C++ runtime +- Adds prebuilt libraries, with the ability to build manually. See the [rive_native](https://pub.dev/packages/rive_native) package for more information +- Removes the `rive_common` package and replaces it with `rive_native` + +Now that Rive Flutter makes use of the core Rive C++ runtime, you can expect new Rive features to be supported sooner for Rive Flutter. + +**Note:** All your Rive graphics will still look and function the same as they did before. + +## Requirements + +### Dart and Flutter Versions + +This release bumps to these versions: + +```yaml +sdk: ">=3.5.0 <4.0.0" +flutter: ">=3.3.0" +``` + ## 0.13.20 - Fix: Windows/Linux building. Undefined symbol `hb_style_get_value`, see issue [437](https://github.com/rive-app/rive-flutter/issues/437) - + ## 0.13.19 - Adds the `isTouchScrollEnabled` property to `RiveAnimation` and `Rive` widgets. When `true` allows scrolling behavior to occur on Rive widgets when a touch/drag action is performed on touch-enabled devices. Defauls to `false`, which means Rive will "absorb" the pointer down event and a scroll cannot be triggered if the touch occured within a Rive Listener area. Setting to `true` will impact Rive's capability to handle multiple gestures simultaneously. diff --git a/README.md b/README.md index 6b02b3f..64c286d 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ![Rive hero image](https://cdn.rive.app/rive_logo_dark_bg.png) -Rive Flutter is a runtime library for [Rive](https://rive.app), a real-time interactive design and animation tool. +Rive Flutter is a runtime library for [Rive](https://rive.app), a real-time interactive design tool. -This library allows you to fully control Rive files with a high-level API for simple interactions and animations, as well as a low-level API for creating custom render loops for multiple artboards, animations, and state machines in a single canvas. +This library allows you to fully control Rive files in your Flutter apps and games. ## Table of contents @@ -21,50 +21,60 @@ This library allows you to fully control Rive files with a high-level API for si - [Note on the Impeller renderer](#note-on-the-impeller-renderer) - [Supported platforms](#supported-platforms) - [Awesome Rive](#awesome-rive) + - [Troubleshooting](#troubleshooting) + - [Building `rive_native`](#building-rive_native) + - [Testing](#testing) - [Contributing](#contributing) - [Issues](#issues) ## Overview of Rive -[Rive](https://rive.app) is a powerful tool that helps teams create and run interactive animations for apps, games, and websites. Designers and developers can use the collaborative editor to create motion graphics that respond to different states and user inputs, and then use the lightweight open-source runtime libraries, like Rive Flutter, to load their animations into their projects. +[Rive](https://rive.app) combines an interactive design tool, a new stateful graphics format, a lightweight multi-platform runtime, and a blazing-fast vector renderer. This end-to-end pipeline guarantees that what you build in the Rive Editor is exactly what ships in your apps, games, and websites. For more information, check out the following resources: - -:house_with_garden: [Homepage](https://rive.app/) - -:blue_book: [General help docs](https://rive.app/community/doc/introduction/docvphVOrBbl) - -🛠 [Rive Forums](https://rive.app/community/forums/home) +- [Homepage](https://rive.app/) +- [General Docs](https://rive.app/docs/) +- [Flutter Docs](https://rive.app/docs/runtimes/flutter/flutter) +- [Rive Community / Support](https://community.rive.app/c/support/) ## Getting started To get started with Rive Flutter, check out the following resources: -- [Getting Started with Rive in Flutter](https://rive.app/community/doc/flutter/docqzmYRZmvF) +- [Getting Started with Rive in Flutter](https://rive.app/docs/runtimes/flutter/flutter) For more information, see the Runtime sections of the Rive help documentation: -- [Animation Playback](https://rive.app/community/doc/animation-playback/docDKKxsr7ko) -- [Layout](https://rive.app/community/doc/layout/docBl81zd1GB) -- [State Machines](https://rive.app/community/doc/state-machines/docxeznG7iiK) -- [Rive Text](https://rive.app/community/doc/text/docn2E6y1lXo) -- [Rive Events](https://rive.app/community/doc/rive-events/docbOnaeffgr) -- [Loading Assets](https://rive.app/community/doc/loading-assets/doct4wVHGPgC) - -More advanced usage: - -- [Caching a RiveFile](https://rive.app/community/doc/caching-a-rive-file/docrLMDw15AJ) -- [Alternative Widget Setup](https://rive.app/community/doc/alternative-widget-setup/docNlDD0H0rp) -- [Custom Rive RenderObject](https://rive.app/community/doc/custom-rive-renderobject/docnbX5AnjkW) -- [Custom Painter](https://rive.app/community/doc/custom-rive-renderobject/docnbX5AnjkW) +- [Artboards](https://rive.app/docs/runtimes/artboards) +- [Layout](https://rive.app/docs/runtimes/layout) +- [State Machine Playback](https://rive.app/docs/runtimes/state-machines) +- [Data Binding](https://rive.app/docs/runtimes/data-binding) +- [Loading Assets](https://rive.app/docs/runtimes/loading-assets) +- [Caching a Rive file](https://rive.app/docs/runtimes/caching-a-rive-file) ## Choosing a Renderer -For more information see: https://rive.app/community/doc/overview/docD20dU9Rod +In Rive Flutter you have the option to choose either the Rive renderer, or the renderer that is used in Flutter (Skia or Impeller). + +You choose a desired renderer when creating a Rive `File` object. All graphics that are then created from this `File` instance will use the selected renderer. + +```dart +final riveFile = (await File.asset( + 'assets/rewards.riv', + // Choose which renderer to use + riveFactory: Factory.rive, +))!; +``` + +Options: +- `Factory.rive` for the Rive renderer +- `Factoy.flutter` for the Flutter renderer + +For more information and additional consideration, see [Specifying a Renderer](https://rive.app/docs/runtimes/flutter/flutter#specifying-a-renderer). ### Note on the Impeller renderer -Starting in Flutter v3.10, [Impeller](https://docs.flutter.dev/perf/impeller) has replaced [Skia](https://skia.org/) to become the default renderer for apps on the iOS platform and may continue to be the default on future platforms over time. As such, there is a possibility of rendering and [performance discrepancies](https://github.com/flutter/flutter/issues/134432) when using the Rive Flutter runtime with platforms that use the Impeller renderer that may not have surfaced before. If you encounter any visual or performance errors at runtime compared to expected behavior in the Rive editor, we recommend trying the following steps to triage: +Starting in Flutter v3.10, [Impeller](https://docs.flutter.dev/perf/impeller) has replaced [Skia](https://skia.org/) to become the default renderer for apps on the iOS platform and may continue to be the default on future platforms over time. As such, there is a possibility of rendering and performance discrepencies when using the Rive Flutter runtime with platforms that use the Impeller renderer that may not have surfaced before. If you encounter any visual or performance errors at runtime compared to expected behavior in the Rive editor, we recommend trying the following steps to triage: 1. Try running the Flutter app with the `--no-enable-impeller` flag to use the Skia renderer. If the visual discrepancy does not show when using Skia, it may be a rendering bug on Impeller. However, before raising a bug with the Flutter team, try the second point below👇 ```bash @@ -75,16 +85,58 @@ flutter run --no-enable-impeller ## Supported platforms +| Platform | Flutter Renderer | Rive Renderer | +|----------|------------------|---------------| +| iOS | ✅ | ✅ | +| Android | ✅ | ✅ | +| macOS | ✅ | ✅ | +| Windows | ✅ | ✅ | +| Linux | ❌ | ❌ | +| Web | ✅ | ✅ | + Be sure to read the [platform specific considerations](platform_considerations.md) for the Rive Flutter package. ## Awesome Rive For even more examples and resources on using Rive at runtime or in other tools, checkout the [awesome-rive](https://github.com/rive-app/awesome-rive) repo. +## Troubleshooting + +The required native libraries should be automatically downloaded during the build step (`flutter run` or `flutter build`). If you encounter issues, try the following: + +1. Run `flutter clean` +2. Run `flutter pub get` +3. Run `flutter run` + +Alternatively, you can manually run the `rive_native` setup script. In the root of your Flutter app, execute: + +```bash +dart run rive_native:setup --verbose --clean --platform macos +``` + +This will clean the `rive_native` setup and download the platform-specific libraries specified with the `--platform` flag. Refer to the **Platform Support** section above for details. + +## Building `rive_native` + +By default, prebuilt native libraries are downloaded and used. If you prefer to build the libraries yourself, use the `--build` flag with the setup script: + +```bash +flutter clean # Important +dart run rive_native:setup --verbose --clean --build --platform macos +``` + +> **Note**: Building the libraries requires specific tooling on your machine. Additional documentation will be provided soon. + +## Testing + +Shared libraries are included in the download/build process. If you encounter issues using `rive_native` in your tests, please reach out to us for assistance. + + ## Contributing We love contributions and all are welcome! 💙 ## Issues -Have an issue with using the runtime, or want to suggest a feature/API to help make your development life better? Log an issue in our [issues](https://github.com/rive-app/flutter/issues) tab! You can also browse older issues and discussion threads there to see solutions that may have worked for common problems. +- Reach out to us on our [Community](https://community.rive.app/feed) +- File an issue on the [Rive Flutter repository](https://github.com/rive-app/rive-flutter/issues) diff --git a/analysis_options.yaml b/analysis_options.yaml index 63fe01d..a5744c1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,117 +1,4 @@ -analyzer: - errors: - unused_import: error - exclude: - - ios - - macos +include: package:flutter_lints/flutter.yaml -linter: - rules: - - always_put_required_named_parameters_first - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - - avoid_catches_without_on_clauses - - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - - avoid_empty_else - - avoid_field_initializers_in_const_classes - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_null_checks_in_equality_operators - - avoid_relative_lib_imports - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_types_as_parameter_names - - avoid_unused_constructor_parameters - - avoid_void_async - - await_only_futures - - camel_case_types - - cancel_subscriptions - - close_sinks - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - directives_ordering - - empty_catches - - empty_constructor_bodies - - empty_statements - - file_names - - hash_and_equals - - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - - collection_methods_unrelated_type - - join_return_with_assignment - - library_names - - library_prefixes - - lines_longer_than_80_chars - # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 - - no_adjacent_strings_in_list - - no_duplicate_case_values - - non_constant_identifier_names - - null_closures - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - - prefer_final_fields - - prefer_final_in_for_each - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_initializing_formals - - prefer_is_empty - - prefer_is_not_empty - - prefer_iterable_whereType - # - prefer_mixin - - prefer_null_aware_operators - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - recursive_getters - - slash_for_doc_comments - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - type_annotate_public_apis - - type_init_formals - - unawaited_futures - - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_const - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_in_if_null_operators - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_statements - - unnecessary_this - - unrelated_type_equality_checks - - use_full_hex_values_for_flutter_colors - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/example/assets/button.riv b/example/assets/button.riv new file mode 100644 index 0000000000000000000000000000000000000000..b57701779bc27ce564f58b710decf80aeceedcbc GIT binary patch literal 806209 zcmeF44SW^Vng7qsoVj-b5hDp0A;f?I6XYd8!~hY)i<(+WQ;jxjsUnRwRkT@6HMNx9 zYP6A3%eqJr5hG$7DcWdLMT?qZq)~xV8Z}j2ljG%zw-y{PrB7=*RR|6*?-hZ{zl@;z-8ewE->KlMD;!EMa%uvH5Hd%yWM*J z{!Ddcv$gupNeq~R&{`GDz2H;lA}B1@JpA|0oqP5<)jxjx71)cF8hYWmMW4Ok{GCrd zj?^|O>-F=`z2L&xcV9RoMOp76_=V>cUNr0cyMO<=xyn8d@kh=2>;)4ikA3{%Mao{h z0s$6YP&}*nf2Mc*7wiXM-}a@eFDpO&>m8$&ef4IgE?;)V^_N{cCidHGW&dU_@=W^j zW!IG>T#~Yzk-zf3y!h)^eEzs+E`WW3vPWG0WrY9koV(^L{hy60bXP{%<(HL?fA+F- z)WBtJ2tTz94(acn)Sw1_Hx2g8va2g9t>4T~fxSSfQ+F=@>X$A{xHRW9HSniNus2_Q zS!MZvgjPL|N8}RyDZH`T=;CRRgZKUIJgS z4ubDmhrlj-ma^4J=X&r)=R4qS&d<@_P_yp05}MBwe%334vy5Lz)YP9W@*$y&(U+hv-LS(p+J6`5U2c!hCb63cNq`BV~mX!bmeb zIy@Sj8~!4=FuV|qgsZ^nFmxciEW8X{9$o?dd-&hMJHvN^cZDH`@Y?WNaASBQxG4<% z3I8Pg2v{Gk2cHZ-1vZ2mz{c6f#p-bVH!!Ij4+!}6$OMAE-d^`L$-1mne zpYVT$yWr9t?pBuPdaiQ3L@yEMK^~;!4e^G6CweD>sa`64hk3(c9_gV*UZ#hZ^~QRq zffKwOFxSfkr+L%BIo{dexgPY^o9E2~i@YMFu)zBwc&T?OTo!tl!Teg}79^~oW=s}*|H@t7a9PuJB-|XEC^BvxOFhAfyw%(7uP2gkRF(&^ie#6IOzEC)^D_neY^RpGnvX^Nxg_F#jgu74X%Bz2NT?kaEIX32%Y_kpKxN zypw>wjE_<+Dpx5h71tPC3vpeE>pEOZ6b1)evvC#Sx&+r^T>pmaKb3MY`Zz;zW#O8R z>od6i71x~@wjaUuA4<7!bH9NLZtioqUQ-G>tHL93&BWjda{|&s=~Y4-Ml%oBC|vot zBDmJzdJ@+@r3Mx#bv*JrJ_px@xK?2ho`&o5xRBQgC*s0Pal%z7w%ec@Q1;-jKotZ= z{x`n8sSu(7aT>%wgbT8%Y3ax+C{dGXvm(_iR@c;R-qO(c;`Uw5Eqhwq{@C7e;9zIh zdr|Fr0~3={hNKQp83AYIn8lD%)MrvZAG`UoL$x10o zEzVe-)tHr)pITI;MxZ$Oba!+gh^bgcEH73ND~c7z7Q`0D7RSnCl`5iEs2WuVu{5b& zs#P68@FXkM%CQQpg;phI6iGqmk!}b~>LZualGTyo+bpF!QWn;z1cnohd%0GBxw5+L6xGNGA+gk!VuHwj*gR5f;}* z!7No}Dpeb; zQga!Gs$msZdsgw<#g^KTrJ}V_T$!r7KEo<*NK>^93#{VCL{;0EW+`07jX5gXmJPRR?$RHb$8pUTicd;PZU^mjxvcATVo=?xGL0DTqS)Ko2@ohD>Qbsg3_;0n`28> zDD=Lys=-3%u2HocR1H*2)mmzkpiV8f)Miy>q0={6B~5CRRnm;uwH-)6b*Kp1C$`X< zw=lNEQVU~6Rz{i1LS9;O!+*!pRr8=A^^23N5h^md9b8X8OD6blBUSiZL@e&ajCe@wTW?L5}wsouSv=-YcNozq;nHe2c zN#?kybx{^%E)tYhlKzT<)>TE-c0p4|q(x2XRb@2G@*;$&Er+Q-OHk;k=;kb}MmLut zuPp^yZEPsfv5f60AxmvX9izMQ5Mx&%y2P$|kjkzyPt`WVs++~yl4!@4wB&_UbIZI$ z^v-#nH4Y}Vv1Or-jcO^=u_b#lLRR9QtSC%5$g;H)6=*F-+_o$`Hma=z>9uFrD%z2Y zj5I|+LecB(YL!W`lKMPR}5dT63HjFg;Zx^;ZRkZ)C|cdd5~ig zM2KFAASrDy6{MnCiyOKXCUfN)EritcP3KjW>Z-yTePGj;wQUDB=@n63zaV1k&6Sas zg3Xo7JL|VpRO`-$CCd{JVAjjempQ4Wv7jTr0n=aphQ`vA{I!i0YZE)Sq0{N@3zsK$ zY%g7%*s&|6dO+8%!j*~kuEMo#?alLQbZ2u>byrt&8_Td zYG83k*2+B@5j(nf`rc97TIX(x?rEJ{?`>}_+^n~^!$AR zx8FmVJ3894mUoPcL~R*Jx;t`K95~RCpOVtpvAAy6t^;XRUgv>AWO-=cS2lFtDnp$I(B2X zJqW`?cL+m*m~4$EvZEoWt%DDThwgUEvsA3m%CIy>iA=T8u8d(qfpUv_GYn?59BV;U zG`7G>iAYh5k4%}E>r_gm0;v`Q9MU??CNL^#->8kgv#MqK8o@%x9o+$l#save9 zVx{hkm6uj~ov{kc3Fs1uRZ*>uLkUGt(t#l+wY>_>rW%*809#k0^;G@Z4XLfFrba^7 z)oki&RjW6wg>UU9q@t?oBV8J66{wM_+PpgHfNE)t=w`LD4Jx7TW9t5(hXzZnnwQv# zaW>!cVx=o{+SAmYmAMBnU9YahchXI3E_tup+OT$QX=yBJZDnb-^}}`B7v-u=8_u)e zP+hf~y`)%1ZAMhb$~Nit4Ar{HJCJF4n>>7zZQ7KQn-|O2lnURun^N=ht$B5s9$K@m zFzTUvmGdw>Z(d-d(YJI)(J{AFVwg+Zvcv-$iW57m)P@q!YgnkeVxlb(l32Q_;!u~B)>Pqj zS_{OiTAM06Fllf1y1T97?TOLu*pTfh?^+n@a!?+#0HZ`ZAJ-VCI?5LI6T!h-G=F;YZ z*wU9Twzc|cOX7e1MQv(HL0*|H;}SbCe$K@-kk(R^*b%E}DbCu2A+%IS|I*cRZPx9v z!aa3)d20Kf1{;&=9+70`o_UDXwx_rw17m72v|-bpg~)Mx>t>Wwx8`(pSqsS2*13>R zM(f;^Rx7i$FsW5-YCX?>4~wI69gQvBcaF3|Tbf3#+r~i?OWSfGnLTZJSnQ;d1mri^bfX*fAkxH{5fOW^qRjbh@=8FD(W0 zXNlg={-WnD?4 zrClkarCll7vr@V;ybdhnDx=-j58vAvnyfma2Rc)&l;{CSBPAL-&=Fe_^&q8`XpYn( zD!Sp>Np_cdS?^5TZ4J^I?Q82oNJHy#)TJ(z($#5sLbWH9i~haXiz3ZpuTbk)kvDGu zYUCB67R$Yov=m`F>XjJnO0=>Pqi88LC^}|;EH$Y}C&e;TiaP3IOVVcRE^AoE)DX&( z+uogKouAibM`L9dwYGHlqmoSgvY=lbD{IVG^|5*QMkAwAuTiJ_hpKMn;I>$%wPd;1 z6wut4`qH8UWE!=b+x?T z)^Z^kn^U(W9>DOcw@50nB~8exT5XVjRcdWZSE7=R($%KARJ0|Eff#BHt!q*>t)7R( z$`0-6P%E%f&}QH^^N$%=m&Ym^*XFBbvFkh5rl=DjsNQ0#fDkKEz3xi2T6Ly)-5XK* zltFE=L~A9!6r|$+YEg?=mbJu6#PF15RjFu~7aNC-$W7=#Io3kts$&IK0kV(se+mB2 zwen(W$&%Ot^*vrL3iYBT9L>SeViHnz4z zy{aCLjoEk+rm3!2$<~=@cnN1F3`~kKr6MZQTxhFUe)k(KDfo{MI)Ah~8XKF|#OCT% zUzu91^J68ki)B4-Vq-myUB6(8#frbq#x@38DizD;Ow3PEHq_%lEQ0?~L{%;(n3t&H zSXC?v(^4$8$I-1y?ZWb3a$l{MApI@sida3;iZGQHgh6=3*rRf~qiTuT80&x)-+p2p zu|p~Y|B;TQiN$~k*%7OPO9MhFn&^s!0n4RqQx@1T;b7w%t|p%3C#hhA1`EJaWzRil zUa=aq__B&?u+uyY?n9L`XI62B8v2>f&I8Z?>}Nn^5`&2S^~RUVv7erD)#cY-qlR65 z*|k?m0hy*y(v}8ukhN{4`F0Qg2SA)j2y3e`xDpU8Aw3A=5!`X;U!klLAQfts!^ z#s2@r*#A#f56b?(HAwdVt%&UZTen--|F>4j{=fBt?EhPD%KpFgmhAuAQ)K_&o`(JZ zFWPhMOYxa!Uxv?Ta28N)&$pM^ci9zkB4Ag^iGY2JjS~TTgPaK1Kavvx`$0Jouz!pb zfjs*$XNEJ|86xKb&Imada7M|wfKw>v0?w!9T)_DkITvtlm2&~7TFwQWb#gA?JRs)+ z&JX28!1zbI2U+HU!q&|tNK#?JA4+&xq$u>&IR7orMg2O(3i`(fWA`B1@tv? zBA~w-x;%8bzBcsb(3kafvcs<{WQSjWO?LJ5^|F(%Z;+jQy+ro#^(yS%-=yopRpBcA zQ`y7U^|FVre`1%*&y6_|VS=qza&&eLX z-UeN7)Gvg$g}3V$W%pk1mR)-N8`+=NFJte0n0`g}-gS%Yz3W%8_dZs?CVTICkLvjjqUbmYld)+u) z83bLQj(#y0S23B3}SMU=|l2zTc%l{iit z029VGI6Bcf-=3|O(cT;?r+>Ek3hj>}tb|Wj`C|V|7X~V^4_70M-H)GW(u@0Nt8a^c zv^ms<@JVW-N`l>0GsKmLdXfqv8#~G;b|>1I(8%E|~>O^zrx zDQ|9Gu~L1RzDQisuRYwof5=ZL%#%lb_`FV@ zeDZ9iPCozSMc}n3ql72laq@cb(UZ4=yHDN+zLQ}i<-r-Fz{wf2d*#A9W-JO^&baZ6 zWia27u^w$<%#UVlh56z$uKaM!cqa%y(w4Y}8M`y~1?JxFea#ZrxQyC6YQIt+oFfO1 z92JBgIeBDZVD6p5$V*0EgY=h8RVmb)y~zpB}Xn zA=izBdF0b0VK%9a+&gmrhe^T2nx$r8A$fF;!s2t5I%QB0=9KhPCIsfA$2xMF6FcWj z4&t6N^OX5<^ChQTqtq!&Pq`gjcgn-y)2HkN_nxvJ?9LpdRAzeS1aM~N{2-ReJ@b;x zYv8^#^Y$M1%ymkQnJ^~(Sj>D_d^4Z!36r_A$9(L#hx=yk&D@VNbdMgS)adll6Tq3H z=YyAwz6M-6`gU;L=!e0lNAK*L%jmtM_rtw=%%EQGGiAgWGymv3OXuY()t6^sF6`?f zVG3#r>V#u1=`kCZBXi6(W0v*}IV)pU4rH4#=60bmAB!_nPEA*8X3Cg#VzJbQ)i3$)Vv;-!^8KE z`;Rr7QkfE(Qk{zN(3AnSxHfLCK6SNHr`Ddj8EiVW1#CaHOQ|d`D;3Pj$^#3tO2D$L z${9_#tNXf)T|Kroa2dOKY!k}UGPWJ;I?Yq+wA9nG0$-EMX?dp=!oB3QvcUbc>eE)k zrTR4F6*n7~W3m0T7KCpOnLJ$eUDv|rlZ6~j!KP7?L{vzk1HEj0>83x zS)?(4w9GqZ%7w@DJz7aB5vzLK>h~jNKdcpx#BsGB%za$fc*v>`H;-$AOUtoTv}ygtope6H_K;DrLe?%$+zlZZ4i!8aG!=M9OnUO+;K1^4K)1@rhLvS1RS3 zxjvt`VIpKTu~AZ+*eR*?@ik%k(X7VjTs!9`L0$fqGK+jBd6QBhpO&2Vz&y#z>FP0y@1(3rd0^qBOTfL8)*Z%cCZS(U zG7NlCiz9>#d=F0{aNmzu4^MiUamBoMlHtx?=HBkdFi##dIbEr~oYZ}|OaCy(beS-D zCQ?{B`I^HxfAS@Vx%3ZnB$wNjnxdzq2q$kK>%rnFrAV!Dax-1p$WEaN`44CDluVW? zmqgi6!ntvC)s&Sm2ds#jo2N+0o2P6bjoGlCE{*-%;XC{M*^7EOr86++uFT!26j%)E z+!UHKN#ow1x&3_S_H*e;)1+UTTOo7YS!0E{Re{;h{e|3D;o6r^_H#Kb3~GQonay{u z)7LQFx5@W}rw=2U-|5q7K99VZypp_;Tt*HcKWwZu5(~L)AnVCSp_C2lXuA7EtTZ(u|Ynn;ao}IOmS3 z=w%4oDU=+~nts-KVm^ywKtWEhyMq6jxTc>0U$di*6>I#A!|b1!UH9InBnbPYq;^Il ziBiGL9M52mc^YF~N*+=+yOI8>mf4Z3%3BHFjd@IAI?9vxLf)%55PV@enD=(xdrD0k zFl`t(cG`5MW?VGm3Q2z&N;vJ}X{hP68>cOU`?fPDfG^K@13Z+^5p3EToW708&qtVz z)1HKRaX!YGX)jEB6?}Wzd&p(L^kLxG>C-V1rArFa&zpWR%$J;r*?jtyXU+$2oR0MI ze+{mU)1L%cw&`zAe-C*Ln2`bI%qRf;vdy?2=38g10)IFI(mPVw@`nax%b%COAShe@ z9r^2Fel))cY{|#!E5GZ^K|$HhoGIloWiz8FY>*zf0lLDoBr{5zRx>W}ZDbfjwvLR$ zv&0d9G6EOW(9}6oV`NSd^UTbdxnS=dv)=nTr86rSs)}4mZXoN0{tVJ6X3-y$j@dhc zty45XcBk=wEJAbqkL%>cbVtkb|BVPk`5RsJxe=~Up7jFA@0dY9Dqx&~B>C67?}&!O zr2yf2eG4d9SWqrZ|J8lo6qd%ph&b-ehynZExhCCBuRo9g@H?tHQ9B0v3Xl}rC1y@_fd?TPX5 zA+b9VKm2f&Li@tF{baH0B4x@mQEA#s{rD3VZ}k1M)tR)f_5HJyroGPh zA8*PNYVrNERhsyRI^yv^O?$cTKVF4tuZsJRr5(MT@|tMm6Dp6VPkDrv`~F!*-l3Yf zKg;Xl)-Ye*l)qaLPk)}IulM-=!<0k&0pCB<*qws7yvB&X(<8qO+UNQ42L|%>;}2Kq z^p_jVq`glw?eA2^^XDB6^28zi2dW_w-j!RwBz&?uOYEBZFsu-FTx8Rp6_5WV+6&|Q zFs@hlRNNlt(LPrN^-rL^C_$?M!zSQaIb%A+8qV;|^xvwo)g-Zpg0iHmskE~!C#{En6~kkMW8Kr$F#0RT zzX|>m>0j#mXPL6P<@8^q#v5IA>wW(rMpxVh`p-sPQzd@*fbXBJ{*Cr1{YN4Fn`y6( z`&ZJwlKwXQFQL7{_a9<(BODR`)O|>wx)$Ex`=|5n7AIUs|E-8GQglMiasN@Yx6*$- z{AU?^+@E*1psz^!H^HCs(59{A&OoMTS}AoAbR}2fTg7o*xP$hUar+dp+vR@xr<(HH z<-Y%D)9O~6?>{QA`?@yK=#m}v{ZmYP+tIi#vTxY!zJIzYpWW{Jk1%)d#K*R5_00&% z<7UR=FBQAq;>XWc|6=TM|BGp__5HJa-LCch$M{+sj5X|D}#>$}m zvW>pDf&NYj?0)=lMjt}jkAG@lkNb0Mb#r}xytjb)<;L@8ecgh1eBU0A&+_OE@%T(n zZ-~bqB7S#5@o=!Q$Lq`SQwQO*)xGo& z`qOZA%3*dBKk!dB{397{HGav+<&#$^%D9&4F5^S9`}!kJsk9eF{b6ig}(oIGjlj=eW@oa zj$F=?c>K>xd^eECNWZ7=iTiWrjjvLZ%}nU5mGa;kXyh3mxsuhXl3p)=t^#`bbJgb5 z`|*b;&G0My{6?6O#Hopwm#YpZf}8aR4DQ6tXv*Kylg!MO>xUn1dY01}x3fGtC2k)j z`RSBc8`66l>2XyUADM@n_VxW=fd2_5ykEZI>Nu8nv!7n3(MLBmZfAMjlDJ(-csEa0 zZG#&W?$9@OKfO%Tlbt3%e6sO(s(t$~Kfl^|dSS+&r;PmZ77t_h)0^m*r_lG$GX25r z(FgXAP^a%d(X@A{GajGm;q4|t`YeCAI_}SrGt?MQpZzb?==+aXIwJKA;-@Q)q;3#D zTV>IIu`=nWo0->L?8nbG@^^xnE8C1bPFXzsIEn8BBX73)0`0-boNQ(iC&f=M+4MIj z*S8N>n&ET9CjVr!@{@OT`1;KDi-%A4vUF18cZgj&N;XV7(C zT$lW`CGWvegent%+r+|=j_K=mm4qL>2lvc#EV0VtV~>$#s)9eRf&MC_r|zdndir5s zmQ#G)4EjR0(FH5eopfIo^Q1gTZ@B5}*28}K>83o^rno=Hns|IXPbm3W8{*-O?gZ%# z^V>dXt1Mra+Who}nX$1~e3st|;%BR~nf~H<{gV#MkMh**etIMPu_e&;Y;~Q4?=?1Q zV;A`<-123<6*xg(8DYkfc;6UdzJWV=2rJ=-_;YohAAf{Db`^%z;1V@oazaUFBBayn zo51pj*bDtKW~+t9uGHWZJcVK67@au{K2yv$Cu`nc8jxoM^BenzQ|;%O?2jk4@j7$m z>W7y%;*4PWLHH4-j&2##%YnZ~|8em;P^P}WXzqCUTmGmXgvvI16Shb}F1(yWQn8!j zlH{rn&wv^K5oVQT&yDAjCE@x0I}@L!j{9e;RZK64pRKO#6MmqPe6R3#ihr+`GUeea zQQ=VmBQ?7#o;z{1bywkE5_ik+XmuXm++* zE9qIAk+`(w2$cf6<gPIM4Py9Ut{mp;U$HOc zWafhO{P=06lupmwIg#;$@Y$wS;&bo#Abz~n%vv%?FU#-0L3-KhLZ+AGhac|GT}gia z1I>8lB>Ck}Hm#s5gBO5 zka`WqOU94qKf*5$$9klhY{o9Od+ z{`i#b@7S60$TLsJ!QVZsRLLflUb?F#75jiPS};%Z`}TpxACFa=^zqh2i63h4?b$}Ep%ULd-i#3Oy}N9+C?er2eE)Qg5RSXS zw`ZAI$gPXpxdPBRn4lWq<~SRCd1srkN!R%HiT-%KAud0&gW47g`U7`N-95fNTh&C6 zUbxNAX|P|@V1CM0Ul)I;&QE{1skswKF5Mp+gZU!cJdNgTkB2v7trs6POnG|jX_CG* z*AG9;@2|mpkgYi1$NN{d`o4s>d!AV{l4*?hZ?=S!p@NoAmGI8Wc>bopWcc=BM$++7 zEn8JEe3g9naw{?F@Vk~1@ynO&_xA!X1bvmU{c?nN&8VbuH%!0Ul z%_!U8+o!1G#Q%RYY7X|W^^+UOY_jiFakgGCw`X|9I>1p4!7BM7Nx;(jvSZm{{ z+(3KKzowW`D;&sck||aA9KTlREDZm&A3xcQI^oBV_5eFcovbwdpY;7tHtiE$FaEfO zn7J$but?p$CYl@!XX{^A4UI{ z@^Bb<%Ys0~)lC74|Kg|z6#jG;J z!K^;XFaNE+f4XUp@S3=MZe#q5{q`SXMuG5d-+zP}Lw~kE!r<+juv=!V3-@RNbvv#F z1Jy9bq81=lGWWGyUzdWmIQ}qMWSFuhoD(nG^-Se@1z9+^Ll;b0md5=T(0{x5xd ziQPRA_x}|AgZ%6uzj%0lTMh>^NMfJ1C_r2KZSSX-sx;FJRum)5Zk*q?NeXXVh5reD z4+~Pw@OxM=4y2pYmGH`VDeq#cKa_D6vO1pOT{91c*T+MBm!X2XoEX%__s>w;_=_GR zl~g|!t|8(zOf_>_TpRHc78A=)Wr|q?8f``@C(z$gL;8dY2eA-hfSV4vAAgvCU!6WV z$kop!)tAs(74&hAobgg-t6L;JcLiRfA$1wdy1Hh3bh`Zce7I>Xr)Ry!x;R~asww{W ztzdi~VZM7iJ@)aEi__wlYP`RfQ4}xL>Ea*Xh0j(cVmC7v!VEO0lFlYSJYHcU{?7Jz z`S^X+2}b5A{&%C`yVWqir?&a=2P-Y{b>o0q)Vc=W-b{Mce)+Q1XT?9hH<+!8#O~(# z{u534-8?`4iGKZ;`2NYr*B1ol*F{ZuXK^Gkg+yUkdWG{7?;k zF4_J!#jn$7Tt%J>6KA9hqcJXiH*2MM~BO^tVb-RRjzDv(s{V3ZwU#=FJq*g`+m5&pgrcWjVzvgy6?wb}^NTjTMw)n$^tRe-Qk%YjBJ7HbLDZ1oxO*A>41 zNhZDyYCY1|{T^MNF5!FW>Q!QQf-xt{|E{vxZ>3D7>0hEu{*(Oj75V;?O!`)ke~O9U zEB(b1UkAE7&~N27KYp^m77o^~$^P0k&(Ck5uUmocCYy7Y_=)d8Gs4*IzI=z9R!8w@+vxZ-MWinsl#Vn@G{bzu_r_!aDy|2-_|UBgW8#GAZ=7B{H`-@}HRvOBrH zf3{l3R09o5HupFMft^r)v+YNsBVMy*%zO>rQLH zDm51ke9pnN|CLYULGxL3@UYMRs)LILsr^-bKexSbThX9lew-lg2m0T+_*k(9O&_#y zP^5G5x^4YGgK9b#_x=oO>s)+K{XO;XmRxnHxBL5BY0rBu)|S>CeBM9i!Nw7lBQ}iKaB#j{2j}mvdbec6(;0)`Eg3m<)a1-z zqx0V_8PlGn-z~|$U9J!J$!ZHe*|&Gdq=xO-O%$HK!Fh3~GvH#C} z?BJ@i7xxa+x#6~{@;MvztY|xXQ$<_fPf+*8(Z$jISDv%HqAhUg`F~H^J!zj?c+ReK zTZ@`thF*Wl`&7+&kx#D>pLyk8wr-%pc@`b&>h(zw%H{^_oLD;I_UWal38m+K~M3 z{i%Mn$9CIPgu%?fOK3iaZacKBeA(OItNXV@`>XE2n07})r@qsBx8&WDRr<~(89mX5 zs@|!*bMGo>zR0X|@hXk}ve-yf<{-4XUNuB zydMnx0H2)In^$iOT6<0E-Mc=Bd?ozdZ{OYh;XZ3aYhOOt_-<4_Yj>`F8QNTbunzjh z9wfGV>Vi}6cLYxlmJC;yF2C_UiayhF>OKdTUb)uEh&jrTOI%UQP$bKf@3_l+Ct z*0rwdym!pK=Wo1e;$nB4;<>#?S z8Xwu+x%koY9W6Ur4lUo&Qh#NA(-X^|ST6tTSK!n1v#Izzc5wT_?T;11XU!9}yqcbP zd1spWJQdl|^3>)XEn<7RJ8+d0joXfvXU0A=dHaIx3z{@OsV}7NuX-VM`+^rT#7#a} zP0auE+uN_)zH!I0?UlGTZtwWWKW*C|-QISjRCg@v^GT$wY)3i%Z`^@;_0%IU$vhm4 zUuGrLxp?Q;y#v^{vGS5x_s?&0PN~{|$Gasm=gE3d=EZkQq_zhay;~yYgICJ9Bke44 zjgE*7pB(5%qx_e4N1W};GF${l#G z+aI%a8-6cstbPk`ejKm&<1-0wfc#HASs%m)?>EHfbd6W->Zz`Uw?dvFzZ0dWyT`l7 z>lto}J4ENZC%VJ+OgG)l&~w~L?qq$Ao9pK4LU*b=Re#Ez=1$Y+x%qCs{?RQ-Lv&)-E-Y@_2=AAxu4SKyPtOF=?mQX?q~Id?&sVK^yl3L?gD+W zd#QV={(^g@dzD_`UhQ71FLA%-eodFUOWdV+V`apR=rZ?a_h$VSx7xi8Z?F8Wd$(Tf zu5<6#-*g{vAJI3vKXvQ%3inC3LEqtSb+_uf+}GUK^cuI#ZPRzVZ@O>lweFwXKkIwk zcSFN;O=v_YLvIV68ah?K5Xuf^>lZ_(g>v=w(Dcw8{c>ntXr68j6@@;he;+CdmFPc& zz8LzVZVNpadPx5<)DUXaZ-;&x`knrd&^w`n`cUYQi|K~Lo5N4I z3E?f_r`&;fFXoHxap4`|9qtf$Bc?ml!^b^I-iYZAlXqdd!@Y@Kj+-WL!F1E*Etu{| zc?+gH%A4=acTe%Y;C;c(^vb+4ceK10(;Xvk#B{T~YOmVO#xF|!yF1pq)4S6h=V8)t z$9s2q_qh|~jhOBk_;snr-09wv-jnVO`Q<1#KVf3RMEA^u+=N_rCf+EU=bnW(%ASem zH}LCE?i{`m^K7Nv`LPxF{fZhMzW=ydXxvnaxM6<|FL#dMrN8{< z95VjyH)A!3zciM_RA81=cD~9~o>Z|#{d&y&5{ zgikzF^lljy;=TlP-eDg(=NgSCUtei^;3WYsjyX<>bGT*OJ$f739~*>&Y9)O7iREH%MxQx`pOj$?uTWBsE8U zm*)G(_2m8J2J!*&hvbjQTJk}Xy;A*{=1t^77@=@}qWIf4VuO6eBBNKj+ zNLup=@=5aN&Sb_8uC7JJ$XO5fqZ~uPw{6l>YGh{v$xZC2f35{6-hm`sfYG& z=+aD58|{~Aeuexk`6~Guxrcn6+)MtBY$bnB?j!#|wvm4%sns~A5Q$N@?YC+E6WKxj zncPqQhtRo}ypCi^@H?&I&U~G}(A+K5nsmt!nLs9z>@}MG1y7er_@U&93M!}4v!-Y7O`gseKMxkmbatN`W* zW8(4?uCulZ!{J!VbL+9XX?f`;6^_S?yk9((WW6Twt=GxDM%&$6D1ed$H zB6|>ba4Pp67+|W2Cxb&+YC7u@!q(LL$N-hZSqzfJDS)6}g(cn=Q4T=KIM9$XfD2v{7CE zmVzvh4rC#$BcCI;k-rr7DQ}2t{883R)Q*?QSI8Ffx8$p&(WX5#_tPn>mF~YM_mO`f z+sU`c4k3QV4D@yID(YG}`8Be?J|3mr!*!BQ_z_{BI{k0fMru~h`hAT&Qf(y6!}JZb zSn6@K+8nEo)zm!=jjH*@HfWSE(5M>pmOJUPid;=XqpqLouBZ8a@&U4zd=MqtfVJFgKEN?msSJM89-}ZwN1((?ve16me&3PRBK-Cr+QL4Oyj;d`8*PeT zS=k*c3Rl|i(0ownc;f3MkX3ZKC06rry>n}O?~%8Y-zQg) z|3=P!K&7L=Syti-#Ps0+}gw zQTQF92wryFU#I%$&MlPst)g*`X#peYU(w~)56iy(9nG!lX?Hoq#mSl)~~bi@o@gc-UBLKoozT?C#vGV2=71P;K#Vyc#vBl14hY=>p<5uv956oS zI9l2nL_33MXE5H*2#IzE(as>+8ALmSXlD@Z45FPuv@?iy2GPzS+8M(>+S$?4&LG+u zL_0hB$nE@_#*ea{9euPuV5RkG)&8Ra`T)W}HXvjJLN?$>E*mRNWCKDrAY@~u9a%QN z-t$q)hQB&DA)?f|N9_s!KlFikd+w?iU0?jL=sL{Mb(o>+Aaorr&~*^H4no&K=sE~p z2cheWA3k!s?RxT~YPX|lGx}QZbyRE_K!u!e>xx`PV#r$FA`**9sbKM_E?)|?re%KoL=lAh`QG}M5gcHzmB`2W5 zIpkdOZ1NoPT(XcXCNCr}B0o=-kpDtnOn!k}Kz@&Oc7YvlFh4P+(xb@Cfz6?qGJEBPI=n!Jtt zE_olhp1hyjKt4eJko*x@OFl?$BzaGP;ynfUgfC50!*CrRF+pm>LZ;vEW#cPOZ5=-WX4g4{|zOE!|vk-WzOzj`Vuzew&Pe@*Tt zc|QSuE?dI9Lbi}^l5Yud0xCS7Od?Mp2b0NU3OR%vN}fojk|&YF$l+ufIf6_lPbM?S zk>n`y6f%<>O^zW?C9}wEax8foIgT7pP9P_eIpidAGC76JC8v^Ska^@ZaymJK%qPzz zXOd@;*ONDpl_Yi2x{+pTCQd*_l1s^NkrDFS1jvKQdwRoq`8e@nhf zzDDjLUnlpHzav}8-;?{uKag$YA4&EmoV-f<>{B>-74x6S4)V|Be)2zrX2%)luVTKA zWO;D@DlW|3iOMXDQ&@577UC3E=#n8aflMUXb8!kQVc2JJ3M=Ll$&<+8B>N^#Va1ny z&ENYTATBtI6>?<2S*(~FggA>8vV=H`6*DD`gd}6*F}bXR%^lM^Yzo77G`g#e&w!pWG>=Zjk=1cvpt{I?e3ys*2`Y zNZw_kcs{Opmxbb87N6WHq&~S*=%46LA*=s9d6wuuW=P>|@_*yrp$Ky4ohScP_YU#Q z^nLCi3T80KA2S&E$$doreMFI>7=<6jk8^!71e{{i~EO!KPHcU1}-FeFq`Sy|5SVn-Jc@O3HdK*<~h0jEX|z1abK^b(?mW`Mulc2q4H2O)DJZi z-X(iU)*A9|axHlexsJS-tRe3s*OT{?8-(_eWP|kMvJvyqWh1_UY{Yyd*{p#3W-0R# z?ikoY_ov7}HWD(BjhK0#8Dt~oCh~bQD#WT!By^nAMGq#2kfTX+H`_a64sRkKBAbM` z^NjbT+2%fnN15tR$=>%lu83JXiglOlQCVw9-mhh?rTHFm9eFQVL*7TOC+{aW z2=#H~U~&jKS{Qmq7~Vwko}X}&n630r)@Prr&(tqOM-}^sdX{G1m#KJPCY}`$U(Sx$ z#}G5`pjEts_LKFQ_0P3F%fP5`zno)OJY)Nq+}j<&SpCnpKD$*d^H*Yf(6-?Y;8(Ct0zWJ0mx8 zd>)AUsjD*O*|V!M?JXpp`hxjc5>I`>jHkXpJoN?QsV^`pG|&C1@&4-f5{&i=`xZj3 zgw;lx9~Szn;xlN@C(k5rBm1tF%h88x*)E&Nhsd9hb>t&t-}Rrw`Wf9HBOg~Q;1aBj z#rH|N|D5c*HWuHlbT_Nw=j6l>>pyWn%G%gp|8b|xO~p-YvZuBS|0W$#9!T#ndBDZ` zu=03NTFrm@;Kww-pM)g5Sy|SzHhm>j1K(hU++RWxH&`KyFK7R_oWwVflbDaaPVO(K zlYBXGjbKp&EUvgMreyJX9Lqe9W4Pf%C?G5s}Y@808A-;rzAU(r+FuU|?nkKQkh zBt&ESOM?6NelP6R|BgByjs4L5>_?Qo8G-xivy|xlYSyFYM{465q;Rwm$JDI%D08HK z49S^ijQxJhk>#kpc}l!Dqg?Uc4D7^a*j_cmGRb1>?M! zkF>`VfqO8=OPIb=lwA7me@U2Nk4Joi9wg?Y&-94ppQ`nq>HnIZCHeQ2gt&YZ`m_S+ z98I74?{FQdXQ3pA^(?9P(dNmIe*Ts=Fg5rfr8`==QvDwPw~y!MiKIu^*L&+>ut(P; z@j#12g4`GEvm)#ngHXfx7zFeCjzJ=kqmRbo`?rn8l0wjX#C+@-xA(~Wx35o*J#MFc z=vgc1LlM*?Xf3Hzu-Zb~{7u?*j#8H_a|_AyNV8r{>hneo?xCBvrdT66kD5{cacWUB z`4ZiGjnjUwyG?xkx2aS~nDBC;8laY0sWn;F=|X!8`4ssqxsCiK*+f21Mulq7VdX;} z@$$j!&q}6zFR^_6N)|5@!lO)*LPDQZ&6z<^Q<3^n(y;PBxgQSu$kM8nkZg0j z5k!1%CBH*fledw}DE;r!%=;%4@8nST(`5ts0Qp0bqle;JPVwvsbGW3>v!{>sU2*;1 z&U4ruatl!l-XVmYWvLN+)hBnzS-Bz&|Ez8*&1aB#d$yFrpH?mjLd>6TfH2Vkl(#(69Z1x?SeaB|svDtTQ_8psj zr_ao5zQrGHC+bMwbfBL{`1aO!WiRCq_MIfWS@-ncNqK=K=lxax;CtpGDAn(o`#$my zWE=TM@=daxe2aXW{1e$h_Pb{eyB4UgKkr>DVUBv|++XP1E&RLQGbibDH^?0zdG)z- z?o27ITR`%z6aQX1ej9Z8z4c>vM_t}0C$@jniES{`qUG^6OyPR+esTl(0Qp1mMnVHKQYsanfHKNOK4t7ev6Ed-zIM&Zziiq-Yxon=AB&ZJN~{%@QoIA zw?EiBK_ujn?tT*Y;QT_&!M=}}k9Kd*3nIP$m3#Xz=fr1PDZ?LFk~Z>>kk;Eu-M3^I?LMouSZkon}9 z&)tR%lqeuJzc zZy|3bze84&w~^l^?<3cf_mdmQ2go0iKO$?%2g!}(kI7BsL*&EcPslp*5%N*;r(`|( zGx9O=adI>H1obC=mz+wTLFSRu$m!$^GM_w?oJpQV zUQgaYR+7|DtY4&d)KaWp#JrUJ78xPGP2NP_Oj4imM4g1EKI4fxF;k!MM4gzIk*kH+ zDG<&gXOnZtx#Zd8O7c!}75M|wq;MC_Yshuvy<`n}AGw~qpWHw`K(g2L*+Zq)VFe+j z+D`5ucapy%sf~EPO~U+!Y$mCbc)m^CUm<@>zDmAE?jc_%_maOOTgl&(`^Z0#ZR8(G z>NcKllk}W%OztQDLm2;-F6Qg#^1O`6xD!oWSSmc_Cg#78-9mg<7rJDK zOdu0U_9HysCSllv@O+z?Pb5zwhm-6nI-O=}KE9tLB-Rc>_E3Bq7jv+7fEjBCAvBLJ!)AJv`P=4t#7d;hi?iu|zx#GT{9yUDfWJ>)v_Ub2R~kHp(R5gu;? z1vijDZ!iUHvAxn|NQV8$nQ?P5vd&qUhuyDSj&X&1ME~p0JxWP9!u@}Dcl|$P zR|IPsX#NrQLq3)}A?on^>P0(v553V5Wtp{@8gJpZXlE@lYZiOA!tCpOQEKWuK=Y5t zTJllyr(`|(Gx9O=adI>H1oyfqB(#>G3cR=|w6pJM%YuDE+;!i1UR@5y~a6%u(AoNr`hBq3>7 zGkd3j_2M#)bY^E+V&E6F#O3dLKVmu3Kid6ceNQc=B*DEvVt$roJKBz_Iq74o`+I*< z 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

{foXQl(c~^q=inNS$iWFoznO>wtW)g*r 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�rr;z`@aD8bvejX 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 PaK)y!YkRC-o1XfAVZAd= literal 0 HcmV?d00001 diff --git a/example/assets/databinding_images.riv b/example/assets/databinding_images.riv new file mode 100644 index 0000000000000000000000000000000000000000..396d12ef391daed54bdce951936013b101436c69 GIT binary patch literal 11227 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 literal 0 HcmV?d00001 diff --git a/example/assets/electrified_button_nested_text.riv b/example/assets/electrified_button_nested_text.riv new file mode 100644 index 0000000000000000000000000000000000000000..17e463b38f9d6bdfa6ac420aa78aed0bbe02124a GIT binary patch literal 16804 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 literal 0 HcmV?d00001 diff --git a/example/assets/fonts/JetBrains Mono.ttf b/example/assets/fonts/JetBrains Mono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aa310be8b717fe3774f9444dd89d5f4101cc6d10 GIT binary patch literal 187208 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�`t1>ioQcDTIG6x2X6$P-d@w| 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 literal 0 HcmV?d00001 diff --git a/example/assets/images/databound_image_1.jpg b/example/assets/images/databound_image_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..288f9dadea62c5f559b578ad56066cd0adfca647 GIT binary patch literal 13243 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 literal 0 HcmV?d00001 diff --git a/example/assets/layout_test.riv b/example/assets/layout_test.riv new file mode 100644 index 0000000000000000000000000000000000000000..edfe827998891d3e239a5c787f875cc6f65d47a1 GIT binary patch literal 809041 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%0Dnj#o4ECLVWJFbu1Oo1Ku-u(H z_l2Y4%=uaKGo)yE|4xq=G5;~p+|86fNqtzEZl2~er%XQ;T6o0D^&SQ7?~6nYMz=u( zjZ~&e&`df{oneahe1(3xkQHG1sVFQ9ofhtamr8AyZw0RG#V(hDE97}`BX9)=k_lR% z{=Zc}bO|gHnjhA6>JPXd)^&8)I@|lE&&sTMsXfpR-x+82oG+UFT}gPC67+qz+n!~& z$6YNfPkr37T_xXxf402&i0*%}=?(UzV$8}KBPPp(n5=&I?M2`$v&rN-f}FdRo5TZg40YFqy8sEmp{ZZbR>`})!+nM7rtz(gR9WA=Fk>zd3r;GMDB-!4;GU~ zAbxsxPgf6lAVH72Yu8R({;qGf8Q{*MK)R(evs}wEY+oeOU|p`^vT&qP=jfYP3!AX; zJ`V^#Pm379JDsl{EsvT(K}mPvklAXy(MnpN(v;R%ZHfM~pq!Ad3_zyJvB~ADPSe?4|8m5fHZME- zKfYJ6BsX{B^-|1DZTtEFwv-eXScU)A40Ga3P2*u-d>vtDB}~J$l|7ca$g%6?%F37C zYWZD5!%5&~!V1@bsatba?;*F4BI(t@$=UrSVa>R>8((=rmM;fGbSd}pqjKyHbv8~I z7>DE661D8OI6ed&H*gaIrLYlDQmj!i2^FRdCNXrlH?%Jn9ohxMz~&ZX1ITD6c~}yh z1UD=5?bc*u(Zav1(~&o6o_!*aA}6G(!q7)8`Hr~_kSzyfmjbdBmqvVZYGqzt-psEW zU)=1L;Yf3*dMo&$73$p?m6ZhH%F6Qc=PMtrgkKL#QLN+7&s0EkG5UOCu{Pq}YdCn3 zi0@b$5tkbhiAw?NG{KPNJ9Wjn5-_?Ua^qr$*=|7NOI&oS52rrc*b#hk6v@K`h_B4p z((*r+;yViww@cKg4v^inceY*UJ~YNQTZMmvu!+O=E4SFSU*dG>x&*p(1!pG6NBmtN zneHK;=p$aw;3KYqR)$)PlP@pGmpk>x8u_}h?1sy8Je!z+@Xzw8eSOnylgz+%QFP3l z>6qh~G2K=UE>$CGr#MfYneIu4#>9|#^0NU6?aR*qVKZ1#(AdEIyWzwI%e@X$140&{ zuaLrlot?Y)E{LB8{vlh(YAM5 zTK*5PW6XUIne>~X4amVw$0G;-F3fsP!z^W9BAMs`nK%(t!?s7@IChuYhHNrpqum9P z9+grbz=;p1w6n9h(A;9~*sk^DAJ;T(xlJ)9${ zsOaoW277|@r9i#YRMD1pHiULvEU)*odIdR0qN>{jexvSUK>L=xVfy*X>ruE%7Pn}h9#VwRPZmN+!#hDKkGENYA{PAMEH4|y2#H{X6my&rvO_Hf zKO*t5X1`+gfB4&Hs-O8_`tm};CULptx0FA?%Y?@$y|D0r8-d758UpVGb5D=Onqjxw z(rt) zH$*fiDH%`F%q$d#IV;mDN!F>8$RdS%JO(<$)OdZ~a{*fyU`yN+RZ4aOwsrzwZf-%r zsd*P%fCB{{TU*0PnYqL{ReD5FH@BF4xK$AvpVtFO!{Hd=m)igDF@RY!~u| zk1CV}*aGjS(@wGK-)r2_O_=@dm_2FizlYg>3$stp%R6sgI{Vu*G9E2~s2y&&9HLXQ zvT}20Was2yNwcrMY$?j#K!f;1QaYT|EY70a3!v>BToF;OB7?%5tzMx(m-UcP*(zxc0`eBYm+sjhx?t6y7a zxb9)05o+?^gtO*HnmY5B-cWYK4W8OeDuV-eNwd|~{q^2GdjefueMo1Gz?lBNzWzv0 z`m~uADUGBLDvi^xnku2l0a|(tozPAzsiM>$vd%suD=Txl#RJ-65)ic~vCx+YkJ{;} z)z+W9)}O`tQ_at7vHss3XZdQ|6}j_SFJ4J^Mv9hY2RzFOuB15gNy3V0? z*kQqn6-o^dODLhFZJK=F&$+ox`V;W;`SaWR>hGMKbDrlp&-0w;C(rVnH7kPVc~I?s z5`*XhEZN1}^d#K3^eRW|dzF=y+Z#PxLxK`m0&C#l1WtKd)t9lPv_UIU3~@??)H7%)}wv|I+MnXvzm2@ zF?0bHM?x8C*hzFKCao8H%2nH7$R(l)lQTgS173>_NX)Prm3V8K9TFoGWvZQqzOd11 zG>Xo6oy5GJuMm~k;@ZJAr2l{C8*q&tbmt?Rg?5*YTK_Fz-;pW>#rz`8dwEAI2gKTt z;_NYX04#NonRFM=3-=Estq&LUSkHlGL!#Te>TgioJ5+QH(Dlrkm?Iw%IU4(8KM_Y|)} zwkBJ}suV+IMoG!uN~V{Vij3@#WuEPk*MWU)`d}QHW`S5($Q8r;%H&j%}13fRbzE{y|K>DFU&bNG+~I z`1+@~N>ak{9`*q)mTy4$djmztK7`kHz~5c2@sgBeO@i3y@soihq5o(6tEU@HnA?wf zj&%lld%FD{9{k+Vd8!xxf)4~d6&1lG^7RMN{*AOa7-n7L#qKVIOZ1?t+{tdS8zuN7 zKl4!rGraY|PH!i^#`pj1Qt8|PxbsTDpeZ`R=n=-ryrN0SWO?u)R0;KX37uStz9FQG zzO^D_h2xDdO%`2>^fm!+ysK>ec6eCI;JK@}vK;z`E~hwPl1rC68`m$g$3=gNzK_O# z40s>-=_%GIlW-e}Faz0OC>cEwYD8Z{#jZ8~7o)Ya9&35!KuBv6eEh7l0H{Hz0>axc zv1$vC?Uq4YDJ}{@Xzf8-w=68eiLX-D!~l>oeE>6jxWsm1hdnC$Z$|dWcWb14Hyr1QWWZ_PNTj<1pkqDKz&s89fn^&Ux5t1)4%&6 z3*ft_4yua)yIEM^1;F|QV0|L-3;Qhe1^bDvZqqs_Bu#CHzU+{ClCUioBHBIs_r3dK z4g37XTTf9ctX#T(1$1^ClS1{JbNk=-QPE;i_-=7+g?u>@ zgMS8}>4JzcFb|qiR(Lvkdu~DctO$j-%jaW(6P+FVTMi%bgnD(ZHBt!0@L?Q_W4+LB zkjLS6L0d5zP045pX-L6M&T1V`e{pRYkveqNG;+m@t+jwIs@TV%H>saU_-IW!6Lv{n z;%uw-anQ9Uonr_DgdK97nYzmQsY^&2NL^9VR%v4--tuvi(2C4K0AHXG6k;lzxV%d-M)SFrjaV9;9z5o;#2_V^20!YUXE?GzOf_$Z_Tx zLu|*dp_;~-$5EWn4?xe;0r9aBdQJg3Z+i4~V!xQxK&B2%NWJLd7H8SLjMGaUo9jR6$tC z$#pq&_gT=??OcEVX?Xd1Mf7&|I*oz^@#*m#^STf~?N*Wu!ET5VLClzvk&$6Fxtxf9 zVuD+RA5qX?IB?ErYZBU+lh!1o$r1uWW7*C`9sz<W=gKjDpbw=P&NAfMuKd)GG-8Dnbqo6fvZ|<_1LWeyB(AMrz|$XQy-C`RRSV~`3L6^3xVHjv4$+rEAd~dC1On_H8f*WATP#; z8u)Vz?QXKe*U$^*g_`+uDAX0U3T}5E{RV~RX+=po*|PhuoBvR;@xq+%1sZEnjg&`n zqQlOPP*`Tb_|@{;Mjt!Si8wJl~r$d#eD z^+TxqeK|LP{5QggO0n51Ap8pPc?%lt$npYYG?sH-p%}tayb&fkMY5QLVE4KWEVM=k#_v~i5Qa#%7#jTN`@6w=*0*{2i@fL zWZY#tC`lGX1T|mG-LOFsGHq_5q{TfSSB6IB3Gad^Dr3!>Mi$=8DuiOzhJ(Ic$q(n! zg-$`0FgJQMu_CwFVn(lSkPLE6aWRB{R+15nA-f(in9)THJ}{SPGzZ)=tkw^Utu~v2 zk|S=R&Ei%g0dB&oe}z?31;0G3dJ0w@Z+SA}p>|N2&6(lC1h_M~r}K|aggC*7N1o1G zb=ZvysJzd?WJR}Z*``g3(1UkrWvyCCZMqglN@@$MR=60VLlL&l10@!4ebX2A!gyB- z?UK6|4qtH3LY&N9&_*nXxeCLm*9v_Tt_JMCQGu~P6BP$|gftNW^7&BsN~c9qA@8~W zxsh#fNphe`22`MvqErkAlg=uyKuNAmFocg(=K3!%yKfVXDdUt0X%jmD!ywC?k(LTK zrB=miN~+a`nk|ZMVwNP)4;E8eDvDh9f1uyCEHrx*9de?xUHX<5Z?_~ljgjiqhrF(B zD$NW}Wia8;9Z(hu86kZDm1+3|q?g5>6K27f{*zLIVcY^V=%i@#(dd570@u{Yd~|EV zd;@Jqv19seM<~%58ROB$M6E}fE~t&v&JabJ$Yh{WcegaUJCz-fO@~g=EYRa5tWP^d zVpF3Bh8fXrk@CoLfgoeNg|6B@o4=JP)xjX@&jYAFjcHYi6WZ*VW}i z-L(Tcn3>KH3aKKYRS}Ad-42+XYu$!Szh9OE0f<#1A39Ak^MI&vi2P`62~VI)4ET*W zM8V+0qP?w60Xew^o6r3SlZRMs=SjR-19y=OpaYf_++W z?xe^qn7!3z!Vt z1MbqHu$Ht=X9+U%x`^+IG#o7ttsjqK3RcSbG7CX@qROi*i8NAP==5l;m4M&WvD*H= zNtN3Gej`Q)HUhA2SSutWGvoKgW%zw7=txw1h7n#JnEi6>m+q_QVZRhHF2dDCVH1nN zOnw>uO|mRIAAfGgkqO)h1{gZRH!C{pz~Yec{mujHI=Y|Ia|-;S6`Uf>c}5U?v|N9) zWiQ;4QJ4u99Ejn}{5mS;SkB~Yu#6kRm!Wn-0Y2$#W;lb_U9^YKM^Nt~{9o=z;zRHz z%9f6AJYV~|k9$H=k}*!~_Ib;7UP%Y%E;qlU)-cK@u9MBy3HFT4jEqbuV5s$kzHQ}5 z-i%;n3E*-&;6nA?zYn;O=I#j9#cg}(A1H^m=cV~P$hHV&4=$uf!XICBUIwl_7ptS^ zuJBeACBwhO{rds26eVfd9e4cV%8RBUpEM*{GB4sDE@2|_P>2<8G~9c|MR6Z}+_=sm z$Z@j+&24RMz4Pbe@_t;n1~pe!(W7%XescRfbV1m}D!B>qdExgf@&%dxCpsLEeH)ZG z#KCTTp?c>bC;KoTNSqk*3ze1g5CMEYAVtr8V&#r~>*H`IPn%U(qO}GYL*5dvx1bpQ zjvKEm%!Q>OO2Jijqct^A9}4=8c6Oq0mxOa*95*i6qz|3$@Ocpo9dMB^mZCBnJ}eh; zZ(SGXgId$+^9P+tr;qG!^7%Z+=$7X5_pGl{x$JF#@%@1D6@YOuU_1jbPNdt>zk=Dw z3CfXVmMJ3;Hid_jyAt=}Ja%^Q-pnB`N7E0&RhzE`oP+pGBplsX>#dO2v zpr%sf8-0&o)$9mppGzy$yR>zeXe94wzaQXgx&b zK=I*9Dq09T41J{FGkv0xGA=C*HPm8@r&-t8EEcO3igSvYn`3<}&3{^#fEOj3ElCCh zx(g|p>t0lGmjv7;0e4z{81YHwM-)1A{u4OT78fKR^T-aN9>2A@WU-uhkWMnQQ}`D2 zQXT}?Fp2+ZH}ZbjCpHlOlW{4atK%Tar;QjOzr=&;h-=glB%H}UtInZmu{1){eO0CR z!muHdopGUXB}BSRF~0alyiuEHpsi(_I!~vzvZ#F3yfe7b!2qPzgYLKdvTY7lCu8hd znRPnC1u|`HEhJZo3tuHF3@w;~_!>L&usggbc88kJh1RO+=}{@-q_y&m!bDgFM4*>s zM20|`sF?f?Mp7o29k8LuQ9Cd>hN2z5Vl8i0mp^~fekpkVCPkrp+ts)yk$3br;pMVE zKE={mQw`I^<(%E0fR(Blr{f(sWSZe4_>@)YroBdXo(4r>i|0YL`xuU?4-w-~Z?LAs zOQ)>MU0gLztbe7l^3Q*+azl%ipW5L<0ed78p$P=cIfp;z1(i+}Cc4%AFLZ5jV}XY24k~E*I>0rV5#eUI-wn*aI)PUeK{7 z-L;3?u=jw%b%GHAz;%UTp|Caz1zAiO>4gxMHCs4Fn5zvr1Vz5H$T% zrfD8@^0*!-T7YX+^9TZS0%8=1YUpH;NsOpd4~S~xG+J}^kJ?0|Y#2qPsp>0;?N)KI z5hMQyTr2=CF2js-fr~RrRpNsKrD_W=tD7UPsluh_X0XWY@a6hH)+6c%dreVN21#14 zcZif75wDJOl)hIAXa_Eo<9R^XAS@Tkgd2one7{S$Q^;k16R#*@gQfC9RVq_X&S0tR z9_g42k=DPx{Yr<;R&Z5RS`SM@8*#nd7^NdyO8VsS$wotupB!x_b61yfjNLvVHQ6Wx zdb)<3wSJNQ0T<~pgcc**0}$?QZ60(T;KJQK_)tDbbn5Zo&OML>2g(rxC_8QNP?8UXpC*l4KJ}65PKEWEu|XVdj#=$R&w1Sdt98PrB(1+9ydf zO#%&-Cl%T$=UNctiH%mv4?5PZ;)1w?9%o#WT`)&6g*7YgAzjLs;FZ6_D;MImKL9t# z#VZqde718<`POX}<@1rv^(&}He^4!kdZ;4f8qgq#hb$$)pgFOr8iHyAt3*Jh*$f5$ zi-v};oI;DF2-1vvsL6PQMRrB-{-8f>Te!K<4I@r5kItr0>7$TaAz?CIN)f2ngS$Yo zV53KZOMO=9T=o|*c0Bs#=4M;bujaxE!tXa6?i4@yl~Z?M_wIvE;jmF5Me>qx8h@6e zg9v#;=0|>?FFaBQp`@CHN=gt0;Kt+B-BnU@XXNLxH)hLn_5z%0N0uz-%)7O$?5d0G zvI~dENzs1zN`ZY8t-5BNL|KTviXis5^ai`#o+v4CLE{u0Xp7nHrY1_1IEWBIJ`_Ff z1!2u}*g_Djh7cs`9t0hc@=$z-5L9#&Et|cEKX3WsFru|F;n1-vejf+cUINyZ18dg+ zYm0z2W{srhPf-5yA5VwQY#uYge!kWEEs;4WK0A_WAw0k9+_21A3sgiRcHo`FdkRf^ z>*_u|?AzDc`hSN05i&8@igTt5LFQN8YjLAIKcetY#Z_0mC(zeoP?8L>O2PZ*LOO0H z{BaoSQG`HHNr3NG40+K;{ov`q==4M(*lOB_5p*>iXuZ`dx}%YM2Y9%el2eI#a2bI{wwmEC~w>0&ZFi*7O&Um zJJ9sc7kBS&{kY-H{zzUAdrVqpZ)|MTqN`srthzA~+<~)GCjxtst(-AyR=QJ|6j0{j zjDN@@fIYBkEyeF!kk_Clz3&w6a=_RnOH_LCQMK~o{kli1tC7S_YWDrY^G%#x7@FR! ztgNhS=D)->{teNqfBm=>BV!LL6|2U9U%O5U<8luk7&f@{Jz!!dgG!tfKq|)9KEE6E zuqH|mR89fxVeNE;(jY<+0Z-rw0(b*VYC+3nlzbm&Mj?6L&odEHC591cLphF!m;V|# zq8L`f(NCDfV2qoqa_)0N6*}dJ=YT4~>zzy3`t}%Gd(IdO+i_g;(6a4+gSm&J^sZs< z!BH`XQ2AjncRmnBA7_KThle7bV{fqjq}~K-acW|px-Jf{b*ZE5>L{u zA?Z_;D%GD6Iyf(CEf589jl&5OsHTs_`n^AlB{dw z(VYW$iAbL!Hg|9MH`A028#ZoxrT)}(B*BdYM)InO)`|yWqQp&6L+>bwahF4jqQ?ML zsfQiocjS2F?r+lHF{K@5ymP_;JbJJZ&qF#qr8zdSf5QZZKyW=-h(|>YL$>2$2+pVw zRXg@j=tCBYLR=eOtdrAlk|SdEj))dEFegr7;iuuRmB(~=+afJ`jB&c26W*aX6}=LQ zIjB}<-kgV!JX1=W%H<*CqJ)gO#59RJ1HfYkp`A$z>=qC3cohx(9Q$Q}r2<@17e?xk zk_TL7Q7+uy!;w_DVx+>2jK$RmF4^%>hf^>Z2$lb>-aW-X?-&JztbVSFM7BHOXGYKe zxNAS`FrGd~)IskT>~`{CEP*uC8|OpE?o!of=-*YNVh=3#N}%sbT=vyyl_C1jnU5X} z4wTQRBzK|wK(LPmkACAj+UoBbavGsgtJ+Q6AAqv+O{Vl@L>a@oKJ)yn8Cf&ZN5Yt2 zk#&Z^!J`idy1{Ms@6>Ic2FTjQB zWfZEQ`%pK|;aYw1&6fnul_s_;DPC_I8vJB3?|=Tb>#cw7{%iRTA8f~_e@~tcWi7bB z;gt>ZU?m~@2z4&GU8o+F18?5!Et=H!+mi+Ef3@0W!LO zbKKt@3M*3Z^aAuaRNEzXTSDO!<1WSsyOhE5S^2B263laW8-ik%IhL<5IrVQs1j~;v9U4{0P zcZN%3g!C(hT`gd3!{)^gFM-*PeB8S6=vD_?{!Hzhs^2~sJho#;9{mwsl7;Xbwt_`8 zgU2UhZ@H%U*Is%5^(RVe_9#*Z63TUH-YMM&C0P=1 zu}1SqY5m92rN7hK@&4{o>EreAj<`%&p--W_eHzNT=Kg%Rq4DVMzb3n>0R0zK9qVqP zDSJMc%)v-+@`Fs4SuvH4*Bc}-B_yg!2ECL|PE_XB%`|?!K3^TGTmQ9jW*&}hgKNtA zwa(O%F@ALOMwcmpD zn|n%EH|h+9q03cm~# zp1#Xwtvy@5lbY>m&6K2MtFgBax=ygiXibLRff|L<#y!S4zo*Ukj+#q0q^0!`Y#*QbGHcqCECETd&KQX}6w>AYn`M zSS72p+=xz5H-0;$I$$tLZfbg=qGHpgr+1!{eBnKU^mjQNrKP`gFz3`WAsE;4^`oJf zdY@V@&CqwTGvOHpd5xlYEU6M2I(#CK9#P?N&z_X%wl9#1rUCbS6!Yi;hX-V|c0c$SAI3^^ekGQU`D$p10Qs z2IL5*ks6_KB0iJ~#%Y$Zp=(s<6ZdOt95|b{uK}~6xGT+t;K=Aq+Sd3?q~B^g8=&8& zk$#Is=I}+XSwp%lK&C>5)`%-4=$)}&;?GNP=E!Gu78+W7%^{-=UXAmPq1*AQ@UP6M zD6?z#zfhd{U>DYU4kvEZB*Skd{q@C;jNrj%^H5KLNu}5QZq@H_6EiNqc~0)KUz7lX z=cMwDp0IdE1z;YoaOvnpwGh^V7$BuVMLj33=erST^tTUZx13rw2W&^@R$Bj!#Ng11hKa48g z)jrDqyECLwcJ$1asb`k8N632cNsqnnX`|?BBYfN_w5oZT3yX2Vlo>_Fu@3q&E^=yV z?BEz8K6YWF(9Fl?A;Ps-@M1Ji#e1Aa=bvfxhDL;8sn@GIjP_&nP~Am4{R6q$Z1wcl zXdFX3`cbYnc)ha7$3&+~8!#Ovj*dNd4QoUQ#q6V<>r&k4l`@{k&s^nasyHR_0s{iXT<+*_CpTL}Fi!fFv67I_nG&qSFt znz#nd%;61tTxATlD+${o_CyQeE1*{8QJGKlIdBDDbp=^xTEXz^uU1DlXrrlr3*QEx zn_73Mb8GabagTm_+ubNcD9>0d1W`qWV_c;;0GIYoHZDEZO=Gn8csS5Ig9g48D48;&w}vp-&*Kcplw8pmoVh$=78I7+siesbSKi<7L*1bdd$aS9~} zeO`-2VRH&t6>H_slj23Jku20|4(bxrgUUzbjuU~GH{DdWA|F8#c%;QM#r+5^T}_W} zW7P{UIKmlY#P&D0ZQHi9U9>H@?Y7%4OGmqp7x0OK6J2P^pbO#XyF^o3nv&FW6d{yH zdeA<0dgk=;V8*KNZ7YStDRBn!{KuOl1->;jV@3%;DQOD4K9kK-&u1Ipf^?6u(^x8_*R%SgaYycpLGs)P7?-nzYojR-`+O z0iW{|yMtFaz&_I5JIjkU%G^_^+jw-=$~^Rm3Bc0<$5g%0n&x1^Z-X?U8BX41;kvWL zUGiYuxn7oA%d2g2ZXJ}*aoHplH9MM;Q9 zh+)ftCBIm_c<~kA7OU{M*4Ca_UWn|rgB)EwsO+@~hI0S^@wrqI<`ote&Yo5M!p>c9 zANn>3=Os&E1AYtM+?~89#%Az|ClHtL2;2CrsQ_3-K#!Bfy`Y$d(|$D3N*QCZq{p8X zT__0#q|^1mJ%n!ojX;#7gm`nJ$?QAP6$l1!wqp)FDx(d5;9Yzbh!>z#r$FTFYn-3- zHqwbyt$Y_x{uUkJc2I@UaR};=D3N-qa*W|eWvQduMjE9Dm69&1%|#wf1!LT3r$Aps zQb-ld;#Oz56R*DyucwLxGb4P-N?nPLe(dpEa1xSFw0-#X)Et|QT1u}pHMHpM_8}dK zwkt9h5yBi)v`kK6C#VCFP|rn)O4Cwo=XGiMO!QX6VzU1v=~>z;frCaT0a?1KW-R8_^q-SD?w zL~%B)E=Sm|d+xcX;i$Zi9_h)wp&4cQ(Dm@>m;ZFpqSdSMk}+GJdi|@=qbjvl5@K~J;PI2QQkYmzEi5EL+^QS2=$ zMj(1XuMdUrE$h6=iDKZ$fddDQ_K2oQ=P`pOClFeOL(JGMz{lkgE(4~GhUmkf#PpVnkcu*L@0KAIGBHV?vV`{`|I|UuFv(diC+gAOGu@EJt}l<1d?L zb#+-R!s)KAuI`?$lP9|Zr%xYiY3Vxs%~9k<8{-THYq+ZmX;=nH*VpC!8u?R4&>}*4 z5OJRfE^)DVCkrbSu-m&yj~Jg|px1c;N?YkrI5x<_fj}@$Z;Uq>z29{D1IXvs<|LAdm7ZOF_xfNkk z*Q4Cet(;o!wz~SycjLak%$$QqiNHud$jtQEZ1`cAvo50hm?M0Tf;IrYkDskrv}jk zfI``fJ+6r|iG0Z0JHx-xuPF}%%AJM8K~%yFSJQ?^V;T-bFe ziI+@F<0kQDtKQ?`42C?2vgozcp{fOu+sMpi5sz(*R3GNhAHGI0PLcFfGs{}6hN!xY z_uW}qQc_*L4Q=38(KvBeu$WJqTv_>M8?#Xk(fo<5ZAYc+9p%RterLwyu_+f`XdPot z95-cbQs&I>XHJ_wBg39P6-CmfSdGEVIp4|1oG~NIWWQ?NFD#4lt-sSQ^)u5C+Ho1giW6sPgBaO6t!d!r3to*_}(M1_fbyhVuBf+QVZ} zSbxr}83yxsnr^DiYMFV_oa}5%c{IpYd8d=HtxGV+PpT!G;dr;jxg!XfY%e+ebAef(r z!mL5mcx!^zeKout1^A?|LrP_!P6^<{%bZJ()$6mbE=1{qxA}=_hLS~lZPHgh|3NtW zvI2BF*n#WVtL$Ov+HB$P&$#}Ao8AWb`yI!Q`c5A8g!(ECoN^wVpp%SNj$!=3?B5}a`%5EoQ$0hO{ul(Fv%J5zx}mOXt^LNL_c*z})+{$PCi z1z21#h$<;$>7g2&mw}qj12s|2Lh2r6qoD07`Nx@}tZ?@D|QuZL_M?2&E ze%@pf-50kbzl~#^trKp_rDVaYIhqO8e+NX~2DB-1;CbM)9AE#V1~dboHF%%;dNAYQ z$zuz`QaCwm;ZG)TvB=G!`Ve10^OXV&b)(Fgi@8mur8k$BUV$t>=voNbd}y5s8SXaQ zB%5u##Z2vg(Wl@cCvyD+#RMQX?cLYB@4&$}{vXt2K(sjD^)IpOb=Wn+&~M$KOa(bp+2KkF{MqgBU@@(CKD0z zIv82*b%rzpMV|C*P*J8*D%orX+rnjlizt%YKv@t(C4jEQX43Z~hH#V>)pUO*}{#pB;5wW^|uiVjsYAg{#H}i^E0-Fahe=S0K>G`ejT)jJw zE`%uv@T)%(=s;6TeO9L7GxQ9BvPFcQn`;I~GLKyVCd7M;0K+X%iE7;N{2JWunwlrU z(?DAalG&cGu6|=r8~&kEb?Bk7*gXH}>kYQHA{Xtj*9Ue6;uiV;BnjZ@3$v^l(=s#C zC!*^s{->k3>-8$E=>9<&W<=lL1ASkDodQn!N8bDls#6i|8P64n;`wp-0xCy^Jlxwy zhD4U4&&~bb*u!;7eBD2>$(^;?Kge~)jRKrn_JH*L4nU`fUz`JoN;aeH!v%r^kBxmj zBJ>0YR0y9xdxbI|8qVXaia*b@D)3X+C}7p7`BE6Y77K3oLeAYU<&jE+<4ipEQ9*A2 zczY^X=%MpK%`AX|t({%not-B-B*{1|K6)^~Pyv*jM?q403sV2AwzLUpR_d=yvV1U- zdK4!$H#JnKsN$R`517&_icn3dv4p8mPvUdWJ@=18EuVkz;l1GF=@vgv672-Y1mMviGA*1|4 zlCVhlqfjr@%MM|w0>N4NahyVj$fJ(2L7c+MK+zX3Zd#e=wlaLa9mmxdQeD*Y6^B>bF z)&5x`3g1M`L;W>D8{Zq7OFHT zYSH{+P@P=`KRn8`2o6h7GSz7^+C})%b@(oUTB;nZO(rz1m03V7uTg`HWVDzzU%;50#tZ{EANdEb|Z+T82GLsb2ADfYPr`=q#22ln}W>@&W!hjuit7;kL2uQgoO&?0kr1g;JK3AH*o1!1J?ci) zM|IX((pg!v>bdv2)bmCe+*g4DsHUPu=_o20ksL#*U6UBYAQafrB*xidO_LYHp=PMO z7#8>&RKS-Hrv42oK-Ug|9tRrd5Ck*gbQ*^sYr8CZ31(^zRxN&D2LUOyrj9iNGi}@e zuddjpjw3mNaq7oFzE1N{qyo)Dd|8-X-!C1?Fo@4Z3Wc4CGMeeC7$Ui(#W}>pNXUqX zkK`T+jKuKld=iv1oOm0MWzHfbp2Fw};=|wWIF+<}XjcKj~|DCSv+Z zdcG|ozo=;bkFuws=b<#&7pme=Y(ZTI+lC(phT5d&`i+=>K9L2wH~SV4B{8nUhnZnBCCYhfgp z&o`&0+3dDtc&PpUQ>ci~^ysd}{KwndJg1lh4?%K*(Gczq^hz!$KvV>_JJ2n_?S|S( zeNLSK>!ec`hsJ#TtIo;#T&C7QpsQEv?(m0$&XfeBWEy8n9cz>V+8p30zskM z)9O9pT5CGidX%mRM_a${!lIOE#h%zZTg44Y0og*#8Bv zuggNF@&XuT$l(4{&EWpMHIKZRm33}}k?Qkxb$+#H&z?^kOK)4UWXaU7Z$~MXT2x*w z`BCoGKU=Zl`UTmCYN^lG{}JtQ>sMTx&jUa9{^kPQgsxLVI)umS{x@_b?AmoDOyJ9q zpp3L-JU4)oK%_#O5Cc<T>T{ z=KWt$@Amaqf@XghaXc>sFPMe8(Q0@0nMhz*lv4BU7^lwXJJtIDam>JIJT%vP@IdQV zEr&mOrQz$79`E6OO`Yrsa?%)5 zaHt{V4k%O@6!|hBhko!lS-dbhav2}VYd-QQ-u{Y~Jht1e>Wi8lM>CSHHfU1P;-KX5 zK===J@QF0A5@)Tbg(FF?CQAP+PJ~6(KOV7vu#pG!RD+&lq+9a5?22z z2{xoZk-i9%6g1)*8pk&X=?`3}SkO9bYWnE_oePXZj*jy3Q3J52#mQ?mM%6g^O|-GK zvglKHMhYGU%A-aDe(aBvC(Ikb2elb#l?n#B5zMwj;U+h?oA2j#yi&$1zmL~aH01?& zWrE#qYJLx9arvR`b!thsRg?bO)H5CW-J8vR8;IZP3sTgcuDNN;2E1>QbuwgwWm@)+ z<`)%R()PUO%zUQ77j&9VeA)bd-Hu)FhV9qSRdqnHBZo_D_|y0zOumzK3uEAKNnyv} zpst5r7eHv<6FNs?6PhhZ!g%&pQsIoR-`e%|{y@>B{muI?MEK(_lx3nW9$dF$wa)my z_J&uUuCD#3?W%|#C;YC^!Q`Y8EG#*v_{JNGi|3@YpgTF&0EItRx`d+J^Wh1@GyOM< z=1doQeC@k;!E*WL$MscCr}Ob0AA90cY*R0CTz&hJC3x46QZq9cMzdU`;fly@68%TN zI{4L*j;=sAG%tVWabHKral}%NNlCGQvXvU4{iG|oFL2W5>kLR{*c_}TYoc?E5NA$K zPD)C^HTZCQ`*9ztq113({0_L#H0^7F3kPr!k8rf_8awwrtH=xC2)lz^0}w+?__GvF z=B3ah5KO6m<|v%mk2=CL`0u6WCr$%DalW^ps-b&=ELx0+=+UQUj`w%;>}zRj>vTqf z9TSz>W;^Vxb#-;ksfDZ64Cbxu+BF7v8DEVn{Owh&RmkGc6+#J~vPf&A^MI#T9{jNM zvUI(q`^j=1dlR=jFZ6lKfsB&5z%BPW%MO8I1#KNY&IIXX({V$Zb+V2f@;K*40upKx z?kLb#R#u{dPx{BzRP|q#BWUB~7UWe65I*-Fy16&wvkpJYlYWsqE9XL~_5CLmSq8>l zZ*1*``%o!hlxEE-2nEogjc+=qQ{C-Nzr3&qwD@1h$}PAar2n zJry|J>uYB1ds+^8{km~UNq&FlDP~HwO`MbjMOabLFV%@Ap`9mBE0XCnI~`b~LoT*{ zjnsp7E@0*1HS!pgX@Xe_xyy)+K@EG>)9V}y3;D!kBZCtQl14i1^L*aY((ZLTaS_nL z++=j=`j}3{jo>kkf6BL{I@3SLS)`8IR}lWUYykyiv!jP=uH?0aehq!QD4ffmxo{kn zp!s1L{`T|9k2e3iv2n`_hui!p%%kr)am@QoFbPx_?`_Dh{fj_oXN+<*%{)o zFPdBS)YZPxP~YklCuKV4qE-%%eNB9*{^Rx@p>zLd2g4T@U#pVC7Iu@1cWl#xCSDFY zu7)NLKP!7QYL%UrCTA(D;B^%_4i0T09vK8a`U}EyDD$?1!-~q=K7iq5gwMZu44O3 zPgg$kTKyhRcjAoM^RNH;Z)lP&oL*jIkGY_BIQ1YFXwd6<7?Kk|J&Xf7)+F`zvfk4n zqh1Jt10XEUXfo-YX?m&s@Yn5!Q8dz=XcU9py+XX%JaOWLM3+m@OHMON9SA*LeMza7 zxNvYCa@C;N7~{sEU4azVK@kWl--EXTGxnZFyI5Fi42j9f7E6kW{uD@?n3Db+5>~0!%$Ac_kd>&?#O$wqHz~P-EZ#56wsu7!-&a~qdcq_V{IY-{N z19pV6G77RBdH+wyg4OCA0)q!t7{~(RN`}Hg{ckKBmH`ej;6QZ}e*`#Cby-UpA{mlr zU3yhX$<4pGfsH~h_H4&Si!{9CGfgnw1W-Km}62tBjX`K%JmvyDFp z7mAzxgPEBV&nsH$QVIGRm7r0nt^^tByy6H4HoVgjL47{{Uh2|F`-HdMbNG;l^*I4l zXwS){8OMIOR5G_roQ`ag=~-q2>i!y%tS*Rl@^BGt-w&9~15Bs}=nnxC7RZO#!!xG5 z_6SCOysL8EL$5Z^)_wZ=mIBBwwJpKQxHVgATl!caz@tf!WwHu<%JW(zU^o8F#vUlI zGi^Gm+c)OHKS4R#UcdKvA863~um7o0sou?e^Mq`Apx`vIS4G&C=0Y&HK&-j-m&93` z_TF|mbX70ndwIomVTLf79fsK13EI7cdYe*jN0e_yDy}7KQynp@$WtC6)KmiSJXA4}SQcpcRSy)|6y(a-spjY&`*; z74+>Ui38kwY%l z)`$sv((zRTU05P=+98r?3JRwsPXTcwS^x zapokF2oqIt-=$leRF_ZzTx>iawu zdp{3**V$~FH^&O3L0V*!BHbs7_oq z)k%vP8Ddj&gy+jNhFgw=>xFbB(l1dfG!eD_#bGvmWH!}j$9v$)Vm{3U`wyAKxVb9U zE~d>GwToqG^9hYB&=FK-GgYG@6?CL^($0p?)xvis9#rSz<~MGLBje%7qarK3ZSV@U zIuaTb2kvW^3PtuFhoVe{+hw&JidI2_>}i_Mwtr_x=!n7+v1aP-;HX`L;o9!VmtO!# zo(D*d2Zh7t%hHOAt8lnWO6DzEI7f{-{=_(YQ88;#nA;`#eBU_5xXuPe*s+N^+0nC- zZFC8Zjc8shm`x~k>)YS*ubr>eMq0+7V9!gdemVZ%5dU=w%XW!&I|Sv}G=$xh72u-U z!k@R;au@UD0Ryrm%ZNhNE=hmb)x!U3Xnh|t@|8x{lW;s!_6#mdp@3rWcc97Q(GL9C z=z=U4oUk`I4VDQoHrTDMC;RcCSt$uZs+DpBwxrS;G(Db=O~BFcr_pot^$3&&X$fU~ zBX}u&s1$iE;J6rYr2d=V#rw|y99iXD9yM+c|J=5Hd-=M`0u+rdC@3oWVd0#MV2hGv z`R~E(!UE<9CnzSL&-DGv3gHbpItq+0L;GyE;1X_u4Un|cK3JjV3azbqq<5JB5_Z)4 z`G@b<*B5|;gNGx+eS_||=Y0inx>+&VY=IAIYMPtBF^`6WJmR9pWea~ed(m}2TX9wh zsY=SuK7ZzPo0O22>4RLBoaC?8iwHCgbRz1oqZ1qjO>O!}=hcZ%LKuiWr~LTc0KYAo zW$P#^RY|}X^H{sxZnMA)P^CilGHm2(J3}12ny;7v$eMHLX1l3+`;OhnLE%k`4J|FL zo=>*_0hzfv+3f~QOBLn?!OrIurByP$J$xTgu*EXQsYAA?*Oi)ri!_B*aDANr04m1wR{l?ev&B>l1Y(n_3CR-8` z3Ioeqdj7^E}?ZV=Vg@gywZ zrWnqlNtvi5wDofubpEV^RMWgnkx{W85iROQMprL6I=4GnXemyPRI z;HFW`3A<=cN4SuH*h*hCZ9*GMGxtYhAuS+g>|(xNQkWdP6qX~DH5it$>z2i+jD~hb zd!@-#ibj}S6bnPCb7W~93n7APKZGh;V6i9M=Mf?V4AVb4NO1&94R-b;=T%=@Bs;s;Bg%|F1J?PRIT3ZeD zy=&q`Tp0NdCtxlc=1Pv4OU$t$xMsPSy}JqX$$T;j>vps4P-{VC&Elql0tfTs&1p93 zgz9Fv_{yaHuD|~J^)yM3-QGjrP3`R_+)nvynnWUaMma(gW&jlw@Wm4w#>c?dYjnfU zvsj_N9%#VyDtSkUPK&IZiCtZcT}{C(lpm4=2nv~i-m0XQrd-+ER#34eyVndjx_%30S3$&IPdohqb~-6$r^YQ61#Mopqp1ZOj?2m1jRsVBy6%74S1THT|#cI`_U*~hw2%Y{#}O4FmWNZYz54pu>g)T(&wv?--l8LN)DbE`R4zsH3>l$GZ&|EVM|ib4qW5`? zLSs)tREr@YfxT?k_7bbbOa-QA0Mp~JGU`1>nIbrzLIXNTmr&TDU~3@uF#FQktOCG$ z+0E`*=U}Zu@op3VKo@hr&{mw!>cchRm4aGfP)3h$W9+*2?TLt{pf?rXsQV|j;y5pG1mfE}tI94AZg%4K*Z>SnS`Kq?EX zaj(f~Yt`9hfUa@OZ8O=C4IFq51sD2-A}l{t--%HQ@}y z2l-e16lpV*MT5t1-;!$rt5<*EdRC5und6wJy}jL;f^_bQ%xFm&J3cLqa_vN^4dHCA zXN@9)>TJm0NJp%v&S=^r?rA^t<(I9kcv0`^u9*tk<3gI+AJr3mDPT^1>e+z#48WXh z2&VR4q5Zv2IwUcR1eXZGMF6>1lDB*SlqrH}rULh6;X6gA>;;d3KvTqqF9UAVvdemR z8~--@dp%fjCEimkE18KLRf59w z@C;;K&qob{s}WwaDk268kXv>O;FTSog4%U@TtLx;GpL9n%%-U!6jN*evi-Ohr6V9J zS?B3s$mNEm9yfdiyi5^7!WuaRAj-&?I?mL?P+X;pB_)}3crUp85#op!iJ^Y~_8LIt zH-O42K;>#c<(e}vtJNGAV0c|_#P8pR6?73bDTV-Ox=`%LsV&$wVX+=lwPIy;Vbc#p%E z5$X$cdhs)olf#2??i!{?hCFi^GBEV@h(;+Sv7Xa?hQ1&yMC#9j$s=}&{jD%K@46Kf za|sqp77B%{Scl9q zhd+67X%}ArI=Se|d2lIT6ix}7;1_}~p=?piaV!K0_a8^;-WQ&`?KfAkt#Gu`^9p+b zj@3sao;aD^7QPKmlBtnXT0zc_uzM<@(bF0^qHPn?Z}Q!tvf?C-%Pb&H;aCnjPWSV*M@~c`}zEihRTCh|^;h?%`yXQCJ-} zNC{O{kVEmerncFWdJpfeX@KnsB|2&fm=Cd7R|?-_`@!_86t;!;97emdk-4AFVYfR* zJ8H2k@PR=raJ)2boN>6L;wm4+1}7l+-$TudX3UsAF)1XWno5t9l9Gf=mh!+LX2{{F z=?by(TNZ1<%AhOQIa3*+y^*}vG+|9ca?-2SD_kMz{+cqT${!AFDq@xR>Mlq}EfPdiCY}4oupq>YdSU?!&K` zt7o#{7;eS?UlSNk6Ci5V?k)qUSr$4q>WbV&INts@v`lji)s&$lLsQ0mJw{U=9=kr3 z9?ipHHy7`{0Nju~8l+p3o@dUP`ho`ze0ikHz{t%8f4f4sSY0aES=a^8WCB+kny(wzjpz@)IJNEpXj`dZ~{JX90*%!~C*6VtY?}y=Jt+-o;nc+HIQOzRCGLNL|i}o)cUWj^- zH$Y)6V+chB+NaFdw^j=?oZ3Ee8rxRl+;hy9$})%IkIrP5f_6QAfa3k z)>5d{<;d8(5^6>v{yLps8_wq9;AG*7L4s3GK;zV|j-;-m-Y?rlW%#Rv6M-pCTsIyV zBug`_*6&<)Z9#6QG(IC!g2ieW)e@y(;!_eI9!|1e0J^&nbe9U8B>`t+fU|fcoFGgO zpE_N3c4?97kDeuzSIG=T^QzbunXSr$_j|D%^HRa*n~&?G7vM+u6V7A>f0ZLVTSmwg zP|_evawURRxQR5@2&=H(#C zN48kx!m=t=GBclpRR|j}V+%J~i3hFA%mb&JAQMbaX~od+GRIK1So*Q>oqm9xU?#?wWFQlWZA zB*#RC4yNd;oAw-WvPF4x>4w4uiwQmAul&`nxroy$fm*r(W)itF0tHv5~skA{wL5Vy1hgI=3$iX}kxvm$kS?!gXMVuxg} zn2sGz#||kn(;ogVz7`=Z_jbX#c|NB2DQ>hyuvdn{*GQYIUU=pqx)xr^%>#47bBqyq zAcdz$wOR15YIX^Iy$-Lu(C~OId9p>Aco!p7 z>rmIIN>~N!z7OZClC5FCgTC=3!hb3Oyi&v}so>C_L{0RNz*k@O4Q5-{VR#GBU5>aj0|{i*Y<>;~HV-&xQDVY4{!^fL;}aJ1cWN zo9^rQ^zC>4eW5;AP&zgmk zRa#Uum&eb|3eQ5hNHE$mCBH%D^|}#tvxjk@j>Wsh#k@8 ztssiWaShK_P|cJMENgHJ)Wp0DW}*W8OM3{kYF^Gy!ev7bb)}NpdBS_l-**z7qQ{s` z-98p`$R!l=plo4EFn0>^JrAcNVmf`Q-9BZC-53{Vj6N4AG#@m8f4ndr3^fr3Eew)qjby<=%HcPA)cSapp=)71KDlS6etdPmJg#AFs z5Pqu5EXyPx02_jWLUs`Lz=L>NiE!}splfr4)tZUbqR^#}g$#y}`$3~f<(lckH7*wL zCM&XGsVO!vEQB){^AXp9u$`)h!+2bpS7%)@My%NTd}-KBQKY`jCIwkg5kcX1DHU2nec z2M53&mqM1`iLdnhSNv0AS#hz=cGJ?OYKQt+5EDxkxgf$A$s+i?Q=C}vUts#e!VU+F z!PmWoxcA6&E4`iYr~go~i5M=4-&{YVw-D2WZ9*zoWGW0Ji-onqPT?~=^}-^yn+1ev z!mS7*-XJ_7)C&I)8t_>syesSz0zAm1wbcII*nn4?w{3f7=ZAat?cev&>yM){`8DAs3C_QK z1!C;n_u)HLsA+UR+DUAqmJ)`oH{G;)^)1_6FP{JUW~i|}`YGvC?3pt!%=~|>y$?WC zRoXv(?w|R?Fu(vKjyU3oqmq$Xk-0_1KNXdVT-U5jsoc%Cb;~v1*4?#s?#zHxWSH7o zk(rrGW=2LuW=2LX>ynX?p^+gHjyU3oBMieZ^ZPva&M3B7@B99~TxABBbI-ZwJm)#j zpU?9=2@_H@y*)rs`}@V%p-Bh3_%2g2&nI=kbWx0&@mfKxQTzSKU7?hWFCQmbtz#3l z9MZoEQBk7XCnh8(8Br-t5A45Mw2Gp!yvF4&Lyng46NoDaMtwj4ji6ovt_zk zKY9@;@eQA}x?HXO)*CW!NcFY4*fWx22#)K+eLipe)mLAQ%+_xn@(s;F`Dh2*mt%t!}O?UEci2ny3D7`hK38Ezz6)v3PK(6j-4 zI^_F+JBI5>Cp?m$p3s4u?l80mP3c*8FIu$7@seYR*T;|}FcfdniXN}q-5U^98okz0 z5_hJHMQJEdBN+7eA>h2kF$BaJ0}CKxNPRH74v7_gr*SvOOUf+7SvZz}-ACTm2*v=6 z6#G_aEYC-pfC|)urXLxynACD*=B$v}o`a`FXb#2+@1q0wUvqK^zBf0QJfYk*1#^p= zvIN{!&LM`K!WqpuIPLR7W+8LS4xCDJC5SH|T)Gu1{cf9rLwzpi3^h=m6wqKH{!Xww zvN1cznTsjr5ssOSBYz|LaXULxQs^}eg?S?W+`G~9AJFwI^qhxPor0c|=ghI&tE=nV z+~<&M*=p!2vcCLINlW{;$)_P78dre(m~?33f)6z{4fE z`@IIesFVkX&sU{)jP@cJl?el0xQtK(nAho}1Qy^EQ_LfVXjy;f(e@us^*I3Xi&Pa4 z*bzwM@uA8KlE|PwbKsm~G?f<$_!+8xiwr>oC=8ACeqLmnX>02WXoshoEh7xLhuh<~ zi@a8^rC3)FcBNhPb-BBG0m#!SxnQiIMJv|Mh_#Eu+QkunRTJ?M{jHq>7fBHWF+`OG zcY*D}R9A>SRbe~-nW?M>oKH`JA!p{zn>j1XOh7|I9ace0&>%Cu zzPnp*l95EGGk15(^Vu(cA=Bi7cj*3i!L z?b_5-Z7`tcJD61~!q28IVHQbk(YLqjMXg=X!q)CsE1&3g^tF;Pc;9$<4Z_~e&}41Z zo^OF(J^X3)4CL|{k17L1;FJz}EX*pCL-&Yl->H80`D|o2pUBmeOoJK$sS($&Lr;W~ zL&^NUeGE=W39%Rn3DKYQSk{mavsr##Fvi+hTKh=pjOc(-jmFZZ$eTQ zWG)B-Sx|_qu=ih|mUdajJ@X)*=5vp5FLIT*UI*ajk2rK^bJ5tZ6ic<5?c|~XMJQ$e z=0@U^`P_7F6yC4kR=^6*vbaVm9@QrfwREaSARBAy2z6)cw?}djhC|oWyrpyR6pU#? z_7GzR z3Vqn|hP-p99IO%$mS_iY-lI< zp&B;!AEM+SJZQFj0Vde=#TLAmreh!fH*{BJi6_I@vMjV@C7U=!&H*r&E5t7LsXV*a zAtF3SiR|DX7;eZ$9_XX|pC?Ytrpgz**9#8NPE|R!u~n-33-EP+Hr9TdG#$VB8o&T0 zg3b*4-rH>3O8F3pnmyiwz_%|w<7bC|zBU@J(%$H6XJ44=m!&Az=|0lQ{AXNv?>gFo z1wZC;tt5Mi16B+`goA`SE|sE??GZuMaq%WI-jBZGs)-Y?N*iHb`Lc2v+Aw$J;r&2z zBUKcGwx11VT^n=PWoc=a_&(Rc-BrjBor5{SaTi-z30*Mnj=6W<9OL@;Ce&g7GepZj zsh)bb33zD=!BUCrT|O@W{xuz5 zIJ(A%mhugOyd3r}ZiYO);LnvGi5YV#8FXzp)V`Ljjh&kzendtcTUE^wV+KySXBA8W zdqwluZ5hTRHB~mpcAF8vfz#*w{ryOuG2rj(M?4mOBgMCNoH*^{;}I~Q7#;L^PIk09 z9jXBc`zqe9Le6b=PW2@CzI9wk!*K z(yggr}U3r@V?NSF4pJu$b!s zRbXch)xWo)ytH&>PUtrTTSFKcEK1hvCjV;WsronUR66KR?D9K+s91;Wl<*Eu;!Cz{ z$qMe%Bk}c~AG*@#qBanF@BaZ!+YCKEAMz9XGRBWj;p==!89s;J3I4i&7hH{hXLKx*{fL4FZcnVJT26emX^KZGG#8$W1F!L>DsJWo@sKuQdU|jJ9*V>EB5$I znUCg%{nEwid#^G1_EfCB9inuZY<_8!B^=6i^B&6bJPA_`~wohb)GnhdSqgan?~5izRjRxU{RX^YZg8mVy~KrCW@YlF+XmYDvF& zMuBBDWQdP{hEf}9$n(R`C5;?!;3>erV&ELnt{5Z1KV@Gj!Gchekb39Fm=itkdJLJccA<5o3-E$eBF9HAGFyxdq-EWZ4tgL{wYnPNi|5lx9OH(#Ne5=3+n z*_6N#Ms!ocnPtKW_aAv;dVStcR$?2vB* zxrg2=cf$A-EsCf)CcGl_JajK%^EQQuO0vNS%EDw+A{t~mDv|GY=KP@OuFBe|a4%Y$ z!PH=z@13~^UZXeNwME||L&Yj%dXrlI*{AJCd70Xeo5PJ^Ppjr2j8OTz{q^JtbO zxED@`_YZ3#JAlyZ zV<)xah!(DxnV=e$dVfD$$|xoj!teqf&g+!8R|` znc)~q9in00qX(NLEy`)OoQ7(F7`fnp-|-S=Y?Zv*euovNdd*~8$-xR!EgfTOYEIgi zv18J$Gp-amzN{$U+ja8u^)n%5&Vpz^9}b?opsLP;_au`_d)k!#&6 zhIF~`NkWmvuCjwmi%we#mIYs}tw_}r2z0r;?Nm`|AlTZ9-yUjdb=p|ZQ{n))F?n=7 zPGsy*D>()d{elH1O1nPZm330#DmW&rw7|04PK6|(j;GAEK*U_Cg}9v ze)^ARO53Jm`%Dd86}l{}L(c#mEfb$9U%d_$$ClW#g1aRtH+Up?Iy4$;rt{sCc5c6O z3N|#Hf5B71hG4D4wQZRp*LGTgGKNL+^)Pg#C4ig1ha-3K46YRj-am1B@JiP|xM_$b z*{*_-aAewTvp`&4mcea<`jW=o98N+u2A?=fW)WNm*(r|MvUrmuy- z!Z&_}pYFz{S;0TMy;k{HMd=K<6z;?y2qHk&t$2SI`~syFj!M{N4jyVd)$P~B8Da*y zyE={>YC0fl`93Pv^g~BySGVVkU+qAGjDW8XS)So4<4S=y0o4Udtvo+}Mp{B_j7H!E zy&*0((V91(=k-H|BR|*>*wKwchbQR~7b}P>1(@CWV!Xq#CMfigi#48wHBQAEj{|Qo zgT@l_^BWq<%kz`npwO-n`Q`cZR)o>S;ywB0pe;KcM-`BHOP~Ls@tZENOvPF92i5vU zHCDkPl$Fh$E1w|R((OEQx$xUdr?Xn1B#K})(#lsssFc-`sAiu+GY5`I*K@){v#&Se zR8Yd<-&8#`dpuA8IM|e|fZ(l(fCOK`x9@!(#x5lJYibWzEEY$FeTd1_g`^?fJw7;$ zV6k$Y>funB(y>zPhn=L)DTMsqff75)eVQ$n;YJuorDzN`#b}UY#zm<@q5Gj0jt#RY zw!?^I5w;St{49VC>dW0I2LQQFiu}3^<-FNKoS11gmIqV2#B5W*&zd+3XOWKso8u|F zK$d(bUiJFsW~UN06^r?g#r#LSXrzzYm_?2>^kQ3joHo{&#fdgq2Cc+TdS?j)Px|J; zH`4ZI;U05vk94fz7_1@H+|U?}u_mKd^vmJIg3XqmPPWEHp-G&@LdmM z#R9T|B0TYaT{WOkFhw|6Kr!)SmHFy*E3-n6IW#_>sD&Zel8YkQT4L0c!~|}BD>oM= z(LC(P4DM>~T5c*B_%_HQu#@B3&Hptm06P!fJD8YDue92Hz_K)p?S$$yQMGyVTVD^! zQ+5j61QZ0u!9{`Z@GP6;WL*-1t0dMfaSuJ@%;g%nMj9KhZEv1|n4xyqBh7pT zU&SxS%+vzrTm}w9?Tiw)crgjE+1T^5o##zeoNc1=%$b?;t7@VRxe;xSb@61s1Ap~( zd3<<5#wfL8ofC2^GQ=UELgL!nol0iN2zTf4JY>y~v7=lW&IenVyK~hTLoryp{{nXO zam>Pc%)%0Uo~#4&F$*FxWlo$-30;<1%RXrrF3-x!GJacMP*Cq01LIt}ulb$wm1UWe z4DC(tZ$x@5)R?8{^gmHD&@BxJHj+3|C2@yVhhZ{ts~TLo8<4oOrl#fqZ_Ro%oOOv? zJXYccg7#>`2va;lk5HJcd%!7LygOE}&jD-x4A};5O*`{q4y7;+{a0++VYA0$KKJ4C z>!1JNoaLq*hSdA4Mz!{tEkBsE^I$Rj1eaK8|^;a6}_`1`M8KJ8H@(uZ~h68D$iOii-E!?a?83Fn|g-&};oOO=$_6~$l!Qd<$ zEM8wgjMC{1kQN3|-wG*wMh?|V$PycCh>d|xuMuI>VZ6UvE-3&=yF(QEJ-q|PV&I(T zT%ZINPJ6UE#-JDQxp+g8-g%8d7oBJ_4okbzI&s2CQ$naG0LN0Sjt`tYb;^CJv(w}4 zU#=M!yaGdX66yJlsDUu}+ZUTutZh+a6vyv}kP*VW~aw@bG( zj1-xGk=zC(Hnlm)xfYeSQCnMn06_j-E~nz5nT}_mn2zi4ximZj zp^D@u5G!6;BVktmHl*Skksto6$=CHEKWurqdZBF(9tPQvS!paX(s0Iv%kpk7tgb$3 z{H+YLvI7$Y?hNpcGhaTa%Au6)U?0o-s9bZE$6H^q@wG8Brmk$7d_o&S8F;XIdXK{n z50|MyjL$d6-1Sh|koF2en|<{wWz?IUn>!b55BN8y22Q-Jk?p(I5(4W+{HiE)pX%9N zC$N|ottF3NIB07)c&KO3#QR&dQ897)_++z@hYxf3WvO;m0OD>^k`vp>-*c|t$?4S3 z#G`hA&)*;D?Kw|HB6U zZ&S4+4eANELj~m4=|0{GuLZvnwhV}D7K?S%Fr!0kY4Le|#mXr_zVpSPY|`&?@icjO znxvoin@1~t^VzdYO5i((qWM4Yo2%BflaHNz=NEsGqZ4o?`X=v+pZA-q;5TnyQN;bC z-<;onHH-S6xXtwuw>g78oc8ms^Od&LUvQhlS&9ToKjS%HIr^8p=4O}6{PT|Ul?t~^ zws34DR*qt>^;kJQR_?r4T%BJ&Z}SVYAby1AA!FsD3;uFehMZ}kB{<~%-Xbk(xDYsoFb_02_Bl07x31x2` z>e0rUvO)vT9)*>(U^_f>s zw7RCjQePHo1kfDWw1J$raf?|NEPA%7*cNoXA)`Mlq%5vR;+M@CRji?Xv7@%W2|=2; zMEb7YwQaS{2DxWlBH;7K4t>+!8SvM6{oS3tVgPV;BnaqZYDpDjLDu6dP7DAinPj98 z)cioepu@hwhm@W2D4x`TC#481vV@F756qPhUUWNj+A&BLI~vxHJ41_foxSm+tz!~; z+;#Ay{T|BOANZ&Cbi&ZDezNwvmTz~%wKos&(tIpTz7$WohPTHD!CtS|aIF8dD;pLt zr&t){J@Rs{EGa=+5??;jWB9fFmz69tA1==8xd%9#d_92oW^JbV6kJwkESWPP=j@>) z4%c2N;hCHTQ}Ha1_y%z^KzB;=C#<6KK(-mxo18Gy> zL{N087Pf{@^ETxG!3B64KbBAs`aS5pJ|4Uf!D^QVg2r-tt%BT_86?& zXzUZ>*AY8wcIc*1mfmFY`SSBCDkxbS$Z{%x$Na36hXNU!2#Pja@TOm0?_1v$z(XLTHTG%(H2Xc%5h0MadtR$Hy7#reTR& zLe0=5ZJ~4qHi@Iv78&MLPy)^f6h*Hi(`tKt_AU{c7O2McLRF8 z`-7La?D@P)tHpB>M8L|nN>ZZ14{@n{?Mqv$3#Uvb4|?X+hLy}aRmLY8VcOe=6Yx3h z@9(-^ufH}c?=PeZJ||q|^%{xGN@NmywG<{-%Z5I9;0rTNyaoOT!Z^DZ^sbFyM(QbxQKE5#z>> zPcz;*+?=#^l(b4y{Q z9Vm$Du+F5Rlb=J@(D@he>|y(vjqZ)^VO%%hZLyucDKmQu+TMworTk-8qwOfnY&L9K zOZnK?U!Gvj3W|PQ5^7AQnoG>Hh-AS<|GT+vmV_0}%`1Lk!i7ck^^1OC);U|56D_*F+qG#^Nq&BbOp6{(4nVGp@1Ijp^%%R9{@!x{`J6uC^10nU zd_GKzB>&I-5j}}Uqt(ji%8}1I*&FeX6%??u)>XE?U zAiCNUe{!C{6zb~cP6;D>7K9w36;baV?M}$bO44g#c3&a9Km1Nq?iv3 z$CEZ90MNpvCl0qH``Abe$3|HgBz*;+NZwfu5_=Jk7Ww@0)Ld9=12D?MVuK7{#F@|k znHi^Wli56O1zQUMc0Gtg{%==Atca);d4=@;Omubi`t{2H>T1U`5@)f{|CNg7aTUfg z5o4iKgDg;lm5he#4?|JLlO1dewu@DD7lsuiu>)tu!tvU!o!e9PK_*lDC&TdzI~%__<@^uBF-&YS zN+r5r+gIc6ExLEySKF$pvKbu7+_vJp(9F;kptvhSe-ySAuyoQrrMysPSddXn$IkyS z9iNAes!HY-44ZOP_pLTkf+xxt*ws`l;M_i5e!15HQTU;{r) zQqaFp2BxizO@wb4U_GyYrD9HItCeZlB;YhKp%U={eVl5H_^!cwi+ z%Q0Vs!ZTE#H?WhYe%{8uT6<4^^~Q}rE4rjhPt?ljjI|%eP0ybm_u<<0>+{L25n2m| zbxmjp0GdNWcXDfi7|rAIkmeJ#&b8XXT|YLvm&g`U`u{!E*w8I7w74u zL3+V-iAi7?(nV8Hf>gpkO&=MOl9%@p%)v^`0p+}zf;pIoIncGVG#);F>U5VU;GYIr z_a?ZQZbaIPheMk~59)%Ao1T64+09?UP@GK(do;m>tEWz#mKe+;XRQp&QY;pK=AVD1 z3>F^nePQGFFWf&vQx4f+rCzak!97Jq^QOz2ZZTrT{=i+!PD6dGW^S(F5%R@Dg2%sq z3Xc>N7G`r!&Z#LFbMo_s&*KYlc!KRTkc!s;LGNpz+&@5WV;ihM2tX5>->E+Ii_dn`l9Ev(MmHe~d`Ysd#j&fmnZV)QXz-GZ>rxuo?# z;VZ|xtAf43L&4_Yq0orXT;2yekDcJQ+xXU2n2COt8#uzYgt)vsi{(G2J?g@=J2u&e zcXg@NsH}0O8_J;GfG{yFf+)LtnGU&y9Zy~~xpuw9g4sVmp-~syZ;nm!O#Tit`6y=c zX3XSt%p_rM#r*urO6VL5LyzhYG!A6kim&V>SIa+0lwO!%op6=W-BPs*U)vj-v=h?V z4oTgxXi-CJ>#GsK?VrWBS}iyKC6~P->ldZsuhY^-8|3U+V63lRjGS=&h)CI1?1oWMu9s67gkb&9VwC}E+*Q}>0>0WvkQ8W&yi;Ic#K-D zag5bERI3g6I=^rIzWp>zszCwX=73MD7V(D1Vn|yRzD?+aIE#WYBJ7;(dlJ;U*>gy4 z<#r0B2$R=%8N@$;w@Pe+4i*{->1ttfl-GJ1?m!Yg`7Nog0BJ{n2n~=N;oWi?8E5g9*<$jak!+~R6a5UGyo&R_&Qjz;lidkR!gWb>iJ!*V{kJJ z0QPiY-L9jUIis`8I^DYVG~!o*hqRh5o8uHS78j-Fu&z z0>fD3TBhFIrWu<#YZaWu+?u`Fu%ACF#KtnfJye0yt%cVnAf72HE$xmx#Cgb3S*%RF zufX*wqRHr}x+nB#)LX5sXM(I~*RCRmEv)&|k$($Bh{arvOC#4L03305v_yFIx0?9vma2##FJ@ zF?VJdyLV&DzJ0*u+Pe-DA{Zx6HagxI7i)?}^78lut?!&4;frzR(bj7&GsXr{%p1Pz zvlO{60zhnlSIrAY@=$C>H5|IABgn-iD4UVzCGPCG(s6(Y@mg;mGR6%Adc9uvu_LWV zj`xWHm2sqHQ}*_7T;vX{+fJ<80<7B~v2K}Iw;VZ_-$L#BJ)pMckDh;W zDr|rAAV?_J-Eq#H2fyzh3Q8Uydvx#K&9LdhI3Ztu)oni5=|fdZzkAn{(_j<5JiI|H zU}iT#6 zu~Jd)KH<4W&#&^}K~=C<&k8rX-&>cBkoZDJt_&j(*?X$Ti}3aEOf3CIwhu@#8QhKU zDXa@?P!>HWxSP217imRBk52=z47Mcss)KQ_OuhIT>^ej4baYaMc#>3L6qIW!;K3vh zLy-fxal+(jg~jT&ZKZ`bjf%Ew`%fQjE}Uct1af4Ky?OY`ccp#Cc}_#}Oo;YVF5>c?7 zL{aPXzsooK>u|1q>Nn4OG!J}DA+;A&%jQ}9wHqC~ukT=72=P8aunP&*#@2pAd_G7AMI9%XjyB>qSo!f+wP zkbBw=BZLHwVn?YQ`q`FILK2bpBaZ4mA=GcJ)^Y2L$Mg1@<0;cTR zQMb&SKmXuC-G7BcK84w0`p2~G=Yj5i2Uet43!+2Q1Zzeh;A(e*zouuMP<{OsRB2h}`kT z4F5v-0jtP4FBe6?EQ~`?K0#FL;K|phHL*jIjK*M4ZA!JICIA%P=|1W1(nV=BxDgdi zup>zkRvvf3z3jj+5*b{sR!8Y$J>3Bwh_fIj5im1>W1T1~o78{k;Gwhnpz(?c>Eo<{ z5JIaWH{$;DMhZ>P=@OCe3PBTuMKzd?e~9S19bW`ZBS(X#ZpzF-b`o6T+MeXg@6UzF zPQIf4IAv_wwKEHI<~*K-3P%O(AdZ$H`qo%3V2?`7$ltYV_Uyk5{d+DJovx+ACx+H5 zr-9RN2}`?gSrrz+x^G>;k0c&n*>a`q)MMNd)vO#0OTg7Q3Av=p|WyYkP5gci@R0~Y@2O;XDS{* z!MP0w5ON})e$8-a4v>dmv#rTR6V2{_*zNYs9jKRq3b37f-q`xaKmF#3GnUVQN9=7Z zcNI`2n?ZARaR2OQUz7W5+jz4M2)2N)rw>|-D%R)G8j^&LLq`rCb_cvd;;8gV*QS|_ zJ^i|2aCk{vzhC0|{5W7VPTt?s2eEGe0DeG;RsM6nfUn;1^TYJsKl zdIL#gQ^pSGyar9r$<`xBzyA*IcQ{de(u<_+ln`mivfCf9j*nn(XJc=ZW&2v%+kluY zLH?x`+Nvfl4VDn^-{H2DLx;*i_piDKoN|P21`^ekKs|sWg!AVjZkH2kicPRu%VPmf-`N&Gr)FVzrf(H8nHj zV}LA1Nt^{fK}C4ps`_o-zz16)8#pD7U_mb-2MtO5?a*T%&oop`RU{c^gclHkAWkIpUg{K7A9XepN$jcRc7ce~L_33Ld;h3+*&x*tym^#F@*F#;vY# zl)x>{LaUTbSvoop=so&X)0am9?HMxMU;rG@2p46**XxHXZGiB>s9sWnG-2h+?kh$9 zm*JzvBGS;P7riH3F4$;Wq}XQM=WNda{1}k?G!Q0;1Mu9_B9G31s+3oV>?${6g;KFX zgmECOn=tDtHzt|Ht)={$HHfjD3u86hQGE4!Mn`%!v>b;$52QyI6d{O2dW7+F2VE3q z*vU=6l>p%JNW5<5w)t|nMVN%mwk*zy8C$}>LFkwgD432UMsl#HV>YD5JzM6+ZHv}DfAhb-s`jhsy?zmBwk)3t>TV)=r$;c=xvqHnh z`ETRgemko1h%pIqI$bsnpofJQT6OS%Dw@S=g4$_8;rP)hEL?c&ZTZ;l<#1b5Sbu#C-|ez zboB(KBwi(Q!S;5ypN}1pGQxqx;Hgky&=tCc>zbbnmP%K#?)FLEEl}$=ot}h z(^b#^jm?)>EA|4nIbDkG^D)XpCAjwDHf^do(xc0mHEY)7*q+u8HaT{vbqUB2g0t8#5M%?PP*0C&NH7HZ&Ytl} z@u5)rv6Fo)#$-w|C1_ZW>nJigz_*TVPZ~sU;3=r~NY;Q51SD$+1zBLgIlho%q7nZX#OdVx3JD$Vc==6V*abZrf6l+g%9OVU| zx~t={_8OF)+U9gl+>1;{v8A7UUsv-yW_Epb?cv=e_*KH*i4zk~wSK-CrmR;RTDy!B z*(QMPv0NT54Yok6YE&KkZQ{8zlsSXrZ<1@o^MUd37%0oU$PzfbK0L`>c_SD;a@gXU zN8h>XWdyZ4#d_K2+7-85KP7KU&Tmle`(N5Tq+?%phU^mvQwbItq|rkj=DfEoq|L3;f2etk7QsVCI_h5Yw&5`FHTuY!(S- z3dO8JaXfji^Lb)bHXRni+`01~QCuBP@%}W{{8IP~NPK!zWhG0V3RPyBnYGv8^!T9N z@g~k;(IAN)R}XNZv`{?fNYI&#Ogn50un$O^)(N-63BQBX6dST|Ik6*q+#p0)@uVe@G|111onYR?d)?I?`gX zqzpG*b??%725nstNijCnyh&!0YeP7%iuz?w+K4OXAOPaYsG>TparSSgj$%iVsz2!W zA+x)k`?f>@__0C?EpG;3P>#G3A4+GR16QjU1+ED3p=;P?yNv$k=S6Xjp}wA0q{TUM z%C-OVgALjhi>mAEo6e-qLk63MGaYSewN7UmqVoFs5t;4pKI=Q(dZ?{i zl+;#BT&R}`xG$i&XDOYEit-uqfOjLPLq*A5AXSHa4#e$?oCAOrPDU`h4UU_EyMLnaG$E9ZZLQAXCvi_o$2z?&ha&X>QodprmmN0e9 zYU8{LowQ~E)@S1_w5IY5?&UeX@~1$6b1P$~*jkERlcRHSAF4586AFk#N^GnuOe8Q0 z2Wa9;a36sS@{;^&CX$9F@}l_M3-=&mLBlGdmP_8?!YC*z`bVQ6vY|T=-TcBGA~AUK z9a#7|SV5SA=q5{W6FG=C{3tdd2(xSWk?<(WNa#N2M>6<6G9}S{h?LF`1~(yMQsyNx zAD0}9Oi^?XguVTEEJRf2Z}Stg5*dq7K!im%A<7y&5TdRB*&T?$=nh0-gYQ5z_MOGNRBQKZQIN7$)SW2=fM| z@5o4q+7(WC3F=M`&*9n0AL1d$46x}(~O59BBc8@K!# zJJ1fWcFZlf{T4{#ve*Z?;8kcPA3#QFl6BBStUBhA{Fo0{m#==|6ZhQ7m(3u59+_L; zh7AX)baZp)W(@nR*jYR;eS5`5O4C(|`;uJh zVKu_S$*Ft8`VGRluNdxWdK(fSKI_?Gn;N<$oH#2Lz~R{vZ`Ou^75LIHn}bE<-nh5AEa_yYd~CkW1K;LTFO0wKWg zAL{N-P8ka)f+az(@tt(Lajz&1Luix7gO4HeYy08Dhrc`4Aqic*s0sk1 zw_(E_2!$_#+hYmL$Mb;=yAx1eV{os0b%aLZH{&U}nS5D8*`fK-wwI9^XG`U09?v@) zrUnnt6%qj0m>*iM{;;d7>(meL=Rz~QJtPDVzz_+ozv6 zz2KH>^p0mVut0^FpDdjLXuPN|%n$he;8%|8wCVv^ZGz@uspixeNXTcpIsgs<=9fnf zrJyg+9{|8y>+_%P=y3gT@?5|dJe_L3E*dYEVAps(vD3K zj1^&XK~hAuq~@?Ouy-81Zy+S0wzAuO+;#kvx0gl5Ml-cGT4OhhDxUTA_WAw6e!X4` zm!8EG8>`oa&Uw!Ub$A3A@(>CpBHI=84Lr_MJo-=!GvTwR6m+v= z6kr|;a}@PYwIJQQd-rY!^HMU53bqi`L%F+=>{5Ino!eDG_S_xpB?Lzg{0ML;p#s=Is@9a zOuDLBKHtesuRRWSys;BUYT@)#4IuDK3w`a3%k_a`?3|}s+pGd4(J@?$te1VK4mEuE z+UD1GHZ|;g=}DW-w&tDsuR4QKc2)F@0AF``BO-x*@+QIer6Ri=Ql}OimJg0j&F*eDR zr11vek?luvy8$MMTnH9pKXg8_9K#`qGSIE9-*7t};+02nbYL zD)T*^MbQIEjv`I$ydHSp!Sj0HBDR9`KnO;F2=w6FARTZ6X5j_U-@R!6JG7q-`it68 zdkiBPe$}wHY%+pz8=lNXb_7azFh#WOINQqT;-hW;q7Z!@M3mqgB8zhga}@^k1f zDzEo=^w;V zs^W9GuKaVDDAfv4COh;CrwzkQnI>3#wY5Ojyu>=V7;v;0CUKca1P!w>9UF0XTs_H` ze$yz#-J0?j<=(s?Pd-c#jf@9sEkw{UGTR%uA#9hpsJ50Z!pOqJr`5s|d}0(4C#<|| zb8L#wcjVAXcAh5HiK#<@so55$N;Rl5BO}9rjfm6Vv}$|Z7eDw_NM7Xix|-_WdwJu= zCQ!V;}k>-DiwL4Wu0rWQYp#9aSbF)B*nwL;)bhX;NLaCDO?z#=J-j8`=Qgx#Fh30xRFr!M1Fz+ zwbnSoY*tHre}BNP4h4a=#+CseQ`w`uKeTtaeL*Uk$E@(FDI|)K!q6rAr=J4phwvm% z$g~Ps1~hshpAl*C68Mx8br~es9i4a+kd&+`xPzR}XbR|(d;>S&vs@iAvOg5Pa_iQu z|2pLzFpixl*AM*js889I_uhAZc9NDN2eo78&Y3;R`|aDC=Pj6-?EU^j9Opp0{6$z@ z$2!T^o0cB$I)_cltFTD_j*#C!P)-osGC3KX&zrs=Om*TygCRbOP75nI<*;OjurO!J z;v9sytYvF7_a}S(tsicw&ciAp87Wx~1)Ocq$4#8dO zZGV5a!;}2G9Ef-8+22(UOrEq5;CpQHkrT&?0|C3r+j-LGn-yk>v5#boJ`OIaHGt!( zngKhIk)YxSF4viUy9O+h8&Cn7hXC^4_WgC+%fct?$dVV{-?y)N!-fsjdk_3@#^Vuv z2?>c~Crz6_|DOCwlWuu9hxP$Vwmx+0r1T^aCu>mp05{Qqbb`os6T<2y_a5))IOAtg zF|n~C&}Zks?Er8zz|zavH5{)7Jt8B=2Qi`uArv?U`UCh%2F zc--acm0}4qg`)>YA=x`c=>tV-dw zGzM7e%N6dUI@gKZsB6NDZhEb`|4Mn$lgEsWah>+FA1%N7&sVx!K0(BpBCo$gC0;!V zae_G<12cY|OFy22Xi6*$Z*O37fJW4k{Ob$h^So`;68UEv10nnxkeOd|hfL(FK7qMo zu`XBCWnfW=%O1NAnX6GKxI z?H~c7g9z{0@q;KHgx>L9ebe!?-QAGt`#Ku;RsqemBHoXZY(vr}PhU_}G<_6&S;U3x zbZPFMJi(;)gAjH~pf7sH?#G^;u*Ir%Yleh!Cut-J~hC*KHa{HBGF$n z7G?O?tX=c`X94)d>H^g(OIMyS-IG@!_nS76S>mO^PZH zq^XZ1FtE9K3gSbr30v2vN7*VPwDf;uG{e#g=H`usdvAy-(1){)H>dv}S&t^ddK@1= zHO$p`@XLJ-jb9vSa{X|k>s04)*Z+wZNwE3Kuo+Y*Kx(9&Bi&33@e9eCeXZZMw0zrk z((`|2Rv(AGr(`FJ*sLyCy|>~7BYXLJl58PhnMum(a{Pp~JR+khcJ`a(cKqi5U8_Y( ztAdS!}zF+TrBpDNDo(vXv_X^@Ini?7@hg{GyQ}50Kp2#@7$(wR7+j zMr`CiYG*s&E2kgSC*)Asu&4A%609yfVnWBBw^ipKjM%DuE67%j7^Y%kp4CiG4+5Vl z%+$&~ev4oK5xk=SykjbO#}r~p+RdBEg+&$P?u8Lxfl$`Gabws*GxYs~lk=wJ<&Nde1-z`{>kYbvKntz`)2V?Wqa<37>tD~+ppz10&btjgG6^dCwqJY$-I$^j}>~(^dT%9Dw87`r#;gT z^aKNEd%O<)0G0mm449m_Cqr$}3s5F? z`ut@SgyF%~MV_lV2j9@pY3EP6M2T%Al&ev`ZeUM3c$3X02h||?{DWctF#m9#RbCOb z{&YFuNZu1k=U*?|nfHYPg57Jh1}`_GoN=p{DZq^$b?yd5n)wNuvqC)!1$ zzqmoOBaake3kn4&gRPVYOa3-_yfBhDlp)K{N_U8i`20Cbci2uVN}VgDpma`m8T`D| zI_9VPm+668r!$(WLA|R7_da;O&i5|3h$yJBLKTs&lYZQCFg1nOhzJ7%G(pacERY1+ zxYU@5KBB-0Y=UbBTFU+`-ed}o*@zjlI7&DW0Vu@Ai8O_71rre2-TYu0;a#{1cDHf^ z+SlMAlp&OM_uyw8L{$mlXHAeh#j^%~L{pKTB0E5SQr@Waq?22r7nxllW1V7j`f-0W zw@?M?IjJGdtAi1HE%`1Ni3p-frbb|5-0IVg-%va*_GN%WITG%#++Eydu-Ko)@&78s z`OWzLDLV%-e+)N=`zt?h-rX}%w(L9nBA@#=*MRHaFuohux9kb-ZkEMcB+ZJZrWK28 z4s_e2yARYXF1!&6|4p+hfoFY9`O~%?0ij^`X4aeFUv35e%+O?=Ev;@M--|&55Xo>pCH*3#j zWifb-Bxx!lElXtt_*|@N0q6GGSu6hHV4j&s(`Mij02}skQS2RTgVB|e#M;m3& z=`9ya=n;!8TZC4TbH4@+FFyBSvyI$=dZm;9;$F*?UP*w+hPJ8nD|f4$T9H;4ogiG* zpjOOurH$2Ztq`Jq@f zdQ{#uV|LCT=MW$+jFwtQdcC;y4z!lp;Q4N4A!5)BUApIzaL;TWt;_kIAxK>4dGI_% zdbR<19G<6TgPzyMAWi&IOG~8X#EV)&sJPH_FfGx!5z(F4twc)-(g(?IG3JXU3z|hP z0INOw&$YTR_VaXnePjfYGLRQWKywzMMQRzL=4@6USuNyyCSp{INb(f59hRdmy;ghV zwZb`l$+i0NY|EGpI^@u@*v6e7@%b|ds0kuBI)#4RRzAJBqDb4!i@L@6b>V4?u=7aI zq`2mBcv>s?SX|AwqmzS^+B%MX*TM|FEpO%E+?f-4P`|c%+qSJc*1uY9?%KUOD^z4d zM6*hzI>S=81oksmb}%oP2O#^3&||`yt#g;n1Yme0PLyh# zAx+Sslo*T;*#>p>cAO=zARPX2XrC)WHU#A4<=GrKFg77H9DXymF%jh-VSWkpi`u{m zVyx}ZIRjl53(7Zf+$Nh2VGmn9?vA71wFDfxfImHj%EhJtG|30vd(SC(Km$V7#5G7)(th$>pRc!b|9h1$H8nOi)l5a=$9%+^O@U4L z$jtPbXv) z7ETuX;KVeh!)KmfSeXCFOe~O+E$;<%R*5-3fP?xA_NsP4X6yUNB;bZG138O%pkW{= zZbprgJW8P~U$bNWUdIs34EwS{#L9i8PqW{QuNc+&$!{CxY>i)AHd<0H;MB<_foo7HB z58wO9AqlZ+2_|b5DsJ<}q0#W(IzCi5+#IY7KDRmM za?M;bb229hd$L66Ni&6RNA8sX8*%(gs4yve*Iw1nH&3a^4yFJ8G2i5eH>Ci=XMFb2w!;*j$98a?gx z1nqjS#p{c|5d~pZR;}9Y)!i}3~K$T@)(8k7Tcy(vn(T>iJW1W7HPaHq_ z`s+rky{I>#Z#hj~+R(sR7w}spL~izIo(~>5gLgsy$rh(AS_~oV4#qS96GX?5SnEWC zVQ31L!GatQfs>H5Px%5)iE+h@dqrNipVrIPVmXR!vW2<`Zxq8XjABU1 z_eT|LDE2U_{)5*lDvB1w9e8~z+zP_8OgtC=ap{~5_1^=X;fuOb)^H{9 zbVF5DX^v97L}feRF%0`{F4T=(Ak@_fOBY_B!ZHnG({#i1$%$Hnhu1i>i7zB9&aqmv zii#FYxA4AWpT4=}<<+Ri_$ZPwUJq|g4z!*70mE7rdR$|Fvho`rpZ>cn=5#y>t0~UJ zXYjvtTrkK3002+iP=grY`_G>0JbB99c_tL}oa*lJ(?&;VIZ_Weo>2RG8C8=hgC+x> z>qo{hr(_NGc6S40(%RV@6g7$Flo6%`1G0E(iF3k5i!V^76DKc$2Uj6vIE*&=E7t4@ ztXT%ujN*P#rkrWv3+g&tSF;H|$VH*Yb*qp^vb_A&+9PKH6M@MZ*SzS;+HWsgh_9

5)!7tm^H4B++FcJW`>z?33XII6&*S_qpY_r|LrYzEL%YE&v)hH?Okw6!%X2-S z)Yg9D$z7fY6}=sbBi5c@z8p)r3sI{OJ2)3|i2elyKh{>aNL>4g|Btoz0f?$f`^V3{ zbLS7kFb*){h@*{)MMlOJxn#WUfP<1zQOjFwk+DX_wye3W+fuUbowyjB4fM z*6(CN4+RXhdXVip3!8XWQbl25h4lJm0@J7vZ5?AuNE`zPPc2OFS_EecBL~0Pz1J7g zFm2LBh!W8w2?;N$ge0@RN&~r_9~n7=U@;U3hRXn~UOK%7{%X4ARhp3B>m4|Wcwxj7 z(YkLDC;iQF-$|@$fICW4O6W+ZW zJk~NL1;aDJ5^y%Ay)OtNPDtUfQX<>fR-ff(%{Y6>j5> zo}L{$c6|KtK4JV%Gnw9rIG~;?F@d8;io5gajkX|R5rlLq@cz5W8%MwEqo?S}KN ztpH4CXNvCo0@tqp?%Lk-t_}I}ylWGUsDCiiQ|QXB^R8<=d!W1mFHBprlsj%a??@tG zrMvQxqw)xi7DYXswX&4yqgV*nV;OIKn#=%%R@DnOCow| zqMYVRUjUXQXu<=#zB=lP^L^gY`L9DK_TG2@Pfzq9A=G`*o#)r827fwyMdhetZqZEl z%_M3;2}?xzk(ap-xlXzL9iQ*x(%F8tTyr~Y$pzP$3W1JYjDpu?Tshj$;9s8(Z25B% z51=t0;(ozx;9i8zh6X*&;Dj_=#GZiT)mZRG-eruPFx8fJ8H(BNJgT>)FU?VQF4eD% zLSHTzv68PUKHLwT!papq5cT|2|MFsX;2qT2k<|*#xP z_q;4Q7joh)`Syqf0)x(|1*P&F3x!EeQ$d9u4o5;}izycHK>jYP3LAk&%ZHI6jtRQ4&;=7!{OO~6Jo~=s z(MwTTf#Q!Tml##1aA2lMQrC4KI1Q`z$o}p;Kok=qh%BK72xC$tgWI`twp=&P0q=$v zQ48ROY)rF*YkQ1rGD=>T5`I-1^yxFeWZ?(^!#VGS){a}{B0!)PlUu|AHtsegDn^J1 z3hN5DTi8KFepkQ*pewvwhlE-&R}|)P#heSu_1}=z_ivae3I8uBxK)-m99%2{hF0U? z)oe5B$vaRg=`U=An+A`pX>0`Udy61=G&@BI%eZdjj8j9~97HmAeEEIX8rbmtEX9WtN=zB_;E7 zEJ%OwQoRKA%q1uIksV^;eU435d3Eb~^cE9}2j?13?1&!TLwnnPAuggnik}5~$a5>@;}ma; zMVQt5F{`BGXGJBQF`0>0 ziWT9Km_2fz(>V`x{!57KMdq2aM1 z2#|?#flE=_0O@*#t|AY9ftO!>onsy>7#8@=&E&G=HUsi{2QtkS9&c&!W)r{WU<2lK z5R<$}Fj}K5I!#4ZL3Y{%y;G|hce$e=JH-g3Y{0)km5 z7iA`%vkduXzSPa8xh2;R=~bt}vw!cmdp&*MdiQ(%A!l6hh-VK%Ku(>8#q5}8xhy+j zjF~#tpusia3d`WqPdT_&I1P}ZCfg<_8BE3)jmileAjW8lL*6aS$;ww{-dl%mynz{* ziy62&x~^F5T!b7Q!&*8CRO$qV?LO5SD89MTp)G*_dZlK~%S}y9FYme)_leq_a*M&j zOUEn~E6_^VM-7=8=0p}~YB#sGHouS62CKI)Yu@zaPjeKusd>j!U7c==MbY>e7N6)8 z660Bn)}@KHrB_#bkmN%a>(%QHCQqL?OL~aC%l(<#$i2?h%PpTXBGyOYxTPGmBJOe) zV*Ajm$052tg?BpQY3@xd&v)>CFEj!xwpux357#WW-=b!Q2}w1G-!{SyoPy@i-kk?se0n)jw%~7E=F-{9ui10LT+K+F zMUp4kSb9xjc*l$N_5bi?X8JlIqsuH;sO#mY-6Q`(xMv#QTNnL)%+sCpyMKUG-q{mQ zyrxuo+c`!br-dV}_u$FUz<^Gp;+)|8kdB>jeFo0qG{GfWH!u)F88q*}8I3khkAsW? z{+3{yGC4^hzpoCz!DJti(LW~m0xpuZ5Te&?_BEQ}=D*27dLf=0J64rtW=xo`X8{>@Qx5-Bq z$**^e9zQDmoqN2wdT`KL7NsPRW z?2+3>rC<_@$=~Q~#5`ya8hUxeA`%-}1{8dNbIVJ085kx_1brt)ilXm#jQVX{@JvYj z6D213OpHXUJe>9ab|!_elry#dr)MG`rSp16_oNV+(!0e9BZ7O;dAEg*$sMJ4qP8FH zpF(iTUA0``t_r_9QFPs7%rAIX3h^mt3SRiG=6`pxAHOS_zeVTFpXma3weY(WeRo$s zpadE#g(Q``>bk(07JUCqW6tT{*{FRw)7vs}%brdkE7l+FBBJ*d8dU~-lH{c5eIl~k z@NqPHe{{VOc6~0lL}y3W8ylbn!$evs=e+*t?9n(a{cfDt?sIzA812;$=={PQQMLOFSV&D*Q~x@QkAH9On;V%FUKj2F?yLAx6@sDWI-P7Q z3FD9OPpck{W1?2kMD(X}V& z&4U9(7yFDUp}~J+4Qz!9xcaZIhghG*m2gzqc>!ubS0Ef&5bazha5PKay%g54n?rEe zB0GCR_p96Pf*aN?w>@fy$-2au1J-pM3DCX|5^cWqkEu*6hdZAmLRQh%Ng%xsLjXmRTqVkF>&7z9}EjY6-2+D z-fzAEbULUL%pvbS&p-sBbb3?r%u51JRZ?!U03=ozla!3QWpRMwLnss;QR$82rcMuq zjOH=G=pmOI60OEiDD9F7unOUL%-7*zaV(!S+eLd!mGCff| zR9cVgsW)Ynf51cTOK`zF0ytn6o@Ke}wGh#wtH=>}~!&JSI zf0J#8W;Oq}vthztkM^`s@TJ?m(Ip%|G#C+FF-PBDSN-`Z(g}#z%Y`*vgEk~xRnkA* zJ?`tCbs#?J=aB9iVa@16z)CO7k`1gL@a#HPh5TJB0HeQ-zfyZrSDIMc^|XRzP+d@|LU>qi_k|lzzzHSNYSa*u7m*v4&Rh}>NL~1V|D!p4)*sS@DIbf;hG9Bag=!7!|XbPG-zq8Y9hNY!4k|#o>pe1QrdPi1@UZ+0U z+tK{ED8ih*x$~RBKmdl+i8C_i-C0~LNfb#64R|>ZIR)|1%UrgQS`(uOrojm+wHlSe z_W@9gHyDP727@|d!bA#OP(f4Uk(w=nXaqMzb}TlvPNQBnji^fl`wP|?uTu+Z!3IN# zNpm_F#KZ`p;K2U=e$azNS3{nQ<#hEG2*Q=;VvLPr37CsG98Eh8<+^|;C3JUHcXeg} zq3|x{zpTWLgbgh=n220nQQDRI%KO^HL5C%EeDr zcQtAS6;O9q(z%f&CDMWOkA6)~<4wv{%3+9P2Kh?uvY$ZvIage*2_P{n!&O%!1*?ZC zSC&@G{fPx_#WKbEtHpI?Un-SO!;WIpG`U4pz`$(y*zZQ2clR7#2IWqWjn~;|F>N;eV{SEe*N_hJ!dgddl z#%*o2h;xC`3A;DG|E_v@?UPSPi3voE^dOi7BuSsNA>ZJUuR7Wq=fUP5ig>tG=8yD) zMYSP|;Mc5gj;s--veuFWFO%!GBu5juW$XDv&!_yp%N4U zcO0fGl8JP*#l_aZX7u*CIKCgYxsxXc!pPDI$SQ{K??=7*qsPGpp5#W(tAq zTb-QE=7iTNv)TIlt=7rXbMjb|eQ7SndKyM*JVwfbkz$$T*P9ht%HLm? z`KST6RRutwiWx*L7{A9ct1(_w>+>oca|Ml8I>{u96E+90D=RCzv#6}NxTFxDlDzK_ zTd5eIe&r>xfj!$$A);%?jt>ETwEoK%U=x4B`XSJCMzc{GJ{>gvw4kuCy}j3KxSncU zP_sLc7RP14_7ewdS>#k;FsyO`W0P1nO;Qi5))vGAeA#Zyl8yPAtReWT@Qxf91@|$p zy0<5gl3D72XP@F*SC66ti>c^9yWCz@KbU{%i5(24E+?Ot_i&W&8XnFt^#SFfY|EXn z9m|e@!fQP}aMp{DGX#OI!hL2;C`h(d!6qed-P()@?>Dx6eh@`k;IB4))(v;hzx#$+ zvu=iago~Qt!JB7I(`$I{_|9#wBbUe$O1r|X{;TxX6+Ax-6z(*yiG_4BG!zO8#*~Xw z5X=piaPTk{*dZ@qlE^=tFmCCs@dkr=yk&g6PDPQQ*todhF<>3XQD{-Z@4+LH`H&J8 zs8NkJqSSy%!pu=sTr*}a1~WGXGZ$N3(%f8J?9R-rW?s~q?U(GFb-7kUASm`12kVB6 zR)gB4ja-Yv&XwXP^)A*X6QUrB4sa6MFQnBRT#vYP-LloOSu`SD^n&%N@H0KGd{$$z zMYCe@DeD;cFzJ{(>Ck{oaY_~oJV@KQxU1BYHz`I%^J)9MuUzSKG zpxO?wMK;MW0WUYFvC^V8q2ExsbcYh|XCobY}u`N8=*VTIe_6 z{_eusAa7K%RnywwHf_p=AITq#kGoyYs+B8RzD>Mr`t;Zadt{b;>-C6Q%a6=c;kI9O zCKe&ad|#|dpKwK9$A;JY&DZ^+s7US!b%PHC9CJa|pW&9No#qfWsLz~u?DL+TBWaG7 zmbvoRO5aN9GX}MjdNl^*wXe71>wTNumWi6L+F#9qVF%7UF2qBFzvGizi=r3tr#c&J za-l`s0D++l^?CoKdA70bYxG|pi_tL=@C7Cb+ptRk(ivA{H3kBwkOPYo45q*_|A?S7 zTad{)90*WMBTa-PobZpFhNlGX`sArKAU7*){s?0q_UrUmPp6JzER}JkLDk{>qaZtr z)X4mbuoSZAjqe9M|^N7n}2#{$}sZ&1#eYgsJ zu%Qp;Xdhx)T2fQf(jZRv=3q2+5#+sJFN#tetp+Mh9@4wdypKQeVAna&1M!pRi(OTi2xdja9fhR1|Bx7yUr6k#Cy_SyZD!=8n)uL7y?*-(N4PLU^`RwcVW zfHGxt!G@SP%p_6rsDwucupWD499O8I%XxMVHp&VS$Djl*=fsZGsXq?+8 zRFn>*_OCn~JscYy4oXBx-U8>W(Xkkn2^baP?_AL>dmysg9wcMN>a`GhW%r15^&KMZWh`9wUa z6yNJ*G|#^Sv~we9=NjDW6x?eH?p4^jb!!UBq%6aFYKLC<3RhNcXUk0s7cML;+_Z^^ zY3tU7$mR$0?7E#)h6^`Y5&0w5kLX;-S_%qU9*bu9iusAJr?IAHlZ&GJNqAm_yv`1X zoUWQ{f!7tXfYG-iN{xzK*=6orT=9K8skzi;tgNxI3@ILNg4mS{5t7bM!jxwBp;jhD9PSBR^TOyjTQ?g6?AJF_!EUl9L4?86V}c=An>BQm*zSXyRR)o)n(L(!ZAfXcY?@@(?+HR@uW>iK@*ifn|Mq8gsy(w;dT7Ib>8kVC&=uc>}DRoF#EHDq@b)`d={L7C}+ z2M&ULG&OJSW0P(|Z`{-(m9h2pKxuE8X=Vr8UL*&HO64z_-`+fl?RyLM`#<6*&7T}a zQv6?*l+;U`tF%ZdN*U}Tu2`=ZiS`oX1a|81es?1772+_9V0j?Hl4eYj#p0EoA;|`% zFRJ0vik>23M2fZ9AU5tF7-8D6lO!{oRLB{GW46i3@u*Dc1q^GGKn^a5XDp&*{k$8; zmVr8oKphTH$In0=eCDi7!lF8@R6=Mz+*nJKYUJ@ydP>^YECI{`SR zVpM8afGb5+iz)>4G_jYpzfTM9eYd{;FMu4mnl;(*@hn$YKfkelMJj*?)aP?bc24KY z!Fp(AD^(fLuH00S;B7q7G)t|$J3iTOvPW!gP81v%bQE^MbA?K1e)-Qg1KTZ&{5LXv zq`}lb9l&WC7!&q8%xV^#t`_RVswZA<@~?n2yId0t29fIivmpWdi`mDpaot zjSPlEBSOf3Z1CjBNMPi2@UU+n;6M27u5Z1-zbN@U_`F*i)bYp<2bdbw42h=TT>=ag zAqV1=P>7|oV90vWIHa{4Mgovi0o#jG<7p&7o z^}o;l$$`3+0NWu-;AZl;l8}5eTn*fJ5%YD9JQ2MYE*MzGdA;s65Qvx2O++OK(lh=G zD_}gXpMvX;$Mwh6*XQRC40OG>bLb3M9$b3Xw)uPZ5E2}}$&q!f-JTN*-N*a!Um=;k zCduVwHS5-eLg~5K`PZo~0+^hOZGqa;tODO$uSU*fDZZq>>1}{18#+Uw&R||eMa6y6 z*h*2X6g*#l-rfDLa9U+$+V}`%36q||&Yi#q3|h5TXH>z%KO8)9H(fNeMVu9@|k{_V*<`=wFd!nEz!77BGPbEn+k~I4{SS zo-5^LVuWtM2u;KYrDBArs_%rSp1ShN9~~uCS7Bk-1&2yyx7%$0>3Fdsl2|HO(FF%? zd`3%4#*Yl%^TJ3%!pM&dpyKhR44^>L=Z_5H^YR#81p1t8V~psNFl9x?1w)1~EAW}s zw%I^ibg<`P%Z`-N(*-z2`Lpbu73l-8DsVQiFJfVMx<(ht`R`C@*1$yQrRVZBK$DPo zO@0a_JFJoK<|^Dx2JR*mcS9N_MIFQfuEEVHm&^_ig#AKW&v!Q#9>P6gvZHq=-{EXT~J;sq);+7mZ3 zIG;>Rqx1$ycXm#f@U=pvq+!|_L!Ygpfux$IYEcy3Pc_MK(Q#CfKi*Ws8k`!0 z#`JW&y%X`cimJIp=$?STO1w1-p=+OGPlo5I>Yl6?=tWSNbXn>T+CNZd!7l;)kSeH> z&E>(&aaB=2Q}rM7;$bqAs0Q=No;H-%R(O~OMwBhx`@>a;-htghi{!;4ffFG?(s{io zFQrCBLCFO)FL-7-qA&SnNmgs}ID<}53wYpM786qZ(OUX5kL_7O`ENo`DQ1LbZ(6jc zDzn++nTyVdF!d?%T1Aluc+p_UCfgq;e&pglijr1E6d@3QbQGKj1}U41efC3?CbMxD zL2G;+Rlafno>}1ndP}S!_7-fzTp5M~`np`a28!d4j*1=ATteE+j}FgTd3Z#9ax%Nn z5G^}rh(tY51{7^d)Cs_$bT%8xxk1wiN^9jIQmEltjL}?-(WOypm`c=8+kymEE2`JG z*pc(1Wf++phg)hf!&F)jW0UuzWU>55$RcKxEU0ih(tL|{&i-$xWBHGD-x-zpvD?XX zvg$%~viux6S(SW2IsvIrxP?qB%D#9j#-T7uD-gZtS5RAmR-QQbDv%yQqrrmY!pplSzc1bBT6H9vD zD9t$aM&$JDKcXzG^Qi{v1*j$gah#kJMWSuC$%zIIRlKBSvQ-hp6IRyO|D!Q$&d+cD ze>rBVRG%;P-;WuX6Cg;u{!e2zXfh4{&tnF*qXXjopN!c(n3#t^XIEpr%>sl5=_t3QY9*)a?AqpST=%)%7R!X(=IjK=EfZF{#O zEacs;y$cs^-MaVU1q&8jymuSh<#ffiwiXsL2$bjTh?PQjGQuP!KsO46)7q+39_tNW zl_O_nUBj1N6r^P1i-_}c!S-m#o6sKYg(ihOh$#7YjkdiVXZp8oTI~bGJzkTA5 zo00-^4gO$yX1kxuqyXAXX0vs60_)F)YtA!c9=$$2{j%|}zJ^e&jPyKVu&=A@bq7)^ z-Gfc}9t6d25rjF}z}cQrHRa_sA(>&y!`ZBzwI=|i`23_Lt8_6Q_g!Zh`J$sk{)4b| zh9&&cX#L$H?fM`m&^tSAb4971YB{M1DxJjkcb!>NoQ*=K2VPD_&zafqP-;Xfe zq`Xp8uZ2n6*`zWjj!`>PICdIAE=c1V8W~1p@bF2*8t>oJzqcRB7BnWaPp2cS+r=V} z0V)6)F9$LZixi88eLh%%P%qIr9vc%KAL0!L(|By!NiaDK9q7Y^A_JVWNuHHoVOA&> zopOuKjqX<2(p<4e1 zysqS7u8NB_38#iZ6G4=Ij8!lrVbykF){@c6h)ZS(+gFj3m1@zV{QPVLrKA8kDV{X} zDRw8!Du%049k5Yqbumkeli!5|@osYQ9GH?%b7|DrY52+mMpuehfrCP12lhW*V`?Od?ZLMWGIR`8d2_~fof23NE z`%~sIq*Z|r;qBLEUY-0HjGu)MQ=mSoakIx_E6wK0pZ@FV+NZZ!3uWDo>+8yf>f0+q z>4i-wOK!!6x-UURP^Rnt+PtOTjqSso0HpNJIT@4V3XB`m7oGd$3G@&0DQqWEbN5%b>!G!;AF@R2N<`a z!OcP6Z$jT^qVLnu_shUBxS^prh{rC8ER*f}k3^QnxZO=(885l`V$~XZBuU%dO$a($ z>ok`^J2*Z${gTw2;;uK^!WlpRRaqHRQkcLWDGhP+K$Ow?kiss+yn5U4r(4>$_8HPj zO0w}~AK%h~O{*0M@nRDcl^f=muD$abR`y7t)ily9`(Z!~2d=wJ>qj*HaAzYbw=R&8 z^HNxLm#AwSw|wjO+hI@`^?ribgODT{2H+k`f+2S>$m?Q^~<>#LpP0~{zO;fb8|4ScSc9C z3;{nF#oh3}k%>!C0Q!0}g`9*=vD2s3@kvAe!PD?WP0-1(y`+Yb_cW?d)9M;Jwc6@4 z7{-n@=rlTmUNDb~*Xg*x5z5XYL;Dg;>xy?0dE2-!W>;d&axiAJk7vu?e8C{R98{s; z#uXH#c?Se{YIjC{C#=};?U@jzVk$t^tA)B1fAwIQ^!;TO)gvg06hMwob86a)i`%{4 zSy3+=;a5`w+t)^oH3`ok*z6R;t-zlWg*ZbY{{hLt>LF5k(NcKp`10$)3p=<=IHeBK zrEDAizk(Xw2p`rH}AbZ7X z{@dhUtOp_#5<~8d+@o5)#fQCxvfQudZ|Q}v+HbM+79*Qx8(Il>6}%dhRt!9^hTFvL zgAbD2xSg00@*8MSp|C>vo$N&{b^2`)w}NYmwrXxZev^SPL7&`?a5ntne%a7M#+F*H z0Y;Qmr_R&c+woGhRTqXM#9jc2rCiOIF0H4jh86?#&`bd93xtn_n*If&1+VYvuVyHr zByXWyZ9f!KzV1_xq-zkxmv#%b>wX=j0`;$ES=p}jQ36rd?-tA%_sUDwQd~T5x>@kP z2P)d!&#bfNm)w1=P4K?oAZ?T_8Y`~$@<7oCLwp2Y#=HPW7N*yzg2(+-7KpbdCjhSZ ze!IIL72pEl1f)tcg$9r8=!W~cDZ$C91;{>542ui8v=a`oR8bnnXQYh5|C!nak%}|M zy5k|!4*7jlC5s{TRMg;ZThIA z;FbYrd|ZMqOfGwSKRKLMP|(qFx;QHRsqg1nGRC8>mF(%Ke(uehrUP0x^JhakUTOGE zY3YpP6(!eUzx~;Lb0Chri<0Am3T3O)(>>p+|NDBFo_29RHoOP*WI0w5r9*m%*E9&S&M2zkIYt-CH4aM zTbNO+`H~bt(mEXJW6gn+lc;--2+w{InmRv+L9}7wgvGa|FbHs_ORm4Gxb%jL4E`OB zPt~n|?VXO+S5T(s5ox_T#F@Nb9#}mi5IA~b$e=_1D?yEjNl1#JVTO{(P+BaPq}s-6 zgC@i2L;ap3C;fqlMkRsPoK(3yvW$cTwGi=J)2yp!7z`SXE(j-Y6-T}xuxp(e9)V-G z!N3L&`}UoTw*>XJi)|B=$C|8(F{pVYdyC;TtJJCyujSHY7fz?dK9d&qJIp-ASzL*k zzY;Ug(r81vH&UrO9_q$3u~zTI=ErMg%_RFfWq7HII3~ZrUu0 z;`5O*9UP5YTj$|>FBzw~B+dqFG0A4VY=in<$C=F=7?3O{ik;`;wEv1)u>YZ2nq_L9 zqfinvBcQ?-v0g=fubVC9Iq`! z@VMur7pv!BAZ8;bgW7*ZN~L8OaTfVAu^42Zf(7x^p3i$e+Y<~4V<(tQL5sy43YkK| zQ>Z(I2nj4RNFK|;fod?3H0BA=XeM8rnhL-aDexh+c|3hiV=vBgV(5$@C*{|gq?OkUuEj+d>#~&16nPNJZNlaJ3i2g|F7KCJ3M7(rfhREJO9!< zG8r_SGb5nW;yv+D&lW`VEa63n@@_V3Hpy3L;<)QmQpXQ}-rig%iW~d(2EeR__jY%; zgE`2=9PfIk*Q5Pue*VvIOrJpR2WpjDWv54^QnifBxbJ2NW}psG>UNBB1^8D9*wsN` zVsd2~=2jOw#{Tn_W!vC+g_=M1KXpj zHO>Dx;^Gf(5~X?2;4zTcR4OsOG8n{OVbyV!4;J4%*OB$p>0<+Z?TAv6CA!45ZIBH% zg4w_Rao>PoGTYK_ub6{Q{XMz}w;)krr6h6wGn@GEDZeDm5U4giR0 zdE{@9EC4XVz9UHbx#t*aF~z~%aZHS$)*<|S9H)-A*`}h}*`-qwb&-JI54{m};wg~^ zQas`c6pVzf(*+RM#-TEW%v9-`IJ+LnAqb5sj`BhB%%Z3wLZgzVPv5r9Z=4F@b7D-O z?}NX!mK5v#UtrS6bXH+__A~#Oxn-qo@4mMK`>OJh z_$8O{((K3s#3&;Vs2dwU)}+DpXEjbstxi=@Qi2*-j}d=2{w^=gxDUGWPShUryw?bE z9*OOA;nN}bri781G=gl6hAC5!=QKQWXxFYjFH)4^E2)YcjCpPu(?W}?qIrbaD7-g&F#&9<(d-3TB%IRpsuP+yPqxXe`*?}iM_#kE-RWJjEcxgfa; zwjpzCx|uC%SRsm;nf3J+3q7%hMU^)b_6#o5?NqyK4Tf64I>hMGB|B$PE$U=CxU3=J zNdrS_gxK2J%F3oDda^}M$OSE2C&skH$#oLap4HWrMNf$Wxh%+l(F4+ebC5xoA&MEP z21Ba1tII1rtqTPW4Cw_8KBvwHP7%;qEIR2i6{y>=TvSO3a>re%Q76j}PTq zj{LJzQoJ|>DgslG2Ziz)On8aRo93blSP5S+5m|1=W!_nqnf*`>!Y;7ia(}oLT?xQ{ zEgP@toYk6(*D|#Gkt<`JzWkOeFG)?AHty2m-;u}DTBNDy6W1;zo3zSjdm|KQ#|UXun@ z^ zLz~<`BE6>UE0n>Jkj}Z7i|a5Kq~TLYWsba_=0$#yxW3_UTef_-cKruf(T5M?W#8K` zULUy`U_?1`k1Uc!A6k3!pxFzE*_L-h&izlQ8hjo^qtT2^zehNT$V4s>fKLgV?c(&t zIoQ%DQ#G}x@nt~D<0$D8(gbq(*g@K{Dp$spm;d(m(j{gWuc~P7Q-z zCO3nd3KnrSN+RP3(T=W*vd1x3KGU6t<41G;KgG&P4R&%pJ{PAkIAonzPCUdt+2iJs zf$>IkWgdx2Xq5Psws<9b&0TOHMTW+T8!h&}8-7Ia5vtOzsqbIjOfm@&fts49}MZe4zUz##*Zzref{ z^UqF2lBgnn)6swuxke@s(v?zE!9LP&T6G6vvX#rQ*B|Tr3+_K_C$*Mg;j#J za)ElnP(z#mt4#-ImU)VZ1=T~I0?*G@w%W)a1+0;GyxADc8g<^Haz`*lf@3ON&w|** zjL7TUzxQac1EuD>eOOX}^{e2&4AzefxnUkL*aBhz5@K9{0d0`^Lw;*23)s>mcy`df zR*EtECB}@fKe9(zF=qCN4L+kenC|J3J9yw54s0LOBerl~xQ|=6?s|OkhW{DvmfJs( zwTywa#+$-v2kn}Mqn zs*e?LJyyaqK%{;GKJ*g^M~{<31D^)}Za8JhwkoP?Z0JDYsR}ss$%%*&f3v+Y7cuR3 z!s)Mz;2pSaY7GWRbJ_Dz=)(m8OWw#hQFIWyM%#?=v_*xN7<`?bKIsLrHXk@T%ydas z1j7;99gxwM2%>7Qf4F0pmzyzCgwlkVyC6J!aS2L!(y^knlgV? z30bTOg%nHWmdu*W6%`9IOcf6;shB?#OK9f&iX{)TQYSVcHS%%wva~r6B9p@itB~8x zd`IZYIcy^dgw)sp*3Nm3xxgYp*Df|r(iUfB6liO1lYc@6X{*3ReLpUxU;?ePG)20FPut9R7360d_0q z`}E~`3v(2Gz@?jTUEa@-$+iOClbE7NtP)NN~=&i1%byMNu)d!kqLr;-6N0-j1^X~9;uM!0(*91`= zjv5qd;MR&}5cPFM<#}givr%$hr7gep5{MUWk))C)5PXl+U<)TFhjoAt!YV_;*o!IC zxjH7!WHe7mGQxFjQZg^CP^sfgx+;{_1$|emQQR(wgdyrsfObQd7TJ-5BPaW@Hw66d zCnUNdRS<(;?wmEZE4MYhc*b_Vu;4!tm1P zmVM?pRK?@wVCGk1=GWtnNE0-@-Pri{+o7DC9F$6^smaTGn<{KS$S+&A>`&0~mxiAL z_?sC18p!RY@bd6&a{F!giSYXH((t2UF}yOoR&G`J{A9Q_dlz1u(T z_+;0fzTUlqF2TDu)b^wUg$)(TUK+o-f5>)2N%7q|scF+FhHX5Pk!Mkrnp*vIE>glP z&SPD3)w=4K}`8j+F*MmAw$STU0@P+)Z_(gE$Pvs}#SZb)Sf@eMV z6nBH1idu&}lO8^w4?qF5aW*0emd~xY0YLT&?$=xnwg(F&oHRh$H?aNicv~WL|w+$ZFxCrQqlgkr{7jwUiN$1r<&OsUEw(2 zag32>j-55|g@q4CQApiyuQX^pZ#OlrCqv$&eCu8S#+~3Rh^}^VSrxh9f3&Z6GL)Bq zIPK!6&dHOoRS+;)T#kHe&&!nDeBKtcYJ7RYR9#+H4wUxd8?vsPYB3wM!v{a_+`Jyi z(q-P6w5F-8vuy)Z?G5jCbboum8wkct&%6nX!!5Uau)d0cm5RiGV>(-@#6d&D*?LX< zV;kC~4_+~71mD2GiLh=Al3rR|KjSIEu~wr&5=`6Fi>HneI8ws{Cx=gu44+ZO=(XVx z!_Efj3VF{X8l%aW5T`T5z#M%Bf%r+`c#US@nAfxS+dT(HP*fdR_=lwB+^OJlE_jMG zJC|?NYj z`tHCAA|14gEf;=vN$Mrpv!Pq}fR>S{&N>%d?;CC!OfpczxD@u4Xy8|{yc$ZfvPwcB48>K2WuU$v3PA4wVJe$9J|w*? zCPGgRm`wPG#UDb(7JOlGs|BQ6F`A^8C;RZgI3s5|DwpYDbnM&J3rG^XN@xgB&S5x* zysV6}9nyls#xTN4T~hL)&JK5CV+}x-zA17OEc&@%qFvz~(2gFC+{!h!<>2oRgb%=A z=5eZCy6(D{+}wgicBDGATAkd29qutkd6twZqSu=sJzKccNRUrO#)bm$fOIg2azw&+ zfW>%N6XwE2$qUjWHVBPeoyn;}w#+=z*=cvdjwz(rylH79YKtijQF=->pwkVwkqhNY zK^WAShulx8EPlVmEd=^{Q&NzBr|KzLx+_5c3ei8RjbZ^6QLJ({!Ecb4N8cem^VMR{ z_4v9BQbi}|#}H|O4pkA!;QO%KhXD$ZgAsWjVsyM=uTy@NvMGV*G9>SaQl&ze=rYIO z%&lM!`3X4~xUB=ocQuOY)v{82@`6$_3hZ2$T)&nSMJRl=PCK_w$_`t?7D-Fwpu}JH zaP95#7@U2lF+oBHj12}vdQKmZAqhi(b#*!69>D~GWn?USP7kpug-|Kxa5y=KLqb-K zWzQ+|{t(7xDOOh&#)TpWNb03%j?`2#0d}+_HP#;@4rAKf`+;0MTsX~q`p}nci?X5I zuQA@6KK#%2j*j$nda@p;^9E8uSqfI&HBh!mJ1xK`LNHR|PzaX`X>I9OA$h}JXa|g0 zniDK94|Y2o-Jt#zP(K`aEkttL`Rv=+vOGt+&6bifZi)kfTLbN5LUZ$p{Bj3-meU}d z7iZuIx4=7Zvq2_v6Pf`&&I<+CIhX|Sp%XTAQOHOY!e?B+tIi9W)S5l9=a6(x`?(GH$952uFyJCQyl;?bkYW=5qgDp z&$s>k$fD}isUog~2t0sd5`bjDRmo&xz=?wR-DKRPDK6233O+H2CqlZONaz%-Mti^R z`?~)m>fe|Ql=^LhOs!X8R;~fHPQk2DL^s6{$O{p8HQp86x)70eq~b@Z&_Qqm-iueTTCv9DU|>Fe|O!E~y)p1$wC zR%i`oV8Boenm!NWS8^A$-<>7ys5U}7g4lBedh-?FD*E%E(fkpE<4>u|f+ePZe-ri$p zLej0su$KfL(i`Rr4!8lrp?Ij%?F zQ&I9^6F&bH(GSSy#I57r<+g$GZR3_Ap^uj>!$NN6p66cTmSEe+fHVXZS$Nj#O}W?= z>mM|PPBKGATyGbdy|g_&4o6#?4cT`lS*B;rO6$>ITtGyxNHUVj;Yf{j-zZb;GqSYt zELKodiDNIpfFTMCiwjGBH5;T|4UxM=3pP`N>flzzN%NJiorhp|^!Ij=Q%GxfcMDvu zDy7zBK|4kebjU&A3-TJ6*u#Uz&ItN3X7k91a~!N*st8%f!n`&za$;})p21-7G!rD~ z;KMKtjDfsyqTjRUNDzguj{5!Km5|red<5y@hKGh-42gq*D{K0`CeKHWD>V%AM0^Ic z_Q2t<6~GlNEus>T6iXLmYQs3xa4-W1tZG##Y^IH4mtozcfWi_%VHCk1XP{6YSodfp zKzxGhp&6h|EsCJ5u-B0PLmfDufi~ba2RN_Yh0GT);WI%!dJOOJq|J@wW8S-vyG4YK z5Qwx(_A@>g6}8e9Wo8zcU?v{jrpRG;bm4S%5^H{1OUX@$J-fJ!42kRNazCw6$8sP8 zPTkNDDk=(9DLp918j+%FtZdts@ z-r0#I^2u&r5YDwJ$+4#c8t&k>HbnZk5e5(Y9e5;=h~G?N2VlRIk%*Y;fFmobzCLTR z&ZUltWy7aJE`I-~U%BC^2^U#pRK7!4{b_O@EEZpq6wldMw`xI#3T~j}d9w&E7g2|h zxP^J?V|@^we5Nb23a~Rky5%e2vMF(WO}Y5()QBLrS$valhXWJ}XH~Sc2-nm zPSm(4^^aDsb*V-M_Vh`!$(SV@waOkPBk(&>s(!%)gkm$i+uu42Kj5@9p$~U+7N+<) znMT^91>OjLcCs>Q88S^kPJKd3g>Nj9eNC`xLPN)n1&$vZfrJkRPRJz@ERq&OC>l9A z6q4M)kKn%rDB|fth}pmq7(bS-nnz_d=#q+#PmjfDd_$B5(KO`K#2ot+lUjwrck-t%hbcgwSk<30SSM8yl4q7*{h7+i z|HMAkh1h5|6m;>sw{}Zfpf2(QCP@6QOn9k(O6GkIwj(;ZJ;MDN6TSjYRSJvBI`%4% zzBlv>Q_V*)v4hE}fcf0u67`hQa5-pu4v?(Nz+IJ@&Ey-|O>@`>(V0DhZMRw|Em?9O z@>ru-ZNeBA@89vFq#wP9vht<5@RE96PEgRso*Y}48hXEW-P5nO?eh6P+pu+UM;>PG0Y6tp# z{vk}NS~z_S2@8>qIs(NhJT!#!&vYYpLTe_yLaDyz}hIs#x1;%~+FFOBwzg*d8y!8Lw02ZfF8O83`3pMbmrE)uI=1^` zwPzQ!HrBr#3tHV_9W*&r2{p;Q#x+k1L;eTuYI|N7r9b4_~hHy?HB@63TTfe-|^ zjmeooh$pK{GgGEsS&#$G^Qy?5s%Jb<24K8UiotcL9PAqu>L@^2lGMcfnG*~=3+^Sv z7OqI9$yqENyWF~U;Jw~E>~M1~z(dJ(`KIPi@D2X&5bByd0?%NxqFG07e9F@bJ7Is1l6AI+FHBaY`*B~*^b%BclSsxs&_WRaNdIF z6UN)qB3oZ>czNTNuYA7lSK)NK1Z;na>Xnn^*}V~YPAS(Zv3!@bWmdoxkA<3;0K6YT z`hin{d=XUdr%YZBsha62DbJy5$rwS*6?jODQ(Fx_y>;qj-H9P zkiFN6(Em6?TpSAw?A`T6&lmenhP2j8Q!l;bqOk@XNadp7xX7uTBwTRP7G(#gX!Xf9 zB`X%mAc>%oSfC^FBPFG}T9&X>85!`X()N^;z|W_s3v#F;qykB;le8KL9}rr2-fr(8 zyHpR?SSi=$j94KFTSaX}p*b_d)a`c=#;RbgV9R#aEIpx<5qbk$mYjgIoXmo+V2TF{ z5D4_5Qbn(m^-4m8uzzhPH;4fiVHUddFmNKUDLuu;O)($8#ry4QiRl^)MZ&jNHbp*;(E-{;g?Me)^e-hr9qSSXvZARIi&8aTMb8e$U! zU*1)dtxVV7d)PJh>&|9?r8TSEB4VT_O}%tR`c=Wsr=zYx+|DBB*!GSCf*^2=*X8{b zUSJ_#S4(<7D)TNxx6stjb9uU~KaIK@xw(`!w^9b}5PMFQ>u}`e0@yx?0ucM4R=&(t zR^AHTH5QP;TtKF|s1XP70IyfU&QOeY7s~Nm182y3VWwWEzpM}f`WpZW^jtg}rf3D2 zYQKO`^b|yQ5j*t;tdtE{DfP%ty|BFe{%C;GZd3&-Kw*kj?hUvGE3FX)D%!XwxMe8R z3O$)ubBDOMfK+92u}IHBr=zwRx=j}MCvGPYKgI>2jKH5F2f}X$a&%;v{74Q`67>|j zlnQcif&DJc3GaTtsrM@)U%t{Y-la9#CX#u3DG4b!)EReTPxrRYPnf|1-f>f*llKpt za%l#=#{{`*X?`~Q7yz^5`iC7@$ckxXqw2ma;avw%cBN|RuenW)aDJ-P)Yoqf*)s09 z5t53clQ&}=>LC4fMRlBZ_JnX-y3PM8)*8oD9q&9pipuJrZ{3O2uY=^j(Gb$ zp55M4LX2RYGG)908Lo~U_~!E+UmRfrmkb;@2-oRBBn%!L0Za4y2fY13-|jCVihko8 z84PJ-^|9Jh2L|9Qt&4F&Fj=KUppc`LT=h=vTiWX>YLz#g+kclN(-aSVly z!3%pI*5x;S9tO7)utz403_DfUu?E4VSL@W^jHV4O zh@j@c8Q0jjDKm6>GZ_h!;~`?4i5571|v4YUCvH1nr zK#qJOOU2FjoeTv(A5oSLU!%{%#b}d$_-dChyQt{4%Urx}u*1o0Jwui$7l5R z-au|CFtP=d)g3OE+sbegICz88rJe{JHx0ojGW(`Hj!~AZexV0>UG`P6rW?T4zT{4G zAudF7!1f`b0%RIwKL$v916P9PLFmMvIFS?iTC}J6-|?B?XAYeHU%ggqFJuV{53##Y zCweqQ{sHKUsXsyP3F3vK<@WTR9^{Onz%CKi{f373x+^QY{{kP_7bd__Lj!0-mv~XK z6{5dJbNKMV!H|H;d0HMG-e<6#u425zPFJ~fLCXDtIq)Dy5TX0=Iw$;hs}$dZ8!&p5 zJ#Gp{k5E{IhXT+m)4;zb^2OHINV$`@8hkNP_0`swDP0wP0Z$~=q)BX*6W$y12>+1_ z6)_igz1gX=j6*&uZ)BWhxgCN1{r&s6YfG_9y~hp`@T@^Ho6|ol{i6fg8YCIQ3;Di2 z;HVuqnFsD(3uJepyvPEs!Q<5R?%IQs?b+44e5@!o^-v6aOivR&?!GubKmX$0O?HM+ zh6I9$K&Ot6O`15xW{KtTQ56mj4UKU8au*b6Dkp_V9}b~Fp%qSDZ~#>2=^udAG#I43 z@gu?D^5+#EKzZUub0_f_6R20XL_5ai7RsJf&g@(YWly4qas;y3!B+Js_gNOI;-Mbf)=#f?eoC%g!&a#tEGR(it@6Jb{x`oUpTpWCy@&>*d(~a(TaXNVTIP(MFQ(jHtE%J_uow zi?Gzxi^rP`90J(?Ki<9vAgU^T``kbChhcyLMjT<(5z)xV$jGQj2P7pUqoN|$iZ*Jg zsI}Hww@;-0nvtduaZWZqBPfI ztZv6xWn-);>*1AIS%(kD$8X;rdi@W^jpPVSP7VTwU|YZ<+F7hr364!#C%W1a;5W?I`wa>Y$vr?PhwBlJ_rHNRORp627$oP9=9P3BRWO7 zr#}MjN+TrjPSE zkS>~=d#S>Ga65F=+dFI$Qw;coKxC^h)wHV($yp&Rk8JrOqj8GdERRY|PQLW23>u8U z_*=v4>(xi<@%gCv{|FUG3nPUVP{c z@U#B`thf@o{YHKz&f_x6M~*c8{jH4%5Oq-HYn7X-br&xxDV>jj{~J8l6b$x8)6MTsCVkc@gpNp$R~S~rcbBGLojfGH82_0 zoLM_*?FkwB`mD7xGKH~AYo~V^V}n_X;u9uV^>|X^iK1UuV4OB#oR;FdcVV3F!Z`8v z;e=EqTa^ZuC6(`Ta2H|i&>m{Z&28zPhS5v$w0}^sx;$gH#?kgsHH5?>L9_lS2Z6*J ztpw=>$YB(i@8DPzSJ0^St=+1tVY7hwWj~u_3=Jz&GF@Os{pN7ZL|rt55+x@4My|j-$-qlckEx<04 zB!D%LtE&3QVGa*CZQmT@`LGFwSh-bKwrbL~`jF+KhI2TN}R zv~w#i)`Y~Ix6up}9xuS&{u0i~FX3RRP%Xc6R!YhRp7zEU*I8&hNx%^Dewjwat>pP| zO*l^n-yH7kce#P%3Y>Hu>$gsJ4~+(VWTd|r1g1zw3{#;T0Cw7h4~v^f$w`H1Mgg2x z1gt6r&tn_`uEN=oJAt{+b0e;y(UrV!z%}4og%8c)@(2xTe-I{G6Q{Obrcs5*>a-J* zFG)(BIawDI81%U{zzVUx{uA(o_Vl>i!z_$29%u!y<^2f0Qx<8bp|itLs#T-yDsV1H zXLmc@M+30C{cc5=Rg%j~(Wc8FTT>ugG@Dur*^;HC+3s zt4QbERZI&l)r3bisRk#Mv&CeyivSvIQr0poW}4C^AU6S)C={V*)mp|6*O(Jqr?xh& zMg!Izwe*=dL+;02Jc+xQkGr5%TGHtZssHSFI4b@WfwA__n)-h!rx+%W+L~T}vpPAc ztgM`3V2V-p+qy}Z2kY-qI6{BVnYWNlm>D#K8@bWq#88!gbVsggX!sFk;Xng$0J$8+f(?k@WHt5#NUB2dWoR^{?V|1strZP(L0s?{rW{(+6wAl~ zDu|zKNQ{qElK$h)o-VsnPui$7B8L-w!!x1Y}y^dZqQv_EWBtUsVJ1{WvgAOBs)Qkr+Z<0*FvL9Mbt1 zyPJ@yKv$%>K%+he6p&yNp(J!0`>Tgf%pC*03|D#~tE5RM7m}kGs||eaw4`Z3ZEVJn z?86=$=@PC*z?c9GLS0B?7-S$zfGW9>xdDKk8<2+>|5pQgEkuRd{q1z# z{YL|fjNhLPEXV5%{Qo$*)Z#gNbalRt4j=h7BfRqbBaEbL03!)l@mO*%Mz{zg9NyC0 z83ByF?CZKl*o;ph|29YAi*htRySfZr_CVkvc6H@Sn&BmJhdi!&z2z_x>(#D3b(?8P z!J@z;GV2@7dr3Jg55I0kg6q9k_hE$<$aV9j&0b(s6p#nPHlW`7drdaS2rC+(;pTc< z{{;Xp&s4NEWWiZ;7YxwwqDy*qe^CG7zM+(y61YUcTnJ4_t;DaSh(Tly!<(s-LI^v-1z=M7k^=P&iuF6uLFTFN`J4EF1M;J@Z*-x%v@}_qlp~VOU@|-bcpi;zk{g zqi#PL1$@=-?e9i4LNSJ~Qepep^P>ZoU`B`gpex`^!*U5A->?#%A~DJie>9E04}cGh zL+Y@aw@y;Z72y$T1q1di-!RgeA$R|9a809@bRr~>TGA1aK){8F+>oEI z*H>3#`(YygpfQsWHA1bGz_2Y06f!oOn1;eAO*Bh23%*b2Tmk$+IPbNv9_ZwxOV(Db zQR_@Bl9~jf$3iaP7ufd#EK!tkpcdO^w4ebkcm^$a3N0|91v8wgBm^i^=b%c!6p+eu z&Tn^q-0<fDKeZTJgkG^&?SKU{1UzW=G^$S$(EekxZe)T(NSk?o@4;banZvjA| zi`1js3;V$>Ca5_OvK&3>am!+KksK1yqI6o`?E$#k<>QDb`s!!)b^9)YHF%M)d*3s- zb9r6e!PsOY+|uHHOt#FJ9DA_NqA8x^{;c^kAhWd|yq>zMco7chWFoLyML@WzIsFY8 z3jY2BDxwyrbbMIGWF|sCP9#I*4P~*B`M%@(z%}^8MnuBsR2o1^^mCXV zHnbV(V_~3{@wlAsVZS+I)Z;$x@}Oo?7#vVUa`dlN-JZ(r1bA>KmwG$JRn>qpVR~;f zCR0(+>siECHTPbSZ3!8@%Sk^x7< zHBkz)8pxJzFY;aAFyEr%b(3@vYWYBqMNors$34Ojo*i_Z z@|xAMaLsr*3_=)&5i;>QG)|An8zIMZ!z}UyTV$P!KovHe*thTspQqoeRAV#l^MM?I zr|t@GU(%!)85wrkI}RWB@yb|(HiGm!e{8qe4jjR7@DbR0U<*HV%GK{hej|tL599i3 zjSkmmF^3~@eVD5BuIcq@Yx?Oi6x0!=49-2+7*JHwUgd5`{=JZVw)u;<=fV9d>UQOt z9pBp=QM0p=b-iNhTQ)CFmSo^Pas$=}U3c@l6(*CZYEMUBT=HaPSIcfu<1;<&-I|;4 zxlBxXAb+1PnPx;TZgDq;JqicmO~%woic!%52>;8X)X0OtXzU-p2$g@VbgEmJoTnB* zJh~yK9>i*oKz$2*(Z!v+TC(uLaq@0-(FGqhG=BBP2eq%fyQ^tu*RZBTECIVy$yhg(fy8A#5!TXPQA4g86E&>i_uehS3-laV6VLDCx(K6oF-C1VMlDo*RD`#OV}}_#9($Ycz$lEm zO2JI6;dWSI9}>h5c-O#4fU%0m`G}^b#&~*o%i!IdI8G}dM95pM^fT%ZXRKxw zf^hq6HdHYg^jfWSD?|g~(k>>%-$bKXl)ve6NZkE%G&(JZnnYqoEKH&XB`oZ;2?O?KpmV6(pp<#0;lJc<8vPG>n;>ng-~*$;09eZZr^^O>-R)Uaei z9u3KvVHcelqVFOs=*Y;=rz}j84?`aEU|^FbIxyrR_XYjHM6JaoXe;H!png~*+A8A8 zQ)Z0+w%kapQ<}=E5Bj>kYHn`+veOftJkw-)^9N7Nb#SCy7vuTiO%t#SY{%YpnSp48 z=ELe+V2K|3(S@q9yx-;g8Z4J$bUN(0Z(I>KAh9|(9BIg2e@}DA4FFA~fx>MLhzfIn zcarE2Ct}uZ1rueb)uYgd=fgEq1Of|O=5G8%!`r(P4+A%qp(h4pty zLGFw&GuJzqdRI0UTq&RRb!B0id^g;WyO3w#^iIqvlKLs{mRk!7u9SE0g{3P>OZ1ET zy4xtv-M0PR{z<8+vkZO<^cM#n!N6v0P%RNY@3DQ29s-gf_*${SXM~slva3Bu4|N>u z_7Yx;iiJ@;zT`s?8=U##NGi{Ql?*ou3*Soc;j|44p z=HZ!^iP*kKKU5FlC-_2vj2y=SyV5tiXa&-}QOiCKnZHSJK%~i&I`+5j`Mfm~wv2}_ zo)hSplZl$s8n*txkXfcx+dl0{62hyoHLj^`^%fP)#g->6@Ea3B_;W4Xpi+3`W3no) zc<~i#m&wF40iQ2nQORwy!2z0f8xAvJ>nS0+wgAjo7VN0C=%{r`(y~GeZN;P*d7n~- zr3Z`6@G)c@^o;Re;dG#6MKCBBi`wml;Ij&>!2^D!5a&F3$_*Hm zhoHb_j2Z)T6akPf7cNQV!Q-bv%iul>R9A?T5R3>#AV@d_#x6!mtV|;&Q?+1)L){8j zy44!A975m0CGiM;2gCu0u2`82={q?1-ydHQJU;GM9&ZaCuRs6sa@@mN?eR#*1G2YC zkQ(#vTJH#+-Tf=i?mT^V^pEr-$@+QwrtROio%VmI?eMx1ra5?g_nFop&FB}}FMcD~ z9tL+!M~wc6qb6#{P@DeOV~qBQW1M{ED(91l({hBQQt@~`bUeL_vELXwYT|tar3j-I zx{F`DZz``$L+}bgNfmGWJpFXKMWN#{BGMJc%5@#)!apz;B^ZqdA=kgd6{6e8WT={v zw)T!VgwI{A+pQEJN*}c5F%n9`leT`+1KdZ1yY1c8ltP6*%z+}thGc#*wi~l)ubqvH zOU&4`_Wh2wZ@;m9bqLKa5`^$km%VZ0v(+^n8tvUdOIiNZqLf+l=ja5ANrfLZ=H}!W zT81q)UYjyYTXfB(_QvuB;FMX4sNR#n+dYQWsZeoX=5#e64N+DN-`5Uo-baottNQXNQs@ISbMN}oLJ1dx*iIR!|Go*X);r`6rA;4?K%Rv3 zb&=ij!Yp~Wtqt3+0ptwHL~^%Yqfn} zeNzAaYt^X!SZb++!h~lPwoW}g#V^m7-z)#;DJZL|9yr*ZBAN7vNA#=vp60ViKeMg;8cWFsSx zBf4gSEigdf#~;UYB;Xx#6aSF2=ZB8NKOT1t3=g@5=^)t0+ff|tA9fG)yPU(}d_)4o zEotgxy?$!+5aT~Qz6LEY>=d&F@B!Fq>^A-hcx(!9mAv>LQuMM>>?gj*={t+{wb8 zxdJ9Gt&8$Lv6_sOj$dIkf-&~O{89?-!hAlShUZo@zEL`1Ds~k%+yO0G%8>J z*?*VrPl3LrQQ(liq*}nl+Ax_{VwGnzNjoE!^9F3rL@mP$&>vT!KSDfGGz0u}e*nkD zoANR$8_^qFcm8afzya@8j2mGW#zWM7OowkiM788}PgE$x&PmL}U)w>v$2T`?wTJ4; zf<(N0SzW7FYnkWQlQc#dFsh4wcW=@CMMd}BTXf%jMHZ7$)?_kzjYt-k?pwgPWr234 zJCGmY)Q!_>P?G~L=jd@di;1-p1H2Ma2SRGCS$+p@s4c>v*7#jN{>#?Z@vGE$FGpjEt)c;hL*&h6^-xqtK}=LD1+XiM1)z{Q5W>ZbL)2?0fZQgC@6Hzu^*h8Jkum3S9LF2bo116^LkduraGO5t;w=$cZH%|AaaRkpn#Wi| zGk!jUPt?bI`o`rgy#dPY2qV^IWq3fADYc&uP-W^!D&y}$0_|P%@r|vb6Y4mU?W$pS z^McA)v@m77I%f2rjR=Y7h}tU&WI0Q@ty>QV%y7naf8YMyfgic_BI9}F9krRc8JRgZ z+_mf`7xnl zZ5}&aG)g_ZyB;q9hN^LiNrq@%nCPd;!91%B*F>vTk#TyZv-hOi1DEB1yZ__~kmI;V zI2q3(D-oG`jMoG8z?fAd!=$Gdv?qSA+dOu{rNRYCgN^Kn$JL2FkG;q324xk`@{G?* zGe#MeM(sQ?qKuoKd||ATbsq=g9f}D7X3spMz&0P=D9_oalq3)8=I3*isS}rKX_jJp zp&ToF=bzPehvU>LdMYP*(4OtlkP)l@{B_*^1Y}!S*-}Qqf1e@L_x8^>-Ik zz4o!KeGoxcttu)hC1rY2QX9f((#Eb9)_~ENc#2A_3k%oe{TE!CM7mG7|Fy+rGJWjV zXbh9Ez{}m;``&(Qx2@$x9K*ZR>fGhoSau|!MGd!n@eH-)2E@HwC}uHN zvGt(a5@yi*4m34v+ft6y)}=t#QKrNk1oa&%N$dA=xT3`1tViPJ3-uvE8`%nGYzbIwG1Z-%0sJi4C9z5CYJ4eH* z)Tj{R3q(dkIKlC##7sa6hMdI3V#mhH)yTFuqy17{&Qk+JV5nwzb-ck~(8q%B&WF-M z!y^FyV1*g!ce*r@0k`AZw*5!lUL`c6OpSdMrM(ZVp&6_!$a~K|sU)w@LYiKJG(8N> zw;0m27}A7XfT#&cN!d_*v)R*%Pp?%E1{GiH)_>65wkD^l`WJLxCWPZv#Y5@oH_lJK z3XagTbRQQrJ+){dR@MsGHS16ms|HK;R#A&=MVRh9iVz8V36o-c4&*Je3(nGm+PtOL zkI{oM*nOuk7hz+I2WMzZ1xUM!f9#6%D;}ef-X;+cAAtY9Uetw*u{aad4fV1o@-OCF zp1u}XF)1PGv^tE{M!QZ-(9NEIbFtA_R(3v(sIWT*#;0XmUz`W^_be3QN8+u#gB3+m zh@S=xwVh<+gwlI1ONtM310276`Oj3MCQ`v5YOHFEQtIO)73#a(pB)2})68A*E+l16tJAxUFSE24;y zB7$5!UtUg^LQ#hW{yhF2D6ztVs+v!NO6(`zJqndnjWh~QtAXNTb-DtY4p=8DAQxV( z-2Jn4@We02*WY(IzB=IUd>_!Y&s2JS$_)64BL&uXzT8zC7TAYM_@}Y9WZl zJSzsx_mOAi#o2ORHZ?C-geG+Z+|dX8h5_qkuP6?R6kCp#&+AhQOV?=}nt@K{loXjTG0Bmo@h# zCl7uLk#E}VINI3w%6bc2MIv`Iqk>gIcmyb-CVwf@sI*tGuIgCsB5p6n!Tz{-Pu3vX%(W;vb-8LH%N6~3CUO>@l zsDyB`-`){Kjl31G-4IksAJ? znVRnBDft~O$@KvF#!_iwhP;AesBZv}zeoVM8*sx1w~k7ILIjb`oYsXWC7xlS*M{p9?#Gq9np>pu}lQi%#bT;)3>GBCa_d*Q9=ZitUKPH5GF4nkf1zh0$-P!da)i+Wq!}GFRQDw{cU)3 zfn6n4aem-YP@_&mv6wRA>h0-qV!*V(1_wC0 zEQo0bX6(u-{12quG{it%@@p=3@{Ei)dfmu-ZfW_dtsUXdlW^mlbe{5oKCA^DFi(h$A`M1yLF-^O`8b){4=uA;7D)j}o7Z+B(f6$E_Fd9NyAzxFe znKttRy%43Ieq%}XrnhPxKONkE$W`*kEFwURtXyqDL9Jy0jgVla4+i$g=J1Q#T3c;9 zk$1LrkJ?B!u&r$u=V0R-I>04%`paW`AV6XIi&InU>UOsubu7S5M)|v_ERj@tN2r=0)A&YyY^ela z8pawr2oH>T-~qY0vfVMP&|E8u%y$r;*GPF-!8KEpG#XuUMoue+)y9@zAwI0X? zl?Qlt@B$Yht?EI;;xInT5`B&?M>jtVhzF*Bf>s0SieaQJ5Bmn4%7}23UKklgk+Xws zHXB$z)Kp&4j;F_W!AzcXt)f>3^N>F?ghcp(2Amq2EOgE@7xgF7)NgS z7|Dch?Io^#yLYRjZwTg4^0&tEPHdh<-!}6xZ;ABzCd@Rr+xGp4%euZsAQhGRbgvwT zAM>*OrAz0JCnyu-a&{m0sZf1l4@IM5bd+j!%Nm5!-Uo~+FQVeq?0XSg&6_mr<9`4> zt{Bq{{6$vNzGPMytXS0U;$KIgawgSic<^^bc5J6!W=ke^G;hoPd<&r4c?H;Qe1+}L z6y{-2KOAA~`2QNf#bIy`eMEj>uEvHOWE7A`%D&Qq;-Mz)*8E!^`xCZdn{e6}$ajd% z!U({l36I@KK*_;&eF(#dP6r+jiT21}1@9pl#92ky9y6X%K-Sx_qdLxTFpVia>h*Y+ z#!LZj>?q{!N2tY15NEs)G#FRHgu0TM&0L1vSECTMb?f#$2Re@H7a`!e;*mHw(0&i! z#b5YWD$MIEkfedfQt0RMis#Hgpih0RW8$s%78WgChQpUG^=OKVi?5U0X52ij4fHju z);Ia$7h!C{(FT^brxsd*TvY;&krk2Cez#P9VDX=WmTv}oE`WR_qiwe zamq^}(d)gH^7!Ri-Ed|+}y&#mPQQRj$Z9W zx4~<%NyL!V0`mRaDV}}h3t@>#*7qW~8Ym;>Y*Z*r#*H@GeYz`va=29E>;81BW#<+_ z4s0L6{4q!QJtrJpCw&mmFpU;Pri3YoO;gt~wiu|yXt&e+a{Rb@9VbZS1OuoX!psSS z#}MQA$>jmsigX-0fw>rgzr?aWcUOmHD_m!kG(fdTwkq>-y=(o|Dd= zUNAZK9PdTtot~2(Rvj6oiHSj-E09`pG@QeF;GNFiN#F^JpxnOWv^vjVzY9se zys!5d{?rFpBMSZO+#*?~a%k?c(Nr4K0{pd9up*)bRhMHSdW#g9Q{z>%$Nsn9p%K{g zU&ks&ZGV21fBTK|w(I}ZHxR)CwwR#(QuLYLhZU(?3_Nm}9HiR<#cma2pEL$7_SY1A z=R$mkVv{3r?`nJ}Iwz;833T!r`bvw}5TyW`$i~L(;4{m_S}T_ z+>iE5LwhFeY5DqJSnU7xb<3VTJ3p$ctNUo@o;_Xhb8pGN^-|ZKmnr`MRxLd4QNFYz zO|wyxwqv6)@C4&*F@lV^#hD2mxrnCbKPM&8{E4qVL@oszxClGuAHS6BTZ0gytfX&W zjut-4C)v$fWT-sJyGnBQ^;y&<_ujH#u5s>yTkb7+6eI{`Qq^@*7W34jCB^p^-d%Y2 zJ-;h?=nsD`{qr9lf_I21UItJOvkab~DpIRllAKnYmb|2x(A@mz4B6SU4PnIH20Un+ z8_139Zk-NU)OZTMN`X7sv!C>;XWW^Mbx9&>u*mM5q3-?USxkT!1mwORRL{6$*|KGK z;KP4Z=P#vDacnKvtt|*Zm2#U}w&r86fe)8j8qyFH0(=6_M8F|O;NkYck%+189P;t8 z6ZP>L&Nt9)*LeC=thcj=?dkMtRDB-oi{Y%H>{4(YQVl0|j z44#M4=C?d&fX5OZLg4A)Y4-y`p@s&+#qbn-wKNbDj~yoUX-8s|RR)$QFv_yBG89qS zBCM7YXhBDeZWLCFF{nTuaR??BNKDIWNoFGq42duh5)K)m-&R0ID3u~h!zG?Tv03_s z(FK}Ghj|_YK3Fiq8u4{e=t3`|{Ex@E#^YQuIF}sf3d6aATf=Pd5+4@-Php)z8`>yk zGe(4?=>KJ`f!GD6qeEl{LDVii9laN!hfr`1n<; z=v@QdCEhqpeBAZCz#`%xhXXkj0KFP~r_kB-)#D{zVYS$5+5=H&wc^|!V5^gw*+tu= z?qJj0$=J0sNrWT`B+0TG8%MPpFY>M~xkWmYj4(uokzmD#ggycH3{))4H>>m`^?E3( zF!q|OxowLUZL`3`fSyglwN76sQr&m@Lelp&XmiZ@+AKL13QsrNNUG5h)n~W7PaSzq z%m26SVR7f|Id>ksVZ2Cfz6x!o@lopUnSxQ90_gzTE0#e>8{F!giOiY@{=AQ2@vbzH z)~vvFSgl*LM0f2f<}!p)o}|k+^A!ZT0o@dxiJ~K^Le##!{~AzDy7JnrYp;lx_y21z zQ2r>;K{50oyYCwY9eONkCc95Kdyn@HvtiLOH~{E&inYgakxFY+Z~q92C~>ODaKzY| z5oB@FuhN77nq?!GaG{xKe+t@v1=@cF+8>AZM@FFim?1FiL;x3VArrUIz|JDAw6^u1 z_}0#bNjcYv_pmzfm1KUvMYI}eX*u{40=^mw0z(II*U=nzzuVu8hdXdJJdY**RFg74 zpLA^9+A)9`&~InE@Vy%)ULxZCS;p4r<}Jf}m+l;@rIg zElI_%aX3R9#)Q_j6UT)1Y0z=R6hBGX{Am>Q752&EY9p!Ostc+MP%rR`Nu6IbHy2iC zG=qk{@n3E;>;6|`W*{aI!))6ozRI?3Tey%cM(zYQ2<|~JMCF2y82Ey+m^a>N?3Pcz z31)6~_TIg3yir{IhGk<62sq>@05dpE^J{GRrzU4F(F!U@f4L zqdu?8aR*nRFGF`gv8<61bVkq{kZuA~0Ht3V6t2S`qr~%J7sTI03L>ftfgAmzbJ7(V zwEgFP3Aj(Jn>p}7z}>!h@%`CYz+NUASj3AnNqry}c8z|doqU%p2?tsqgkS?Q= z01PextQ}7nLK*TVF@)U0g?siu4jc}>{@m3k^xe~|4|}fe6(uP{r^}#{Bx&9;l0@|n z4>_RLTF4@#if4`mG>r6(DrBRLwP`~~!VWGJ?ci$RJm2{B=cY%>$Fzc4j#jH+#LZht zB5em+B98ihcVq}FHujv5r2pcqp_MAsU$mtH3{I;6SwE+(|H-lE-WNZ%2WE&Z^@K(u z0lhU9y)^+N7LK_afn#aj1b%8Q!31s8Xc1O&>42SDWd?)c@;NEl*bl#m)SV{MWHORg z!KBQ{y(2#-V{Uf3l@#Z|o}`#E8$7QlmIO~v8Q7@TuVfMaUAYRgX{AZ2R7V0n78b6w zt{2B54(-6Ijtan1mb?b-P{S_9kNQ$@CL)Bjl51)5@m2{GzZEuQ1*w*0(ArU0if9{} z>))su@0F z3Wh2yq-ND>6Lz3hJi`qy*)G(kQk-*56JsLqfCwv1xNhs&oL}_#u=5_DhT|DGI;QFD zZ=|B7S@;IUJJI!@a;-(E>B@;ERC<<4U7krDg&de@Y{o#EAojh$(-9zNjQ}r>0A(tt zk1{w|Dr70+(ZjfQ3Ra`PT~Z68B#u3v&UHF_SRPXVMlg``QJ8HBNF5}RAj#lCW3(ownh;dwrs=Lrpox_Npr)%SO`=T5?BCNGcMQ4)zaDi|J`#m?l~IwJa)_&X9{-BEU=;i5|pvg zWSX}cNjVt((*^ojg@s@bN{1{TgQO8az_yw=1r(l><}Ypix#&Y_#Fht?g7^;MZhdgf zq&ub>SdVtZqyK2N6B@0Is3>1o-O!MJlqHLWb3NdTnq2uRicmo%D`{fRaJEsz*|;EAhbAy_~Ot2)Etac zGfYwxGp3}a@I9mC)k=I~W__c~N~u+}O5O~#N{?3Q(JDP!C6`h28n{<=t{pYnnP;1r z)7Vf&n(AxY*Q&IFEQBUDk>|NT<&t87KMy$W91JK5q?6MaQ1#jPPhl+fLhU*gP{+?m zxftME&q>Q!f0NowaqQt}^H?e7-D%6n9H@CsEe&h{>>m_-alV9B)v@1T+-a7TINU<1 z74ajT`!e*$bvQSz!*x0OgXXA&tAhP8rc=0QPj`+HmDti-v4LL2WVZvBz_w2(=XO)r zpK|}_j*Aviv{vgsy5Yad(R6?Lveh!-ET~|?ZHo(TzoVc4&$r)>t~t}CXJH0SIu_ad z$Qcb&Dmcas)Bs>HsGvA9G;mgbo&^J(a8|$DkDTFe|lVtc?RH6%Uu>pQHyJvyT(NJ|)9lrg!ly{6`SWhyoXsmkL!YAh4> zwzTg3;>*2z@%+UXPb^#h#N&T_;t4!I{`fC<*aScF!c`HGkqXE@?CmkXSSC;kUl40j zBse@8V}G$s=sh{A(k0KhXq<{4JaN`9mI>s5Od_PS1vwjKYL!D155e5^iDC%*x z-Ej?i_!>y%Wsu65=wZq)7OfF?^K?O{MhBJ6G3q2YB%aM@bc%3BK4Zsfm-9&GS^7p$ zpDmL=Q$JBqKN(le$+-HOj0`+qeKplZmNC+4)s59lXA7jHqAX)oz!`M~E}ZX=d*pGt z37n_TaR@;$Nqe1jxHNM^b{w^`Pp{{0C{-(~f&R3jQq*}o?mx5q++?@-jdMmIboP)2 z5v_%DjurjW;*1C#9kTdkXc6lsdvIng!R`mHZR{gp2?&y1K|Mm$9z4A_$MIAWU`|t6 zAn#hplZf(JNTh`zo6aphi&qNe^iZoObl3EofTfFH1+yw(`FnBe2K?^~+A*Q_(Ypz) z<*bK%f%d7%5-NKF77sk}Xse0tJEPD-9aI`$c0~O?Oh9(J1jg(^92*oXLa{U{h^Mn4KKR%#^6e zjeAEyqy;qCimeh2GB?uqCWr$uWnzbA<;xApI)f2Am_|$3V9bi!Q2&zMzSi<|n99pe zLbQSHWbsRHVqA}0#mXlQTAr39-+&fPLyMv@HnbmUi^5GtLF@qY;H07T_Bf0ThL9?vsmDTD=H}|65ok!wA;lB1Oeb1Wkv0I1vvnBt7tw$Q1F;rmW^DzRsh zYEsSG>oU+#Szb;-UV9O2b4xhdTcNjkl9N+XmY~@roi-T7ntZM{G}o>3IcbCSdY@Zu zKy%d|O|s<~vAq-{MbTo^q7~;N##_eIMSvwGfKQMTNMRGdDb-ed`ty3wyJH${C57OR zVY-2$T53`x<>Vyo?&{iYStk~{i}8A6@Ya`<JS6B~uAMM1hKP7JmE zq*Vt{>h!AebNS7UR09;d~213_zrU{JE2n7{tM);FYu3B}vDI3CB7GxbDs}q~E zAv`itETqTgr|av}o$jtYpJ9Dllq60HYo^iB~E{-Q7nVM|wQG3SXkf zi{IoBlfYY*MrGA&-EOU?|CCQA_sKcW$$pI*rT*e4XeLCf!|0d5??q2PWahwLDP7bm zX%33pOoDvS7<6cEoW=&q4b_Hf$fCTda8o+e$mu_j)@xC+sulm6pc@Ji|AcThaLT-; zL`k&*4LO54+k^)yiz`v}Rzv3ld{!RIhH$D9h`~SrLDyJ<^I_3FRwv>oQs=Ei&Wzfkt?{zlge1pMa$<0l#?gu#*gzkv$L@+1mq714O`^J zH{V@&&#lWXI!9N>DZ?Z!Iq7j8Y-%oDzT*D0%z4>2mMn)jz-3qUKOR8m0P7mRI2U@7 zKB_SbK0}w%$4)4i0{Q%;`hi`n5^~ z6~t_xz@JIA<%&-4@PLY+7!%3)NzC-=ks7T(JRH0dDintLcYm{(m~JO3S&(5f0S<7& zI5X>2E6fCF-}8TNy&_T`H#H`Hz&q?kK-fFTocd|-=t=*OTotQ?iu>iiS+3v{^&Br7 z=D}wQLz3@8eG4wa$AVc(!~5d3sOoph$K%=K^BwL4uZ+y?#a>V8v#_%=9xxK~Wsm$J zZ_)KP-IjmTqDAxLyfJ)4VnWi4St+x2v<$`gIs4&5-*?)N96o&Djk1@Yt9tkCy6w9f zcHj=jYcatH(s6tOa};;00Cy0H6n^1z$&#G|NxT`7cqt^2GGEiZ;6%eER1&)z-fC() zIw`%nj7lP#W=!zx-&6)^OE4aPc}>~sXIt#wwg0QFaVvlO(xs2yog6*cFeNVC66yG1 zU$-H4yl(V_^PhW~0c10irxkxNUYn79+oK?0TLlkw6%`O!&6k$|I+lYpnlgl-BuAxK zAxwSGD4?-#)%+FMsLeH&1P3z-Iot_q2K#4}dW~>(b#)ENH4$p{hy#uug!KYuxeS4r za8(%Ho+PLP;1U}gBB&EH;`O-M=-5a#?;pYTTBb&Nk(|egD7Ft@4Ie=uXJFXtLpFim zn&2J^M>UHCeIoL>;&eKV_gGJNch`>q&7O3livbQ~K`Ca2$6CSoXb5O<5I{evFGH55 z27MW_>&|Ow=DCsqE8=weBt*@N5QO;;EKMeEmXW+He*#dK!~<``s*Ci?6H(+tjzIg_ z#-_N6{R&$%PlrZu$w_)08pR~Lex?*{vXLTOyQ8fh2_H6BTkCmkO={)S zJyU3pMR#Pu-7`$;4h!AzSglZ*L0$bTk3Wqs`rlevbxcb-{P`wDPDx2lmrB)jwv|OO z$kL}`zyABy*)0G;(7QR^I%)yw43bqwZ9wWx4BCJ}3#dN7K0ovku(crzh|jBAT0ux- zCPFux_#JT>8F6S>`;Nu~2b-D>;;kD1h+eI>*Afg5@jN6Pd%s^sZv5O9Vk?#sE+Z~Z zj2}voXl-w=Ht0PK#eirOmRdqFX#20VgysVWX~*170jE$3UhNj9sTA-=zV$%oipR#7 zLvjFpTtL^4F^A+`gNZRVUkWk@er65b0ZF>vf+z;bB-08*m>#saArtE^eH9T!d04{{@5SXHq=Y8(|fopGkv-q+m8u z8Fu};S$SISDf&;mf?~|9AA1Gt|HW%KrI`X(j5JrM?_xaWN)*O7v|kF&6SkqfA(NB` zHWlEo4O?q;Bd$MI6&l?PUqyX^NYf z?-L`SP*NapDfkHk`E-9zA?UTaDqh~5np}d&xx5~A5MTrgOihh- zK54>(8l4$*2f<`y19E{!HfrE1l^PA8eqejoxT)<7$}56gI@DoOhFWw1T68s9G#M>2 zpkJsajW(v*4NDC6RAZCPV6U+oY)uxEJTJY4q_@-w^17CE(vqHMWeSQZIBI$7a=b9b z1vvnJw}3vSfguP>FUR|K6Y^FBle|{^1{z)vYYQ_9mQi<59VRl3G?l}Ot>l*% zWE5&Ge>KU~N+;1E04jHRG(M+NZMDD|M|_w*@XA?DAVcGc2USi0W`>8!<+A=&lqVK< zBgfs)RgumQ`fRldv=vrTk6FZv>xg*l-3Er-VIZi<#R5so0cQnUO;7#F5*9{$C%s2% z5B7x|Gd|uP@b~mE3a4FvGs=bCtZQ)g+?=0umywvbq%Ec`<|r?ja&bxu{JmkCxb$=c zIyskVOA`Lh-u3;K;OWIuqSEOREW?kMVP!yQ>g{{o*n|z)2JI)Y_MhwkH0Be#%hhdj zX%u#I>u=NRZ$niE@#mKOeEh@DEw|9uTZ6xfua=#(Oc%}5^ZFTc1Z=Wl?+9Egv(Kj@W#}RF{^Uu#)GPFv#+8FV@jP?_{ZYku_wC$Yx+E>e@jP;U_~#ul zX^+D1z<2$#-8&Tf^8c+?Q)U{ke6f&6o<H&T4m#CFFI?>(zQ)g%Au|dB)Ham)mkme#ClYd zu;`eQsQWA_egaNI&k+32g8iPJm@YLF_8%UAAI8zW|LeB4efzM2o^o}6C#^H8-lGl& zZtUaW=&AjaFf`U8ld*qMQM`335`S}1} zJRM6l<|r$dA(f!-l#j@e*TlYQA9H-BoJv&}GaJap#t-o&oO&RRz`Qgjfue#lAL`>WSg;E9d_Tsgwf`XD2D}doC z`9tX)R0}~N(EVBs(ha4K`xdX%Zv7aqyU8vvlWzl<@pZBV4$hZRVX?HN;B?nZ1M=k9 zfgp=5uq~*i0f>+I#sXRstWbpcE0sARaukFEqm(TQKPU`M@PAdLVRf@2Fu4gs6&2k;)JVOb!e)(QX{iI=3ZiZ_^7 zpy{O^Few}A63l9fw5Es!$~O_j@8jDPLm~ZyLvCxSG&a`SDrk^lISrZ`1U}VeAT|Ne zavVnw2mA)l1fFtg={K3!LQ;6G^q#?W7$Pu@*=D}6GoEAvQ!AD2!GT;!$zs&creTG} zIGkG9O&EkNc&x`K_?^WOmY2+&5+_?|8U@6aN)06sL;!d#$N)hNiDno1L< zR?4zSnp&NDjC#&?Shd~iRSKQFGrz50nNyw^0ZRUrk5Dnlyd|{ zVWHh_#E+<&)Fma$?#6MczeSEKc1o*I10+~%6z^6s%b>F=aMHya!jMZk6^LE<_sufw z@aRcH8tkkIGp1L>`i%wT zYh(lMqx9_xjV>Pz6cCwH5Re9W~Xl_q17%o9DBhhyR^d#+0=Sl174pU1Vw(MpA zr^&?tX6~Vq z5@`u!9=XF(5zcU%0D zqcyUk6m@pTWE#JmtPW==(;bVt3@{VIN83jej0yGbqTFdZdF3ZQ-zSxIuxz;_N&{hm z{S~K?K;Hq-3ZD#NWK0+jul>-Vd_+75jD zEHMIJDv(9Noe-B7!-t!RLQoHnA|}LkVD3zDe0VKVx0a*W7mag0$+*5jA$VsuESZZ7 z3k&Zmz$Q04`{sgsAo(Q^E-fl5EGk-Z2L$NWg2i_i6&2mHIDZjBvw2G}z3Oo-uN5TI zD^bP;B-AK^LVvIzpnxt&*H&T`LHYR`(2>>_v%ly zZ@KNP>ej5FKDx~^3FUO>Ey}->_UZjgkRX8`T$H~U{ar}A6J1#=m_$BxRIfpaC7|X} zrVu3};G`r=7eL8x0vt%{vl?QOFD;=4OX6aT;>Bno&14vd7LLb^imR+lNdfC<)r*_{T1nrh zF!r652qgju#G>q|nNcF^H9ZgEz?&>_B_(Zbg@wiUEh&Bo+cT^{TvApEnhb;!3ziKq zWOfU(*7rel@UF#3HZwD3Tqm}j8f7+O7au#x7JN?AAKt~M^zp7`6B3=MkeZ=F1epp9 zrP>I5IB3DX9BeQcY6ayta-uSkuu1G~8dFL#NWMmj0jJu5qOGYWW|EWVp}vg^|DmR< ztZKNc(Q$Oc0_z7pQIsL_^>+7y9+v`YQsDt!n+cy`otaHoSiAt!=wos1vIUDKn=F+Y zy)`ouL0M!b=%VV3ZjFr>_JvuKnzEw8wE4n{`l?zU~KO;7IyeMVk{ za{DU4yShpn2WO;{W`WJgxi<*liu=PXa&XtSDm`=~RLWE0RVvK@04{}`%?=hg8lmkz z8Vhcc^+aMtY(NE-&9FTvHPcI2LK`uf)%a^ITHi*x8HHFNv7a>XrFr8#9$FOiD0!7w zCoDwK^0=ACoNH5JBlO8vCAnM&cVZ1s%3GERLX!@8TgRw|6h1N^8wyI$^CL#33I5qf zVp|FP_5zTasMM(u9}6SO%Bx#F>cZbW_WRp2Qi`%+_fT-+Hu7xPvZ9%gnz+=AjBIRM zPU2i6%Y25xOy&)%e z-b_REsN2^1ZMS9T^K;een5aq9Cx!Fuu@0wy>V;85s6VTa%iSZMQCYZJ5%3NU_Wjg( z!VM}Cm9EPZ78%AXBapuazHDTadScz9Dt{ntpQZ9-V z8sZNI^6tHEq5z-$ZKy?0-m z-PTzD4t0)l&uy#$3FLirI^*%1z#q8hYMx)434@|I+Wcny?oLnlAzSlz99E}j&$qOc z(w{XI+nPyM;kDEBlT&kMxOab82^I$#T2NmjEX455fGErc6Js8jo#Oqzz{EfiUsK=i zf-Uoqz&13zngf>J+mOxj2z<#8;vJ}H)Ijlk)k`8SpbP2mb0Cc!4fb^ifbEn8l4L&}^d7h>&gf|^YcALGCfy&a#JWQ*sd%_~`+4S9VJ^I-?s681zv znj1FwkKxxy8`0MzpD36&)u0`8^!FPsoLBHfCX`qcmzH+ZiW_i>TG+<>NINV<%1f;z zJrK>WF%>s)D{e}|MDz%<($a^Q6g-$kUW2xLE#`@Wd!WH?pG1x|y#np@d`;~}YBc5q z7GLySZS7`!^iC%kpY^*^l1Tj(cjjj$kmCoozJx!#jkWe|ygpmK^?;y^nVVmT0~RM* z=BB2mKy=1y$4@j&$6hKaMj1HO1!4Kg>FUS+19VJ3QPJ@!HIpt(MXfTd#)H0qOc@@n zjmIEQ7#FD&S#~Dsw9)W52YiEcy=E;tUznSkG6lSp986$&%4PbgiQ|;y)KR4HlJBZkxL3QcGRhOI>d}Uwo)hQK?NW)s&4cx)iCVHEStNEn3vnrWi3|#1tcq zVGKhU!ep4t+~0F1gFx-q?!Ev2?&XloWafOl@AE$I^ZkKdkQ+PBpVV7P9y%OAP7mpE z_%@mJIy;ZgX`ZGT*+w8|=s1Qnq|@XF0d06VcwtS={29}yBb^b%jEqYr|A{~RjzsR) z_I7o>&C#{@HU4^Q&^GR(xivPc9+-eSj9fx289ZZ@-DV%fE1`CFK4kvvXDf40%a`}D zpB`pERk5G0V?WJeKRNbgU$&s8cJkgsiKuNt_6tA4-*RXAFgE<;#rKCp`jNJ6vc<@{ zG>@<3J+<@wa~3XKIO?V6RLHOQ_M&mzq4k5R64VqQ_bMu96H5u72-?aoD{>Bxo>l!dLHq5rNBW-nk+$+% zb8&s7mE9NB6PB;nR89=)qrEHU!-d{f(UD`XdN}8%(td=zUB5lcrIBK>He8aGk?fdf|Z<|!pUJ_|Qu7FwC6oa4skQUN~F*Z1M!R6#+>#IeC3qSW1> z1*(hLOx5blw_xNr8Yjav6}rf3wb`|g*bRT^9u&KF3abzeACu^w$wYQ8rAH3O2IE>0 zPb?Vf*R`VugVOFn5}l<8#3Lq+y$WgS({82C0VhPl6T26Ax8SS@bNuLfb;?C^HSP%m zrVw9p59NOb$-(SMZl@T{tkjp(CZE1*AUPW)a37w3QBg;(#vpKw=ELF@)*7@G9Mb1_ zmD;X#>Sc&ot*IG4t&~6oS71ID&*r!V*kZj@d+1;^&-|p049@L*x(E5NYjCiO(g}m% zXmYSC;uwqs>s9XBqT+bGIKFQm&P;65@&m0JkrpN5wV3&3;uWMLEUZvAr}pHXvzb(T z>Kkev;-Z?DiCL&5(sh$ot!fcq>JeLMM2W!)hET&ms64?dwP&)E7;nd-;04Lz2#0%m zq-d!L(=W2mZegFz1g4h))3bTz?9>8|+QNp%p4-v#i~5EqvBC_#w*k54MrOG%wNPKT z;r>~25}I6&-@5s28KRP!=wAUe9NLD>73%)13KrO6%tM9!9!M$2I(2`rQoEg_5VE`} z_gl;BR$N|p({=p222k73UnWu0txTK3?eM3fI701BfV#zQV#{c zk0E7z?-6WI@p$+C{rlhhpx0p>$7UO+c3Dx8!x7BqiQs=`lZyg* zS`ymso;0EOU=+XO{`cP7Pl;=8iW$X(_@{yRr-AqwAfCzNQ1{PM&!+Z+vOi09mbwdl6zQr+_TqIg14!hz2))|D=?k=Fgp`z19Is6+2d0?uG)n9F zI77S*+V+ipwY?%4*0#&&`J zzea?F5yjrvF_IhcPmFvq__>IYi~Xe(Tq*8$PbXBuj?`@aNQWHW@#`W8V}ffVGnW|TaHjoUgZsSGQru@3d^Q0bx|e4=QD!G>bsV@ zbJXjzXwO;`Jj+F(E{-NHkbk1Y@lU7Ufdz3g|KsDGkSzHGnpI9neL=G$StJ;ZtDYjn z>NT~V(l$G1QzqGw8U?hT@zF|;YLxYAwG>9QZusd3YW#w)jg&&P-o9YG`k;9O;@7CA zC!TBTS7*(-X~~j>pB}CLNMhvLGiD*qY_ogVI*SoY*aD{8Nl0V>=bP$$>%BuUl{0Z_ zY3ZcVR&~6mGw9O|1>H28T2fraEUcAUN1+v@+*E4aT8n(cZ|chXN0pvCX{=QZe(-i@ z=lB15XLn6F;bZHr)?;Gj ztx%2pu}o@*0Efo)TEtNegw|^wnBZ=5;eDwvB&Uj^vu@4MDpiH%;Hp$PXSc91Te!M> zy(*>23deS>bd%WzRNGWKmz9&xN(G|9heebxF~SD_MRzug^he!>$KZeW$Vcfp+{zsO zfjQJMhZ^Rvh&f#1ES^NY%Q4xG(jq*O)2G{de%H9seO_T#M+^MR>n%HXRCjD5hNda! zOm_Sp;{~oDzrR>hiN1HbdU_9j7>T+r$4s%PV#ZXSrfe>MQE90|H8%cQl~&Cpzw*+e zXnSMul1R@!^o0K8U}x7G1V8N7-RIq0*Y%!OQZfV47c0l!kKFe6`Qp{ryTaFT$C=9O z4~#Z!lP~g4AVADv@A(Cfe{9FDUIN(@UH+nujt^B`9UyA{+0I?N+T->M>Vj5}=c1~` zb^mjb3L;c&0NVAyS&kIhpW5-I5!bf4bLWxp=!zUyHPI zR^&wJH0;ijvAI%9B#}iWr4u-x!C#$fxySET_O;nY3j3thekeqvW&}eD>0}x1;(#aq zVK{aSS$D`rxkk1n4uX8=*aAfycPbh?h~PK{1I^vy`NIDZP&s~eJfNM3hg44brbBw- zXxh4aEh~O4E54W&uVBTcSMHSQ(^=T2=XbTf{43O!)?KZw%}w%2)0+wB6$qW~#DSkT zvB-hE_V!+BDt#=X3haR*Ye{*zO6#tDZb2$f1pSk-VcCdG6OK&y6sBurES1PAb{3B|)bT&`9Q-K8>g38r533&ib`BauQo0+{21^t zG#3e0BdCd$O7&w3PGj^!;CLNytmWymf#Yn!=uKs1<(b?0=%gXpP z(b??t`M$fObKtBpAzSFWE=wTKUZ5h!0P66;_I7{1iOUxz4*VF*-g+Q7etAbn``%u> zHUyGU88Jr?MP-_kevct67)PenpIG7tF%?7nE5j)&R z&DlYq8PsyI1%gKQ-1Qm=ZJ`0RA-e)OB$~*!`t8&YfB=Em#Be731(ZBKdR!UVxil)V z;sXvs_SR?yTS3=@GzSal7P~d5Wr5tL>{ZQ*T*Hcp1T%{jxsnw*hwv6K+hs%!zKI2* zx3{+TGF!M~3t+kXrI_=gnU&4We;{Mo@6KZ6g5N_)r`Jo2!40WV7%wbTdK?z_!ZFa0PA-nPldGAtFMMnh_z-L9AXFD;V0~bdi&~S zvnprKs#&u5>T*Eo2Lj?ky2ql^u~bN|U)e)Gfz8<|#a5Fo&wg`GbUE`?)JXRB_QzNi zI_M?17@?N^6JjZ;#hNhk0~jI*I0^Z5t0n2509j#6;SMI=_jrGA?=h=AIy}}TUH`t;H zmhoxJm;3X}rS3{10h3+6ys9iTX7S=(yI7|_n|opHjH@p6UIGT^k-8D47)p2&Q zbm0xvtKqwSMYNDg;2<@U*+ygtFcGo9C6Ed0n)JLR24@AB^^eS}nt6$}{o)>HnWy1L zySv#`-tuV^91iBbx3%>Pvq{8E+Mt(^N9?e%8CS2KZhME#u5vbf;F^?53ORv zhjt9UeyR^`qvrKqZQ^hXyPq(4^LT**!(K1Buh{B^GVf4N1{<7GXBT%U|8#-?5=M53 zV{~@#0d;)cSj_AEQ&EjzDxcU^!vrXCyy~hAahM1Z0?TSCX$`X>6=_ zNppZ@Rw|Ng+~{tVjGI-&Qu+0236Au*Lt1rr$g*tN%J3}Im`3Ye9UUuH^j6G*Up4qB z0;abtp>|t$cSvjYgjAihm8}PBJD>_75Ng zkOzsEqHJ=X&ob}NGVdFiw?t6RVBUqM7yOa$Z}|R$8#mmyX8rvmmQ!emBiXSXiU=*Y zcKsA=lE6^iLHfFda2rIxc);qJ3(K!Ar4q+{-YoEj3Qa%x@>^GY`PLOH?pVD#V_ATp zhEv|_ISK1%+_Ml0KoU+s$5#-bcNK0al@qXbzlgy1LZ{!_yOTH1wga{rbKj?Fz&qyq z-a zkrIjlxs_i=?ikmke3n32M>z}VfgTL0;rp2<(zS}OnF7)oDktB_MxfKU zxs<3>eabb>3>lc_()Xanb{MXyH;RYKD7__8DZVV9oJVtK!|%0Q9M9$ zyg^F0*))}u9VV9wO%j{|Sr9}p8<43%Uy{Lu%ENY=htxRGkIfsc3#GthS+~+W~DW#>*^o{?reS6Duko0ZOZh!WPjq=IHm%_%>ii!$Hc+bCW zL<$po!a?G`jHCSuon*wG@Vk%g3D=bbr*w8MU%v9T>np3~)j;I0tE!r}=r;6TgejNW zhwJOOYuX~=;{i*BX-`0nj~?fqiT$V86MoBL{P;jng|7kn9f(aWh)=jSd4CX>CTo$i zyrR_Oxo~!Mb+|%>vTmJKIs5vR^GqG=mnNs*rZx&?yW8lG*bU4!76Y3COOmlE6tWZu zJ&AatKY|r|DDEdEObF^=PtSqAnCxj+A&iGR(1k}tr(vRTMGi}w6)Y%VlMTDw7)}}k zG1@d@RFsU)&W_?OnAGBRW*&qCP$IrHJ?|k#k&KHE`5pztqE@QFU zE17o)eB{u+SQ&D5bkx-?|5A0uoNH@5p7TrR2}`T?2eR??0p)nqG!Gj-a$0wc@UgU( z_9{BANQG~i`{4NzbJ>$>qwY0%hvjZ%5uKJiNQs+|Ig80l!D0z?U`K0A7Pe+hUd%W# zln94WXg`X;<>fn5PqU=y!snTxM3LUY48^j%kQq+h=pGgB-oY%N+SM%a0Y7@N`#km2;7>{>8+S`@Rl$a)d-+efs_64g=&-JqyU!*W}GbXUj7{BTz*0bpLCDoty zmR&G^$&zcYnlYnh$yZiTv%`md`5{G}DD0GCj{lWV3(Nt;u0{rj5`Ie}G7w(_JI`FV)_~a3u*0vG8!|l(S`M4yg}QCFr$2<6CsEn){FoZs-Ya3 zSRHcoM4pJR30u~>snO_>L}X|nb^^-c$To1dVwW}y3WM0`Ph>R(YJ}aPsL*yr&ugB5 zOh5FYp<~z%*wDw|zeAMwQ#t9X2^pzD{K1o0NjEDwX459OTZsJgZLhr2*7Eb;^%P)U zX=8-Tmk089Jp+ZfyFNyCQfjc1?xuBJU7e8Z*=1#)DX*G)e#r@n>y>lz#*Kme${P{N z{&}@MC)?0+OM`R4%Cs#3gv(!CJ->2RRaM!!7nM$%Q5(EZ8@5P1?`TX22s()&WFP9I zWkuC-ohr+Mw-(Hc){u`ny@4Ei;ds~hQBGw&j-AHF_wn@i7PgVdqcXFL!BLr6W*3rm z-p~LRmY(Om5PJf9@Yg+gW$-GsD~PlRaX2n&;x=aZOmJ*_dtDvIfH&T5e*+W)1Fv*O z+NA<-r37)>VG=ICHvRe$V}QDzP}x}`1m$?WRaG-eOV3}h-26Lx<p zh(QJ-F4jo0uqt-!VEEmB5P%iBmwY76o(RaYQv4Ko!&Wf5B)^c^@m+j`{*&j0KPufN z0OUb}M{ulPUshV*)ma8n37KukLOH8eb#|_%fjERCGz%`cDJ0qWrCw8u(rO6b?GPR5 zUVkg`3y;XNN{u96YYw&b3l%ahInhN8PlPQ|F{r5n1tyc@f^ybbH!T|JHH2?1%P zR_ix^qolFKp;7H!t30KhE8U)s6{~wo-OI2q1*1j3VK63$^5H{SoJyE>pj!Gs>$zDyV=ctRVyYweYrPEt361^P+-WOcHtB zVMH0cJev_sWJCp>gTtyPlIQfYhFxX#lD2%O{se1@gb|Ca$7QPjV22F=;{^2UyWdI# z3*6&|m3vfH&o0)uv||z3~3SyD{eb^5TZ!8gG=)e-c9< z+{=m@!?rcnVoW#<;!?>!vf_F0IJI<|Usnffid$#2yKtAo1d+%L>yb$+dmW5F0k0@`4F;oKQ>Z zgB{QZ^{3zZF{`rJU4=Pn7>)V3vUtq1u^1Lb?Nr^4WJ$}HBk6UNdf-B3B$DQ2U!{S8 zNI}6qVt`U#@~Qj%zI1Ns(`xeCoZY+IB9R_e&cn(*`sgm#T17lMaXb>;BT@EhDv>i5 zm#f6Ome>CNL4#MJ)U$cgT%L3-Pr8h?K~hmJwzO+1G&(o@`WC{X?Y*yWMUUOO6Uzy7 z!?I(C>h=5bH@5cJJ!MrO(%iDLqCigWMDG<>SC+4@uMfF;dW(_Uz6iv+9#-JP%R*wtNu9Cp`TA+5Ax5kkQu z>M4j?E4sw{Sh^1q`LKh(-%uan0^ixkE*rSmE?Mrf`$RSkGi=t;%3elQrr58 z26`9X$h;y~VV=#NQ)sv5Ubrf0Tp{UK1^PJWr+KR!lMP7AE?m)+T%3M7X;bAfav zJq>X&WjS0fGB@Z6G&mf((51h>r+vlOu5uk}ZEYQLcXhdST>DYiCCiqzxA#~}F1{As z{Dvh}B4| zuB%)2xhtn%xv1`+ZWb|(qY<9A8OY1J93gh=5N2};LE1wo>i|B9D4(^lQcrW1Wafpe zcPv|2K9$wE8^V=mW)zA(f&9(_VCGK7qC=sxV+q7GHGD)`oeH1Fbcjqxv?X>wtHo;f zQ@7QI3lPhvHII5Y+$|nGzD7?P$JXGq31r!eBoI|n@$A{5B71H&`UqC2k^&pMD~8M3 zZycxW0e(^}=y9xQmH-tk4Xe`?l!4jSYB(*GRXjlG^n>W{0ZV^0V=JG=>P};Ir5=pr zn@D6zc1cM^M~A&0#sS$9&#KMLSM?E|rA{u4ulZ_1zBcuIGD;k5}VWJ~{z7i=W^q{)B+;3mCifsYS#ikJ* z4tdIo2lsca{N}Q<9I~jK-sy9yJKL8msa{rh^UZZDzK)Fg#o2Ijzr%{cI2|&6x&3V# z{XXB?Ar-_uo{4Up^F=s9LV2a7m!qF7x~^j0(v{b#04~}F%sUSPuZ>JS24(IB{Td+) z5+?dHM3qq1$|awf%H-D|cZ>YCfyR2tHKQbLJ{CK+xA(x&gkEGvJ@7jc4v=c-cr?a0 z*k}NwAFH)!6Bzz5?G4xCFjQK|l1L6G{iCcW=<-R|-SFXKxI9tI3=BsJT_fAmDr)T- zRV4O$G7)hF4JB;3S!oLX6`(EtwADcSMxZV6^cS}8PmDtVPVMbz^7)+Oj&(c-|6O*O_GeP7qvsons+kydefTk@8|EOdl zmddqHf(T@v&8g=e=QNi(rE= zO$pflj6^|5qigf|_$bKd)sitaOe5~N-3Fl%zd4B>&Z2yqksKUML~-}$I|X^Nbn!Ye zW?D7#09<`GQ^z-;KqQ-?oAx9^X|2cwPEd`=e+=)vyYTZu`Mf9UT|zuFz249juHx?g_O=kxu0 zceEG;NOtdTgdNcm&>zT!1tu9f$tRRIGUutNc*&xaG&cUUGps(v^`BDV*BaZ~|7ds5 z!~(FW+?~}PEOpz$cnLn_2mBqdyDt^Pqa;G|bN!|6-2E`HeOC7sw~XMaqtc!G2Y6Y^ zUH%1V#!QTnI8m*37YIU;-dHk_J3L5xK>T21?1sNYqHSEpeh_rO;ksm1dHGob-7mt| zo@nb%mIt%EQ!lGocE@!9Ls-%y#NX~hqCJFo6y@g-?rAfEB^? z&iT*A`0T`4Zs^DQ!u^9uEUGp~9uMq^^!7z#$x-B8FxF(yl7%DN9CwTzNennlGO27< zTHVJZV1HJD)5gA~8djPLehKXRD%f||2o+oc_LX(EZF>mB`rgl8Z|@%s_ql&-`w?`3 ziQ}9lpMndG>hEa%5p;29*I=>7Wj!cl&^ny5IVZUb14WVjU0pk&OMATD^DwqfC~@Wb z^H;2>^*SRsB06oJYgPm;WtT7d`fL@FI_&gT zEEUs<$I-X17ccP=e0GL?lpbz-_5Fa6i>-g&$UTZ(TetpHOl6&2;bCL_`ps=Uc?fco zBkhgrgY%$!1K`eHXkCNyUWf;CXV7SQBzhZT1LD+d}`?Kz?G5*V36 ztOWt07|3a97LCRX8%_%7XCd;^SSR!<0v}Ykz_@RAZgv9OHxeY11wWEPVl5}4k$BKz zEpRx%8|0}_S>$+18;(Vf4p9x0GnMsh$5=fQJ&u1+m}XWoGDyuc?F1;AR7d)R5L%Oi zhkHMYg7Bc55erzd4Sb0tzuAlO7;hqK4eB;$Rwzvi%fO6_zzp%sd!S1mFvEgBGAjM% zZb_}ueLkP4hF?n68PS{)N)r@12T@=WL*%VpG0kqD=nYzWdxu?Bz;rX|&uOvrLAXhi z;TrB$tNeu#eYm%`z!{H(-|CD;54;nsqEN(-RX^#*=wqx{BTB>Vms;a-*V3R*i^u&0 zovH*-MhgfQ>Zt;lAuD!nxYmNm^p(%ZNnXi}mdb!ZgKY5~;VZTGGDfJ!t%Ud)k*^b*T55(|q$lG`i>aeUZUY1wf=ANVzrZ z7hUmq?)0xpX^ch;PrA$*LH#F~;bR!frHcwK4F|K#%F=bj7K%P3spfPd2;B+5)M#yP z!z6c@ImS*TlQC+%s4OFia}+C?H9%`kaEbs1b!23QlKnB(o$fRt)hZD^xd0Jg*R_d+ zSbtmdH7LsdZqnD=`9krz#Wx4cmt&P*Z?0AdKy`|X5mSQq1}s$J zFBq|n$+L<^o+X@A>Q#SiWiLP~?+Q9NhR1phdh#u=tKP{i9C* z3hpgdq|3SUf03x(*=A18jiUmae%6i4YEN^^u05T5f3t1VJ(XmvE+rRkMd}+`$Ty3; zqRRgY5xp6B+kj!#C#{dzq|*x|7TGgaDRWhNmBMmjiMgsiSy2%>SzVv(n#^-Dc#ytg zhn!S(5)aNeH*@zi&g_zNr;ptI<1zhN%t>F>DpysUe8OMAv{Rlk$~g}Se-ie zlcSoeG*!t?`z%=UUoPTfHaX7=Qpof2(^PDs$;I;CLp9;+R zM10G5oR@+R|1CYv`MY<&{$@{S`>vhawlp=}vk?E&a;gthQO4lv)R*~dHFZO7Hj9p~ zNUhHIuiv=o@olZ02gBiap=@Fs`fu)O&SFQO%9qpl)h6qnre?yIM=&enySCOGFYY&! zAEY^&3=VLbm;DJBIh`Lg$%%iFQvYYiwL_lpr{g+F;WP8kj4M6=^>WqnlN{tP&isBk z*E2#h_RAlW<(E_vKTQHSeI~tfj$`DizXIX(n0Ct*XUYM8W@PCrHpvxrr#{2x&){~J zO7DZrsM7Rrt6Y&@kH2FTx5!mXPD1Oi^5;`#l9qy*|LL$geKlI-{%Kl%%I?g}Aaibd z27mil(lBa}d#^e<_A}s_x%dB{=bpYo9Wq|;$eOa8CQBp8=1d6weOF~PBk{8SeVUPF zds{mu+m%{98v9C-F+{WbGpdofAH)Ym&dp?deXWaB~k^ z)iBpQ!vX_QG7_gv858C=d>{&8<0N#7?FN(IcP5UpSnwk73MY3NVT> zoK9O(x}?dO`LS$b!xKYkJt5=grkt6|1}dh_fNr`21N~BI@0&igIpgQPhjO$z`}ZFR zhhqyDs;Lsf(EO@xZMKi@4P(p8>22Y|W-xXg?rqYW^tB@z=}h206S#kxCkWgx0`6m} zyz0WzXzBgUmMvvvc|Ff#_x_jW9cl0O)~zV4K6}INn68Pf8WXS;d#BHwuJau4{qRg<*XX$(@^C3y;OYRM=Zm(wl=>Ge7(qDQ_3M z_3+*n!jPYBX?Y3<_RmP2!nGXj?lApYzwD+hW;vcH<(Ul_=XxX}FporSClQY$o@-~K zx4WzMCa*2Rd3o;6PPdMoHSV}@VO7`uqmGiPS72wYUc7h_5hv3pN<29BB>!m7(xpq! zcN`|95a{KEfB)o@Pj<;SfxP4WIEx7D#l5eEE?i&#@aE?2P2a75Xlu)^-*Il_-_P)4%^SuFqq?u<(Oa`v!H998NdkpT_H%u6MEIgPBIidr{ z$@?7YCm1jq#|aU`>`82jt$@G)oPvbKV!F@qXA|H_^tWsjVqMqZqo!gmi*b*UU0^S= z_@z4=AqwO$8Ueet$W=txND5nuP50a5ky!jVH^L!K3PmopHB-YXnNwiij3i*(;8rp9 zugS8Is}PT`!v;)efrPRQ&^I8xucmM6q)-L$3oUmG5I2#>&HFPOgQ!2=x~JBXC{U1S_c zxu6DLH0^%v_|hW;%|=dyJZ{I}!JgWi=DT$a{n;g@Q_H%#Dk`Q|*DRPdecrX;QiWGM zNs<#v9fP{M3vKT(o7cO0{q{|pB>dIwb`p7{g(myfKGf9QyycM%_dUJi^>=!D_H}gO z8Y>}@Iu_Fpx9xcP!2sE!!^9DQGz0=Ypbf>=`P@JOzw;j?$4W1jv?W5xYsz6d|6#84w!;57t22 zDa$Y<7m_uAXLCf7_yX%L-Kt~{OVuga!xwbCuZrii%l%6{PObJ%P&I5^k+pr zIBc7F(V7W+S;4I3%WuS0SU%NVWKdn=vXT=*S6$v4>w@Qpf_MM$mz~k^Wo4Iuy`v|W zmJW4x{*grM4_<9~^1eX*LqFcJyRYY9=Zh^*eOElkcww!UHBdHj5gRxm1|!iE0roJT z;L|t~IzM_`g02TsRs*ZOLA7o>Sm zE+%4#tP%3xB;^J-9VwZ3UU2LfBkL%gpT@Y;9koR=5&O0k(NDL~3&&OMY7Xu8>11m7 zPktC_i&WHkeR{*Djs6@T8>qY-Wgf$Yj5@MRVF@(?Cnzot?>&E0A2SC`on(FL$WJ zAQ_zFeGo089A;VTE2^t613fNwJ9KgB4mc*y<$`k@60$_cW8R;y-11CibBaUwBMB6k z!oq(f5klk0#{sG4yB(6^*rPj2>&nZAsJPPD_`9B=a$;cbN`1Tdp2qDjLL?3h*~XrC zaoMHbv9=++(;dPPAZ}-Ec<6^)n_J)Q*xR|?5DYN0ybjZ0K~b0nUvv5=!g zf~`eX6_yZ$tPh1mHp-3>M`BatF2HW>5{k+RNlC%C`!(xupu~uTkHiynnk}GvNDNR>a{u+iIi0dvMqr@!f&H?;41!nY0h~QVkn$65N zBHm>!h)PJ{^3nVyNsX+GLaU+mMEZ~6;9@Hd*{$OD7 zJ=r8Vg=aZpt*^7|{1c}_?UM}+|4K|j+um-1+%|3c$(|maSjWPH9Zj2pUhl;hjEi=? z`29fWzQ++A9^SCwm!QK-yLZ3Qmnb;5taOUYn)ql>+wRVRL|!RWVtDANgv_bq!U0AI zg&C?MPWhv_Rw+JUhLwB@(vo69U=2g>QL6y=D*C&e+-#~$hb+ne@`DhU)kIx1-vcU~2cS7RiM|?Z$5e|Z4n;;KD z-_6M(Q%nkR;Yoe?lds&IzH;iwmHp8fZP{5b#*QlPuAcrx+f+t_7XS1~Px#-Z zK})3g3mlITy+oy0eJT}z(z))e?aj(9Xm2R>lFK>>=E^}?2l9YvKdYAYVhK}vLSdPy5i=@&Gl5*+H@L-v^p)8zTUC62nUy)oYce`WCi3O)(?Nu)ylfuQ>EUIl%3sq(&KzHwzMA86pB&#` zq^)o!>HcwYHYEIwoS(7uX67Q1x0xs&&sJAUyRpl&!+Y|hj_KWAyHVOz-mX-YnX#f( zt}-LA^i}3Ou*XSPD9n`@eiIatN|34`R$vp-e<6y;)vkLpQ9RymyWUnt6i>Yw#X~Tc zh*)xCZo4ka46`AwC%vySGmw7o5?yub45l|sZ)i6fot;%DXV6yNR_!t>d)%#N6pxgO z-e_5}YSj|Vq}E83CbtP2y^BeRh(-Onq^yomcZtiJg48B)d7t7rlSQU+x$I_K-j`A< z({Xvx5>?LE1OPtQ)vx1|-;p~#t-@J{W-ml%Yx+EEfJ^Hk% z#Li7EwW|Kzulu$B0|euR)DuL_N=@k=^(!)XLe`ZFrZ}D6TY^5cZek!2?4vO(B?RM9 zTZSwRskxw`PZ|cNL<3eS!0#ASfCYw>T6BLcH^;9hj}Q8_oOt>SBil-WBpcCsnG8;e z#FH6H1+UBu&4dkmXp?tp36|Bfrg%4rp_Z6mW;d23?aAj&E-4;c?D0$*8yrFx#i^}{6x+f^dWzLbB%c<{ z$|n3uBhWAoL{5#oIh{LyEJZx_iBd#n@11_tW}yvJW$$qn^0r?DZS&XZwEpy~K9&Ty z>Jub^PkvUL+*v$4@+_p}zs-}nMNTyN%428nmCRF4r*>QAeDSHNk@HVdyH7s6`h4zkY7@$)c>YV&n02!RwMc$XQ)srNWJirL9N8O0`)#I;8MAcd=WHSo)n@H&}V%nP`k+(ooc znainn(Gssy+V`9OwOTo5)@rVBSfer!W4}w6foSoGe!S1=JBXBi<{kXH2ba!T!%H=Y z<-Cp^Tp&+0x+y^LGhPRYz+`0R2;}-~Mj&`25pvlAO;5SX^{=t)j*^7DMhi!SYc%S& zt+6=zLDevBQy7axy*NFj%M&4|GaIV=!OJZ_Xr|vW!Zhq?syhqxVEzkLJ z^G>1tKW~1Tb^%!)_j;0xu&eEEe+BcDY zr+xZGm*FqC>>~U01m32^bUPj7S5&PNFICl7uO@)}32YkaqUt@odx9+Pug)*8RJ+WB zKeO(r;olvzId!wz6|juGvi9q9;agJRTaHJKuh(8aT8%Ud%2`!A6FX|j%-Y)}P}cJ3-$=%E;eA^>TA#s<_)KfZ2bldnSODYM$UJsQc0b21-cta{ zx~jIKqM{aohChsNVn+R@^xoOXq|%l5Hm9vSYHjcyrG=D6?e{?D|NTB&^ytx}=8yj} zjf!^~h%wk7IZP4_#qzU~HUr5@Y5cZPG}V>^KeL?}B7WRv6cjl|6^ONn8{@J_HE2>F zT-u*&0j1rKYYVG0V6X*X>IN16Mb&+m*&9T%_H~AORjS> zkiQ3uErP|tGjO=%OdS4CqPPW@*O#wB>0FO`n(4;3op<-~iBJ3TwUtmpIhsN8o7p6l zOK;?xX0)1+c{~Knn$$DoUU!ciuklwCy=f%5MN<9XFsdo*F3hWS|2&&-+Ew4*xk2u@ zV-~9M(`=A#)Zv_LiUsBP&7wg=F~4yRQ4i<%jdxg_cmB$^|DnxO^1!y!HqZN?xWmpo z=|8!{u%C)kRC`Qmk7qU*JMH8iJA63mFOof$N}jgI{8vT$53>gklbM`l<$H@Is*>zM z+A1Gs4-Wm+J!pu@ma->oQwlPD*W4|&ri7M|ZUS`s9v&An(p4GtU$5 zbM6(=pNSIovZFt{c-hB0x^Bt!f7gy)mRhcrn8$d{%BFZ#QM7R6cmj2}hfJKav=Y=Y zIo^TYgf&n4FmuA*Q(Fz82%;69$=UuxRNGEpD2s4tEM}{43SmY??@0U+bVmIec&@RIcqn_@j>wg~RYtE08V((y z$oHJU_knErntmk*MMj}TORmTu$05PTMFz>GyrciD6UQi8_sN&%XD-LN9YOp*ov@us z@J=Ig>rGn7RA35e8EIWw+k#<`OrNeY@&)LgJJxjosKyf?YpJnlQdMB=1UoC;7Pfm)ZW2E>vN9Yv$0R zk0TjPwsYMoUq!OPZ|$zA=vLFGum9Ui$x)Zf>kXI8Sk>7vOGFBzsi~`r){XX*i%w@% zsTDdR`y9IcEhFjkn-)m-dg;ehON&4)WoQi#e3tKOIaQg5op+v8AypnYcvnSw;U;vg z)qbDW+UloS(E8HWmPfHQZ|?|?EpdNpn!_qpO*Dt=65PY*szcI`;}>o3@Y%~jgyV zLG`Nqx|C0p5lZXTr(S19db&rh+dgs~ihYpg=4<^JCN9QUq0tzL@Ve8VDsiG>{S;fY z&(hv5DlPViP7!5%mOhu-@0UmVEQww$0+^q8YwJb1H{XhdAv2C_?v#l*^;tS>l>6ci z-d3X18A6%Z75sWQZSOE@@W8E2kED>DXJ_Z-y3^NNnTNWiLfxaiyf1um(=g`w>9)*KK#6qfy zBrw1ND8;~HL9Lo1T?y5zHHAt0)Rw3UtwjRrHHU+jAe|1$s-1&~-XK3gRK&@XnUldUaxRh^uPVkV7PKrGf|oSFC-Q)q-9NmV>2 zGm-VNy3U1sk)K-q zhRgMC3)=BwIc)c}yo<*C@dp<9AUGd_b2(H~!fZJiRt^Vs2=pf~B9ly6u!y#Seb z!CZ@R&CTy5B<^rr;+^JG-v>WWHHhb6rY}?cqyzhb{Jcn!%je9`U*PlKpZ+=ZzjCR$ zty7Rv;%d_GLgSLdg9H72{o%v(+9WJ(Ak6!L!J!nVQ~WkSpj)ZN@&vW^F(&?X{Hu;Ys8y^C&2m5*tQN%Mo z6z%WjegD9*6Q2xOeP~d?O4;V4L;6rGiLKFmf7;E@fUNB3$>6K_nF^s(QXNwBw$p=} z+EV58>9#a9s7Al7*C5!frKP(!IGdt5F)HUvLVA-{t#xP}Y>o&7YZrA*J)T6U3eS8S zKaa8b#5zU6oM659i0G2hKNt=ARQw*FqD6|;x~AUTHJ37qaz=3pqd1pQT)-&KYATsp z7*+PdLdW=uny#1k8#&pD!@X~8gSd>Vtv!oa>R(Ao=_j^s{Ro5DRZ=qS#^5*)Eo~!N z#U;71p?A8h)eQrL4ksu;=}Li5+vY4>mEzmJyrN z9++y{fc6Hyo=)~_qj_vW7?*0KEow{f2jhqpCQkGijOoZgG@7LQUS0u(Rq0hPI;n>2 z!|x!KN$q@^mt&(NEL{Nb4<+fir;H$m9zUX<`C~{c1}$BUZ90&U{s{t!^MHh8T~ws* zbPcEvUfp}(gAWcK89U|KP0jn>dw0)EJD&<+;2gJP$s~eMU->y?;K$9)$B6BpzX-bW zKZ5oe$oh@ZSshYcs`m*ndUM}`NSBtjdSEs!5^Gegvb$(A3r)U zK-HH)m0wVh?)iIn@5st?U7^x@JpF3y$d|=(^qRR8U2! z^uILZr1Hc>AeZg_xGHNF@p^bB^>! z%-T44@#4LWJeJ$<^5sROCOlomhoVxdiZ!I#BuNILyuEwFNeAYM!eswmz5qdp6c$sB zxyu)EgPR%mm5lm)#!dY*Wo!6l0!Su)*)T742c5M|(Vf>jw1&G!ti;*t8~zo>wS|39 z=Ff6EkH6GJo5^cZrRH&sBh>WLap#U5TbdqY+COai*B!ynG3aJCahrLh%Pnpq_#s_! z<$kvN7Im+VEqxwF(JksFlS=idm!M-cq=Q6{^mcc?(%RbkN@sWPk*IspvF_d9Z}{Hs z?qg>MZ#K;!QuL;SC;=jq%_GA54nAw)+g6U(`0HI$Na*FYgTGsYkNb*KLjy?3@Avfl zF-)j8xdyNyD9A^VqemeKw88|TP_4AJl*&W|Myk|_*s-J0fn!uQ32s2W z(o-gekRByc$Ca#c6>Gc@$X)_uF9WiL1xRwHcqPC2Z~SEM-iGzFQa7b;vaWx8>thdw z9s;6z=W}#KUy@pqbI-qZuHU?M>qG0+CbnQI;cJNKg zym=9SN$c5itQ%8!U!>8^%2GJinG-N#{e2(BC|N1$q-AY!|Imp@UvD__;U5o0qJu{U zX$celu=n8M$dM?QMEb%60NaYj7SWGJFi$1do^^oYV##djpg}jO{vLwkNNI>3rLjcF zZ#g1&H*BMMmOmFawZL>3N}TpfPXJpdgRL3PC|Mz}MN2!S+2M;uIYAUK#?Bp`o!vHD zcV}>(WOD+T;h%3Zz7CQ3`a(=nZ)?g-NxnQ~ zB!8c5GLPS<3?#)mpL)bUKD>T?n0^#n=teOGwQ`E_F7Mwproud@2DPf`6{@>nN&D~e zT%Wpm$<3c~75r}T=cRefCT{%>?C>34Hxd5vc?bc)EAClhgm<|Ul>9C&Nc6#z`&1$C ziN9724xKfRt-;5~#}6KivuOSOl-SIn2hzxU zT4ClGK`gGa2TuLP?kTpp-S~s0yq%H_6d!p{SUB29!vDCrTcjrDWk7T?yTt`W$<|P+ ze{SkFVnjlzf8_T+<~*<4#&i3@IBQF#|Mg_2NHJwMw2X76vdZzmb0=dFHVJ^Oe_5)8V>$;- zq>=ZRrIrOB_UD7TAaRk>tcI1y>NSGMsr7-p6Y<3HW6{KkVIj0ZMYlHqoA%_+VLp}2 zM=CW<9hr~y>7D!b?R%wO`btksjlw7)$5M*Ce3i-ptBw0Z4JeTISgd#7+rRoZ47)pD zcwkPtuyN`Ri!U({3uY~=x!6ANQy~}*ZN*nAp_TRgY$OQqs|%~|`o?l_z~`sa+J)Zf zH{4LJJa+zApk7;wrjUBJIzhJ)oxTaAI?y9!AIu=bYzVTvW%pFlu%K-Wk(Pji1Zp>tIBC4>ZkqO9N4^c&UOUp!9%vgi2jzv z)mdD9DsLq+CP;LRM*=qFUz+BYaApZ-N-nPG!qOXkzHx`OBP(e+pbc1(mdRROFk2LC zQ^}sMw&^XF+q4CVfn;@Z|M1#iwkX`D(mh{oM&(B7&b&$kakOt!1HX6vaPRQ_!>fk( z>kj=ka`1}H^xgC*3K)fW2v2JFj6y4M%u?GliNJ9>Lt0zUEc&uTU8ElrSfkHE)!yW{ zbai)kF>6yPHur@@=8ivQMm9J1nq4!Ow3BDaZC#PPKiPZAgytq+PWGf8p@_+h)a^ck zivRL_sJljSGAs)B3W}Tkpv5SKlvI`#w{Q%B zP9HlKmEN*%&+B_xLGw-v82{Cb|8(8E0~TbO)aiQGp`Ox7535j5hVyNnv<*e#9+;gWjf@aC&wNK=#V zCA*O_ZccrHzaX$ac42;PZ5jKvthV;c_)3?Zl#$c!r?iYL9$qhw* z%C%0%yE9A382MH=q!#7>aNn4(+;Z@P1N+{7b1#F|THX%W-fn4m66^0%EsS}y`UTRT z9KSI4?>1~Ga%{sW^@Bt7>f~;i{*%e4v7bMk{6%tCa(C(i>!S^ies_bK;V-PHFf`K5ySvG3l8WiU z&%)0)nL_Jt;LmRhh)m{ofWLOar?=8FoV={TVLhkFksQ>;h!Z4X%+Q1Sap^rvt{&AJ z`A539Bo-6TU}BF@(o?k*$ylh6#FC0+vyVtFla%VBjis{>#&Z5dW-s!V-EF~UiFRs!dr3~qi_c}3qLZa`k-n9 z*_}QD^;E4~0hb8@ITH?|t!1vsXltCsDP|#tazFM26BZ+UCDUU?IwDAS%R+fdq+cuj z;ym_SoGS8rk->k7MlmNFK2;Mm>gyld`onq9rBeJ1u2ezF zma+-NE40$=yPW4%dCC^n%~k7P<}TW(#p3XQKG!IT>5!3Xj>Uw^xQI7S-n z2k&$SeHJZ$OrhVBTbO4F<&`-tS(G)mj~e%>vS7Mn0-WNs)fV`uI$@iOeX8F7=%cSpykWNbF=ocGS$E!f$4ysVib*`;x^XrL z#F2eYBr*W8JS-S!2_JgxzN?Wwy(dZZQruX#rM@O4x}c=Qeh5i^prm9PhNWr2g&^4q zB*M?6yyo#a^Y1T=7@ofne8`_=Ey9vPt$!&_uZy9J|Mv(Gg-B3sKmw$4gCqSU$GSCD z>?VHFts_mPyI+Y@z|hq{R;Vr7m`<&{LmHfPShGe<6Q7PP6FbaqRiCw?sH*Da4Pur^ zRV(9kyF?xd&XQXy5!s2LbeD_ePM$nDC)V2@c~16S5hE!8mbrwo zy?$8g*soX-^civ6^c$+yOGH&7?%45Ds=?!C$+fvzdcx8_wAzByc}p!sGdmaKypAzr zGJvW^u)jZ-(*2fPisF(kPl`ny`j{qob!I_&pl59r&u0p4&vi>R*cGbFO*wYY8 z|5gZM_F1xhaI}m&)u_`e7K(vL^hmh(U~t^2fIRhma9l?RIi^#lOvz7#J32f2RngR` zQ%9*tr(E+ffKPq@F-^<^))}9iL;$NLL0l??N&1kUDpXUjBDqWGhnHX4G9Uf!(|qE8 zv-d6FQB~*KYwf+~lF4Kkk`O|OaR?#C7!i@ul%{lYB_hStMvIo(l#@eKODVraOD)yC zXHNhTxfvA|F{Ox&)nb4G3&3xE2ea@^te5fH z&7d4_ryzf6%ILkj&mxF>Uwcc-r$>A}d!OI%?B>^iaCNxdBy9@jg_ha^@F@2i3L))B zV9*xe=2P@53#`*D{mN2b_^#%{T*uN@kIMuVG^w3AkdXT2K+lNV91C9XI{n@C>S#I< zLw`6O@o)Tz&|XyVwR|Ig5s!`h1^yi0fa_WQ44yaQmnWeRTg6xNb-32zs-VfiBG-l4 zB-9QGw3$q2f*DW;86S_3I#>Km+?EVR66*`xTlg#{OJ)<3@XO!v3ziw4I6YBl9vKwE zU`d(nq3@Rr{a$aAt;F|`SK^t<6W)aSQlkG*Ikbk+iyFF9S-7Vcdq(59Sb`*OzsB9l z(ev*BpT3R0Qali$u&@r1j3+EzT31)NZ0%aeEVpgjjTzm$_pLW~{&o{|M3paAZf_x* z+~ZZmRvB76JB3g_qIj}{rNL4)n{VUWZ1!O7KFt=C{$mUAhJX9&NRVVP#`$`enhwyEmp+8 z08<$3??VU;!S}^^DTtG5Y*bJ>|Czc*6hxD#;CBxtd?ewgKv`2@Ee_;VJ;=zbI*_Lr z4()!#LqIf=-hNLkLcmM#a3Nz}zyD0v8Mv9-?CNiUbov2?=g>|<7;3@H6AegMN|cU= z^(f`C;Aabz^73-t)~Mn|COjEhI!yg}fW#;r&zw}6{*2w9$`XbSl|3jV&c}8LzYgP1 zziSwmhm{1WMMWXP4iz=-8ZJvGti=WX+9l~6wY>?42@jO;ooJRrIZwv{2@`_!(#3*$ zOC&2JeH8f~g*`290MER)_Wgs{@|zkDzF+(H?pJrb`s$8`h7aDYeS1&szkkrsuxC&8 z+e}pyrft=u^+Y}P^RjuxGa;p%dH1}sMft!^(xW^qy&gu^ZKWO(fL0{2B5hqNTuQT@2CU^R*8@;v+VX+bIR1;!7LTx z^9{c%r>W95{!Z^daTVjx|8QI(;;B5W!W}%K;K3?Xk7>cKU9)FbfDf#eb67Rc;`5bk zKA&gdEGoeMQEkecH*eFX_f#&&lD+RH$(_pDSAnqUQNek5Ojb%x;m2pI3de8jan^m@ z72Vx}+*2suDovlLJbj`hOqRfAD{Qu#3+18d5~i^_BDGUeazQpW>v+~YIC+9|RkI>B zr_Y|9uELO^t@{a&4YXTyUthGfv(t+2%+ax++vi>7#_p{viZLiwNX za|HU#f=AM4&r17G_BqU3hgShfLu9tV%~P>oq_PFrtDc!Xd)Kao-$g)1T8<314 z3 zv#Fq6o?#0W%OLjW=@S&7$?>pVZiH9EgYBZtN~mKrOCYu`#eP9vouE$|k2A1;-Zb3U z5$}9b7J3o>%wpjG5kI~~DxxQ&9En0~5;O2$YFEY745##@ai0AD+jEj{yIh8Zi6X@i z$1Wx$Bql(1Bl_<0cvMd|vF`jprkk6+h*Sj<8Gpy7xw(s{Jnv@D@U37q3wgm_cW@sQ z$iSeHY_xgTVf={rAgeqOCHGp>y{lk$W;%Y{)^ngMBxMS>9*ez>;$Beed}pGYb(mUx zt*wtfs`AVOdiyF`SJ67;-sr&mW_PfKzn2WxM!vTIt;=jHTIYwma;a&Z-Vy{fudWiU zz47rX%fP!H+wtQHlGGl!r1g<#JqE24cPqA{VYDwM?nLXz$_kG)KDEvr?7KMj!#}c0Qc8-5eCnv&4 z)#E8HuAxqdep_3c3VV-LqP;gMNr7m1YH0k)nERWUk>57~Y}%AF zc))PCu|1mNuvZ#ng2EggxMLErAd)D^Bl=wi!2n*>19K*9qfx!g7EDbE+E}k}q?yDf zz4%(M27@W0B>(>(!4%8^X|iv`>?dIkk}(Ig`_i5VZ@$o}&kq#jGM{z;=f95?82g`h z7y&S33ncnX9zqQ8*;P>NvDsX}bJg%oQ77iEOdSmFk3w9C$Qw#0=sTrXCl>VW(rZu* zfjDbtx6Rlw5$6hILyWO)hKUC!5f75Fd8$Jwi2sFyK}n4UK9IhVB>v&uK$tyyy+^p+#d zP7ymBknmQFp48CkU1#rMv6HJCJ9;}Bt0%{LLmIPhxL`%#Vr(kX;p7hM^bLlv?M^2c2^U$WktfgdA-@tBxfnMv$b0{(V$rlC=N&$zjoik z+nLI?ghT_BO0XFUkSE23b0$SAxiJ5Zg&oow9`l^~oB-xkjdMV|c0MSW>?52`i0v)} z1*8~rAmkwIQq;;wXylzX&41<#1Wxos4fMg#s{2eAcHkavQ!8~W`DzFnQvi)|fCkyB zIS|6c1W?eaOn=foX!7E7aX`@@>>%LKOTs zU~!mw{;%-T&%k-5hV7Q_$%=!X^q=LW1@uHfPbkh?SgJxo4~(2%uqV)oIkXf>ib-3i z|B6x+-A;d8R&v<=Vy||;tC#u`e9o8SwJIuu@zaa5A(q>RWZ3^SuXXuMUF7#5wJ`V` zUB(gS`LMA<#9 z*HqW!Yp$z7fK5L`M5fR@kiQFI1g#3vZpETii?2Ab%2nJ}rJ5J9y39qHbx>RvK!XLx zc&%QW3*(PUAjl*^TC|Z~HZDSxpWQVum=KokhIV8H^u)4+aM=hwZm}cY25jObeB(z_ zH-EXMrm>~Ip|;7VS}4|3kIUYIzR-BB=u4D~!G;^M)2=ObY`wA!c3m9WzibS6k0*zi z8f}5P>|%L4`fil3+d}1e()|>82dn`3Ik{OoPW@#vX%L3q-R#1e-_fxH$>)t0NO9<5 zHJ%*p9&G7Bbs5Kf1^Ei?w6s)GEk0!mrUDJrD9d0E0yo`sv_rc~{E&GhI>H8s3K&gJ z@MEoxy(y!Y7|6!pU!c`uiFp{JP7AfYQT zqY3^AQvhHI@}K_bX1lQj2Ov>uI+Cg{Mr2eJCf{;Y|JK++W6|Omv`9Rw9b=3N!LzW? z9sHvV_&{fIhL7+XU|q$Vn%vv~7L*6+!NaiA*5RzJ#o2uWnmXOliRX`Q74d9$M5&l| z$mfMy>Sf+@#%Pn^N~0wDjM^kVS-@-{bshUi%hOwR2hYfEK0?LpoBNZ)uf6hLSzHhLtU|1xkRp5dN==c&Tq@I1nSbwjf`9<7c?tEp%;tcO+| zA8+5j{bM%%o_p>YKYf2yk?MiT(zxJJ=sS)E#}(Jtm#Yr5!{IQqejKd*hbE>qp-6P} zSXb)Ai4#*@W08`zoB$ql$UAntb)X4B2o4|E_j`v!7m7ne32MbdPb)ldmoPKiwBdbg#+?O-46qNjJWYt;xR0%o ziZU$kKa1ed*sWoH#J##*gCP-{=;AEP#gOe=VEKSH(K!*;QHX`2Qz~pcl<;zHNdNdC zuRI3lG=OTGIG%s}n{1fu&#_0w5{;+-aV|5Icu@PUcCYXoR+0GwFo=8pBi!G_&G7cGyqCI?YfBm^T?pu z>r1cT^#yq=)Fu$_s86U6(j+9%Yf{qj+v7ea7jzbYmV2Kn&gT1AJqt zzIU+Qp_j{k7G?RxH)iOnJCcXd1qGhp1%1&v>^{*uC>5b-fs$ zk_z9`6V1)%z3WVU=Yqk=SXht1zVGbk`1N#at6vpICM0n0nh|hP8g1|R;_v(Rz5hjb zble2|-qw7iOBF|_q(m5Y0R@0b0bnu%Frg@UHv%T&-r2MFUK224OG{bVe*hgv6c@nD z48lj;Ht#ABVmouSSlVdW?#rNLS+r>O?Ee&`o*4=$r09-~y$oE>3*YgYBO;kIFe%k|H~ZOi>vfmX81qQ0xHb|eh*~2!L3BY+eE6HYw1g(|h zWguGY#0yeTYj_b)2IKHDN;}DobMs#Gfbw_H`EfUTFbS(p9}v3W)w;B~;SVc@evt8@ zbl5L4Itp5I0lKpm-73Rt1zzd%s?ckN7qWGI1WRyW?+t%gI`qS0eAqMW7a8MJK}Q1u za{-Afy_R};ZQ8d$&ZY^l_!K2`AU}ars#VO|sU4oykr!c+vD}W`t#5QO?Y|bg#q8Oi)qJNK9LI88|>lu*f7pIlc3tqh#MWvhv@;niHx{n-<0&QL)k>M$x`MiK) zDWJ9m4}Gv3^b_O%V4f(i{ZBAY(=ku8(4)0{!oL_s&nu*VnZS;`n4^cVTN3f&5x2Xh zrg2gREafsLH8u=>66uq=Mh`wJy?BIOQXj_pY9vZzptc*e8!!1Jr^3Suwv=R>gjXbj z@A%7Gd;jgj4mNUfeqQb*r1D8jM7)z&H4;y;gP%nDq|(Zq9L-Ms1@<(5ImMzU=b>0^ zYzON2^a8^_U4QIYPh9%+lEn`{R5Cq1?(D}f`b|ooT6ou8-?@EidQzk|0~(t?T+grv zmvN7^z8#VpgayRq|O1Y0dj%J2E2v60i5<; zUNfTQlau|-95+5Cd6b3qoj9gOQm|b+vI$Yt-Ag{LgHR009S=w>NQSn^NdyTTy9QJk zEUMwYGyu2Q^T@*@S|VYtNXC;AEJ5)^pU5VZKEaV#VcHr2w zl|f_W0Y&ow#Zo|#;=g|lP^@4-%K>fu8@9^!(>vKNNcU#5*PbHRq914vvUTcH@Dh^N zRk5O<73#%Svqd0h7s2)PH|$C2XGN@Pom#<^9C$$#X!qNcm$myIWuBM$+{bd*Zz0Uv z%pSu%m?k|oSNpA8s2BUb_LyeIgQ|RAl7FkseM|*iETm3bG>dITrGxOwJBZgU`uk=C zbEsxp&5Nd`K66_hio5`y)VD!*y$z3qC)lfat!FiOzfo9}cN=j8Yhrk$b5!gIE4y$` zgHM(JT-V7{XH+>gsA)l9riM71LA;}nr+Ut7W~(hS!W?ahKjRANaK6;l;x< z3TW&CAy^ZM^qmW!l?uW`*ojZ-llrQ<33s>wcOdT!vRbFJ zc4ZDuf=a$cn8!BdKrCMp^sA5GuFZjlq8{hT3SLdmT7B?&btPX_4dt!S$TA>d8+a8LtfHCNB@e5{YHlCw*95qPt$CA!1YuK#85y==2d3PG4Iudm2?niO~ zYvFcWJKzZoB?{Na2c^N~H*?j@8XRT`1_`NJXs8pooK0saO$c9c0HP$VN}CThodz9) zKnTKn=`=+`dir~AZ5oI2Oq)hLyh)aQzQWtxP`cb+2oro>J}M)X;E+);abf{PUG9X0 z=;);AX!SWq$6=bzj^lp+@$T-nHbrVb(R896l{7E7o`3$U?qffA>h}c9wMa(^h3<2Tz6zTnE!@dyWnUruFD=*6=(12 z8ke)rVQTy2e_MH&y55#Ue3O(w?MP z|BZQh)z#Ha$F0W;j$28Ju;F;YO~*IvfqjhETsH0Rd;UJHjQrKg=%--8@eS2^Z0c9g zVVX}UtOnmu-|zvw*MER63=tAcBBU@P{_sW+9EbPr*s-^DN9$fZpLe=)b?a=XrTDfD zIdHh$rY#gVY@_%0YxphF<#L`syu;<((du&Mh?v1e75Dl^9b|~s9Aba^h*O@iLxc3!A_FV{lS_R(K4Su@~pXJCOpo+~FaqjT` zKOhLvFUi)}^5o9_ZEgE^J_#G+5i3?~d~<(Wpug?l{y)9AoV0Qk;QHwVI*7fv8j`pQ z_JrwY_b$BeUW6xpT>q7JYWkhhwN#8;vHXQM_t&@f2io?(xp4*ck+$nsL?Q_*B$F9A z<5oy!3*u0yQa^~Z{^iEYYWWtj_J!|0C1{MaBCbB2NI;;T9!bRc1an|SqemDP6gcni z>j#-;)&hNYdtX2?Apl=*pWSoAKwnRHPq2qP$Za;8MS^8>52`XL!j56Xt(@X5^db3~ z)!x^Okilq*=qsE}kLyOj<@)pEKxD=%qyY5~vL}z!e}P@-Q}ynfQ8@H&wK7Vu*rG

Dc{oWs!JhW8pLp3%@a$$EsZwqY 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�%N3ecxcvF*d-IWZ%gY?r~vP2MGR84%$_&WVsd35zG&PIv+tUrWKxkPCQ zX!-@^4_s%;y=CS}b~5x{4Tx2`qoXcu)< zPaS=eI=Y!UnoS*9Hf{Sos~Iz#)Ah(p&u)8m4?y7BhqrC=F^}qInKk&OXH{G}sas!Y z&0x`ZsCI%fTZyWiJ!dQgoeSzkSc1J->hRPy`W^0 z>$7e&-VMr=`r=7ro3|KhMfprrjvvJqGRlLAtI8{8yPdJ%l-r3zGtnu~M7nwh~&ax`Mqoxo6m0vYD zDSEsk*@aC#$lTNM8ETk-o#$Cz=$L$;m}cy=XV1RG*80aMB=d?{JWssVYMV5B+_>}X zt*`y;g%^JITC4Ru*c8fcFQ&_EL{{!J_5J-^dB9PAxkUF&n)NODQUvF_e7TdIo>T(b zZP%3;e^@iUyZc1f=};eoCt|_L)pPO$hRtZ`L`!RH%ZZSZgc+(=w+$MR&P=G-T!Wy1 zN*XkX3A3+H@eFs_G;7~UBLH$u3HKWeSg3e5TGdED_yWU<3}q0nn+{_^5^N77d?a=n zZO4@y44w`<(lSPk${6m9oW__r#NPMWM<0-rptmm?WvcA&k4Au0MI%tQ_G$JZX~xq^ z^cS%?^Vjs$?ex^8^wj(4sXlt@kWD>WGsC&*RQtB)_po;S_4*z<=@sUZ%@HlpUTU9R zg#CwNS*R3}I8tVlz~J(tq6w|rw{LHDMmDV7fv0S9F?Il9?Hp<9p>8C=JZ%F?q@4hX zKQ?}F+F~SXXIc)twwHQOZQ1^LmcWExeK5GBw)WEtr&XYZ6AM4MyC;3x;sv-{r!H7L zZD@N-a241^>kZQ`fIQL|Qoi`Mdx*VRS-H4;Zec+|LE+rR`X0RJQ!E` z;F3v)STX%MBg1z)I~OQb3Cl|=XHVgPId@%&Y}llniXU64tuB~xY}~({1STN>gmE>ayrzHg(#wG5Knb?Ih`&g z)Jfb|OJ~TE+|}7@cP5WWi<}MX&SZBo-@4sSOYfO*YMRSw4XK@7bVN)KkfOvoqM`K@ z)21=hoO*L>0IBDIlO z>K^q%$G1=sEd9>l6(zV{V+#KX)dj6o0wTvW8xYO+dZz&oPQQfGeanYIYENWVq&9k; z<28QmbZ^l4`qi8_wsU?oArd5*y%(Qf?B^a-t^oZM>tOZFd>^2jzsd9eVOEj%Zz6yW z0%CYw*>9D^OJ7?t3vK?GIP_U_(Iu^S`ofLjaG`i+hJc&Q9yi)^ekRtV5u?VAPWEJF z`(h9dzTcYggN4~Ft3#u&TUmra3#l2%;tqlpB9VY?_@qgm`aMm+S|fh-@B=cjOSumq zausD$TrfYVPA*<;9?-O>-ZN>^aPt6VveZyabZ?UVS*3oLr}-P|1BVTZ7J2X40UGf~ zfAxOIana3jo7s??vLaf>%q2^1oSfeFH_4K`uN_|*+Nw1Wh-g_i#rLz_e32vc{`NRk z_5DMhdrynB?_>9!e``y>a1N%8nHk1jQRZq9Rxx4t{A%UT~ z6*{#vRLt=?2b(@@ZEJ0VBmzJ@0k-EV$;CNM;@aUO5s>*l6|IoX*bP!y6$ z1=rFYSw}cw%Oh&!WVNLgwDvk{f49;WjIINY>gQ>*B%nV9K|MqRgL*q!T0TD7mNq~K|C3S1l4qsAN^$!Wl9m5`FLzw=za3u6>xLE%XBQzO z=;0~<;|@MQ*1`WTLra&T#njNj{WtyRef~ciR?1|ED6_!)%U~;wW|5-uU-kT9|E%Z# z>+zNHPsSI9Tyuat8yhaw34NI16!6#Q4ufI;Y#4lbK&AYX0fo~dVtjdYz}0f@*kKPA z`kG(U1}6nB=sO*Sjm`8=ThO#pr42=+m&E@D-%0w$SObffNV9aeXqd zg6(O8hqA9*MtCVakdX!Oru(v2Gh5o;&diLR2;RZuvW4Ual5n6LRz9=u+K=))Nm+xikaVoAA$y#)(LPnvVc5f&ivQW8j=CcOKarN z8l#YJR`<}phMmv(WZp5$t%(~BhQkdVz-L-^ul3g4S%uDoe9A3 zeInxO#XO_d(*)aaKsBET=%+e@$GZboj0mZHzl|gNEibl~m#@wkHSHUBRNnE80Rv%IX@krp8cHlDT{szc;{LsLhpJT(=Mp z_EI!mO}2r#sp9F!`t1r7sL2m#dn+ntpllpb%9XI?NbN%Itd6gvS@_hm9#E=$)Dd{D zXcb0tac{G2Jfhli{T40PrmcRYN!zwcpeM0pdRJ+VA zB~+knRyQNVT8-85K%pR8;(@es7gp{OjM9WQ3NhUixQObf;Rvj{7Z}=(Ru`4EttK2jx{&HASY-u2N%3F$Y*w ze>}L$;pl>v5!;r{>ovpYAY$_RRd1JHaR`nEf7NVjtTAYX zfKtt0wYgn=I~}4GH&w1m(oy{6IgGekhENk|h!V9Nmufa^sKu&+Z&W(c|9IajNr$9N zMMee`UqC6YR(yVKt9-C+-~-vNR*;$kAE|{X1W1HdQCvKOw-xf?7atXJQ4K?DbRDUt z*T_@XV_WUI@$v;7IG!+b5d)=nDw2JKEw_HmW+SH$sWS*4g)@s+T~DzYFDu}@x&n%e zziPI%F2w=M&AF zPC{F|NXupYDXXNOZCx9pTzZ=WLDJ965KIk8m zk&&mOx@Ke`XcjJ-{8s?25ewblRDI;v5pL?EMP|Js+^^pTIY61fv z1GUiczL%>Z85sflzKt9AE!((p8P2E1W5@VACZylC_ICc-2O=Q_t(4~dr%bHANC%;< zsnPbxLA7l67pIXlS`0!psBTyou%~u*rpC`g1X(laagwVhbR9U*g(;$ysV0WS8ATgq z(niAC=Aw;+TXiOrX?gS^Gbw4VWdlC*g2-F`DrIW`+Tzu-RE7IVl_)+i13Sq{uM}vy z-x1DdEypwx2L4&WWGqutxfmUJtuWR(LLEIAVfZuFRnd8XWvpHo)8U16b}08c;7L5E zPW8Ixy5^_#+}*zVfoir?=2zyU0_eeo2lGI-HPapHc->~2!M0JA-3~{0(CG}~N_6>k zA*FQ0y?a}AWd-KE)6eFZpw zD-|rUeyzSsLa^%@0R$U^bEQbQw$8TspGm+$hIUDf(bH!xs41TIwid(b@vL0Ae5J>;e5HBnDo38@U^v*| za_4dCJdEngSus!L)VUbE^P^tl5prAx72QoAu9o_hCo3|C9wPA%{h7-#`|!YZ5^ zhZ>INGPia0Zw~K_`ix>EZ!vJ0_UKyG!|<%*b*14bb%tJdHfYIt)d^Xzzm}GNq`-Hq z-bkp?9TlN+J-FFnBn0!P1~X;0hjV+P81td&eYS$ywuiq{(6B zGbX`dYNlC+VbA$YIjp8p9BhX%DM<;lk3&tXlDEa!hQmJ=BOS^O`?0~5p2PiOm@_@!TCJUtIP$HM3gkYdk8_A`I|TzOfw zF=bqiU#gk)+%EOLy)*DYd4Uf3EUTIR{3X%!$nPS1n5*x@pxmMsszqF3fY_Hs>T@?r zc>X6~YhO@re6EPA7#dA8hB&O^3w97zpj+c{1=fIKHJ&zmghVF~@IFX1v`*2=m6!bB zNh^?A>v1_6)zx%*Gs}Q^jDuqwv<-VIf_)S{M{P%tqn_a57KDB^+{|!;u)?So$7f7y z5$-eFSB@(Wv%W0{4mUFav17Ntk+KGxFU|bjPr?)OEBvrJe#+?^48(Mzw_tc z?c7)mv&PAH_aFM`qoZ9(8OjU(q1*So{viTC`BLou;~56;lRD`agzB1Fv+|gskkNJ{ zHtQ!8W9W*NciwPyY5BL7>DI*ISz|ArF|TCW#SFYn{^0}*T*i!&DmwJUy!_mmD7!b` zzI^%eV&m(y<3if=BAQ3aI2=8(Ru(^02Jfzlo3*aNeIBEADK(xM-r3dNpWsSxII$2~ z;lJ;0Z~OGvr|mFBF%gmMh6NhIL4MRTHGto6IJ?<7yZNv>T+Srsq``v97Ghb^8wK^@ zrgk*S0CR@6wg$<4)USHVmWO-zwZFczZB8LL-Y;K){CV`MVu@UMlTDR7_RXzyzlpK@mKH2`yY@X-3Tv66|KmT2n3~pOMKagdD~q@s$v9 z$0&DQ12UO&j_`gV{YTTT1Lq_M?uuxL=kl+dQ&~Gh&Cp!tISXX&kF2ZuXQw44x+`|t zLNu}5DkW4%OhRK7XP5p~80k<`{RN=4WB2d*%C(#`6Dgq?NEGv0^sJSkl>^u4`{M4^ z(rgx*YPLz@Aviq=UXk7)Ob4kp+W-}TL*U6Cq5uBx&$@F4(!;Fvubg!^F{Wmn|GTp) z=MW%#^{g4(tCxBgF1A68Cs`5Lu`rkqOZ(2<#RbuYYWuUcuC-l_U5)2_mz}XHRo3d+ z%4Wp_W1j9Q^^_`exKVtXye>2Ui)&BbFEbu$?G(m>LkwMM72I^fHYqJJ@8C?XDtE<_(19d8*&yk$&EU~neFQBe?G?pKz9c!)LDOfGXhCt8Uz zP@^^PZYC>?+Pr%XqK!G3*MsK&g9Gmk1Ye3@NqK;4piLUv+Z*M-@mQ=kN|dXUS`kTN zjmz}{M)LKB>arV!1aEzt9NDLkAS&AGYBf7+fa4;C>pm9|CT$pF>%d%~W%x2It>M;+ z_$Se2TI2dgORk>Vcx4pDnc_mHk^es0O2911p>Q&rlDj+Pa10={L?`$<*C&xB6S+Pw zXK^gQ`@73-D4U+{7Q4{n%EPw1$}3lX|NCH09zZeNYb~BK<@!-~6=3<9Y>XTTr!6bH z@C3_(fjHZDQ}ZUf8hQ+E{RTMUR$w+*MrzzZRS8Wtl2Ldu^?L=&NXdR77&Ag4^x9wl z@|hZ$P(-GV?CLsx6w{8byKEz{#Y`!}w}pz3J*Z2V-i;fPjWzf*zKE`sXx!S*W1GGj zk6VwCs)lhUz|tn;`H^1l=*%%*@7OGFx&(YBFqvCfF(;>w&hWTWjWrU{1iciYwd7Xz z+klOPNG|VBAu`{QAn}9ffDR&Csmyp>$^F#jR_gLr>he1%uKzVl9I8XXzbFaI$ zc*>-a;qF_Of9u+!xeLkQck>K_LB%HbkZtiq=Awy<3#s4Q#3f5EcOKcXW5*Ha0{x<^e%dy570wV>n0g7RdzDoP*O{v<6CpE_2fyP0f1G6!83T+1fE zBNnFPT-EUSd55#D^BWZYZ&H5FQBnkx@q|)smM4r?FFtVaa4YM>jxMs)o#^Up|FEg4 z=@4Nm2O4+p{N=W7uk5aS>#aBICY*pj{OQEt_`Gs-uj_rRtD@kZa zjT<-af^nHiZ6JsC;UM4hlb`(dLp1XU8Z#vK9GT!iQ#CJaev9#Hm`14{nI0T+`F%2QA<*~yZ)?HEgBc)aw9 z#4wgHa;HeQ+@?J1T8=+{-h9jn-zu-b2|Ym0uq)nX&(RwiXz{%!v$PEHpW}XvnXV-$ zw1ywq$M;g|;{D}MOdKKX*@uCJO8Gn1RZ*Fm*^+*An23xRD{EK051*o8gFRQj3>K|SJQ?f4OF{ml1x;eZ`y{soWPD0 zrXLrcyCLxUxl_o`@Z&1cCWV_pEH@V*7i5KK=84bGzlwXQfm@-DJK4(XonSxe?Wq-0 zT(_jUrWuyb$&)+%*3_1)to&5JwIekvD>cth>*}t8!(%6~r@i=m6(*2W;zMig&FeOG ztZVMrWLWgQdv(9H`AA(|YqQ^aq`9uHxz)Ii1{DT078I0x8dx-n9Jb`WkN@&MKbm9w zbV!77NURH81kWjv9#950;^BT;MP9f7#Hzty2qvu9f8(dIo<4#*JdZn+xnJ&3SjH2x zmoLxG%PYyKs8~^A_!BZRCN#CXn^CuvC`@(u3K`jPIK)=NaNno`fiUh@_hslSl56r*g zxw45|*(k0ogDV@%l_@KH*ghp3ZJXk^uUN5^*yW`wjHK*rTgTrvZ*FZp+3^wfovRrW z?W9YQlqv1z_&5`_a8Z`XnMlY;0@;z5ot2f5F){D5;$lNx1*`Z^`Ne&hD+kEYx6#0$ z%8VZ+O_*|is-~x8j7Un$9G_wMEoY7$C-GLavullzJ20mJ4s^&`a)4KSK387Bl~3i$ zB}#S-S8lDDI@NdM_huqR$z+Aj`Wcxv7F#g~3(oULYI#mTJ-@sVNY!2=Vc)*rKlRj8 zzu&j-$r*$ePLyI_bN}_kXsp z^b^9xm+2cmZvB`jqh-;{BA*y$=_AKaykvUO*Df|-bc;W%RyM5oxwSAvOb`I1dkE(p#EvBPGO;6xo~7J5ivih%xas4z?ozfGRkoLUW;=?5JB=&p3P*@K z>*9HYZKy-_jBu-?Ih~$va^`~<@_fc(B9M9t@RLP^+obUehl0(5=kG>ovmDh zm1__!Q7i`XT7Xtu4W1E8fywR8t9iZW?mNILi33LVEs%ZX5!+K@5bW_^9oVxFt-8Tj zT^R92wxV>JkJ#SW8$Q2=fxV%_$7Yc`@U!Om}5!m_TfUbk^AAV&e%tu&IEV{{CgR%sL{yAK}_}aP9YV z?JsfdgYls75#7H0 zo*x$Q)uc(YZoWrAk6ZBMN_o_B&#hNZGA{Rw9D{B&FM7(~TaD>X}_o6>ktE#RenZ`Z5Ta3hz-}w&PQf`qcA0i2n5|sjLGA?gwd<#{y zp{W_pulClaCP-O2K0e&^cf7rC9g2PV&Y=(6zVzi^`SOhe#=T59*K&nIWw?U#`!Ljb z&9!E#se4Rgb%5?cxfmyu4~UhVy_{>B{iP!p{3k~mFIb}FT=~hpwB}}f>AwW=`*X@3 zrr&oM<-2&kffBL@5mbYCd=U)xJ`{|X6;Ve2#5dddZX2J!!sowYuh$S{hgfgyA z+zV2_^o4r5#c-pI&=G-s(j&vHKf;0G(lY^~N}3z_E(U3jedqZ6J8l*Gs`?YN{|=}B zj-dYz_yZ)e2;;kD;>2;qMW*9^7gn-&-tnuGCSm7wNS}ZfRv6IpBS-iuJKL`|H4*H= z$l#6}P0fV36d3=}_5;L{U1B5?MUW zs}wHysq8QLRV9*UxOtV2+d{{Ve3It7V+MA`El`lGOXwan84jMyE}ga9@H?#DLKMlO zv39?sv$c&5c(mm+!?xZ%x^z*(248e2jMsl*&Q4V~z-c`PB7=N=Lub;FCyk*cC70=k z;M#c4Iklu@{+vq~e3Py!Gv=Ff*c(*K(<~LGJk55Dgyd}+`V~`Y*hXg{q{Vo0ey@-6 z-q}0*r$@7uRAk9feTyyAww2=1AJhJ%ydUk1s{JF*mi7MC7<%yF$IvpTrY81&bnxIC zFF&(k!-l7Sx!-_e#GwkC%2^8*%p}t`3Db!2q**iK0e5<1zALdsN>n_JtEnL>YU2AFv$Lv}48tRkTO-17ApYT0l8hYF8`Ess3ziclYr>g{Q-aS(UxC z#(4G?eNMC{(dTdk7AkNs+H3Q&H|N!E&M^|ZCr<1Rhd<~*L!D-*Gz7$%RYV~Kgkg|3| z{)yOEIq4(dBy7Ha({f%Kcs&Gc_7`1 zCJ1)8OV1d>Rr)nlZKIOAY(+hcEqhL~?CDU>vP`Cc1#Lxoy+qwe7M!OTSVzp|RDE3D z#momUBl}1rhNO%Qge|;(gFTNJwHFA|JY!6+8dSFa&`4!NXxnUekDxe2py-%*?zyf zUpy?l!Cwx!m!j*{CIwz?tWTHG{LOFdVFw|qu%%brf5WV3fn-CqskAY|W6gDffi0_Ds-DswZ_=ae)4;x8G?v*^ zXq4(kuVYZ61_t_UU+^R$R5}2C-R5-bBr($ZPMr>F;cCBC)0ECLk$^pPnl*1vPb6R= z>zRrm2XG}$6N?2!$dB)UN#=|n>N)u57zNev9&L=(zt^kcJ5rRf)c`(#niVo^gwrx8S(X#0`BenjIw;4B}m}Ju*WW_y^EgyEbMWz5) z#FmfcRGO*oq?tTi^G&v*<-E@4SHXjv3@AZd?MiNLmf!In-Q+zbIwlvsK^ciV%sIF- z-Z?tWcRTo8I>J8lT}!-+w3zSqkrsR-oG$4Y>&e{we)F+2O2nQT?6O1@dX|5Qf z#9wmS<9@{%Q0#uCzgkuM_}IcG8E5@9sjiOIGh$TjA`>&H zKCw`ZM;2aUR%VVlTo0l)KCXEPa7L+6w3p;i~%A3 zip0vY3$0l) z$4k)F_0fAQKi;t6$5)}TU(fp)_{DSh{@awB`T01}HIfG%{fHRQ;+5Lttx z-M#uIvsP*l@C`_pj(BJ4k@+1PYi!c!BsAb4-@is3#%gSbG%EVgCfp`J8=XEjYh(s= zrx~7+X=x+#rc6FRJuPGS@YLiaBG27}hjR&5yVBVm5a=zT9X+4Hc&e|)XjW}#dRPmj zMnWO6s`p~bv0=M$;8oY6)j#_}y5C0amQcF|@ewL{dbXmc7AQ4?m)^m;>bB)e=Pml~ zJ@e#}<;qI`KXbeftYC6#$-n#YeLphVE@m%HX zU$+`JnsQwhB6(Ex=h19*uM!p?D8XhI%*Qk?R;X{W(2^;+fUU~tN{aw?3!-xhq{$#=)!Sj%3wB#Wx}5cfp$y z8_klN4ny~U8O_fznlnu}m1~e)xAi029i*zZ*%OsBVMlWE2v3^LrmJ>ijip;>nze?H z)@Kij1}u(ohk}TC#o9;r4u>CdvtoeSj*(3+h%++#nj`zU&qwxTdbnuiV!1qzHW17i zluCs-E*^DEnmzlvxnD0TDw@GHOL<1S``Ss^0sIb_x6+WfnwPp44Lu+Gqs)~e4`a)| zpD?_?Z7M!1%};Zv-x)0LmSI5v9(h=jjSe@}I2Bs77&U%Krk(!K6iD#&# zHZf9yI7`w7Yaz`R2`htA29LHIh87B)66$fLg8-P~_!*)!SU3uoL?6e=N`EnTEBZt! zcPncU@tvz)ugM*gFfG5dw5(t{>x3ERX*VbjCoZ3#&!^YNKaFu?KCJPnA$X@)9VATj zCxx$|4lZ@*f@(>~<*ep=qr!CG#JEaI>0MuAIxM5t#ejOEIwnPj(buj3;3CG1LIi@) z#>c)Fclc0@_456ELkT{pIxrKb;v8!@vRZYdvHcm_?->>NMW`rK`u+0?9Ozn;!A{9)c~r*qPz z^ONmVceVAFo6z(;ekFYkjCO@$CQ54Bw(aFTTlX-l)Yfm_LLC{l@Yd&u|2@LQw&t2I z>V^3t2w7!J?tQ5i$bm{IB@_OrG2^pGVVoi3SE5mE(`+Wr_dz9GZ50?~SKotiWUY)D znGFZ5{pOfifoDgS&PSZ4N>P4&Ma7cJ8B7MhrT-o=EFVmo^npL=rEM%JUfF3AIr6t! z#teNxK-!VUxVA6?Sv48z3K>UfFm#JC`aq=7sKR+1aD|ePQKTM;hWZ^Site3_V!Q$+r~=XI zH{b|xu$Hc zNmi^QxF*p-lyaFbI<&>YI8e6g`*CXc^GVAWw7VJ?9 z)Tu6Y3J7%hVOc1nD)X$>J6^l?NPobcY%u0N1UN+&MAKA+Mkw1NPygTGo|q z*idFTtE#5WxnZe1elP>o(Ok~i@4I#0G*^4O%kYzg_$!YG(lo_8YGg+G@ZlaAo2ou2 zBTEQ^41bbl6=QGwfm>gDz;Ew3{t1@j*4Apf#oF897Ct?k4RJ>Ok{YCGr4S;}rw9c_s2C(eN!-Rk~QQu<{0h0(9H)WlE6 z{|jp0XG&c0ZXPtANJbHjkRx8w#A`k7^lF8i%{e*5A3O{Q)qJeR5?39=PG@tC7sRh| z$bY@YVk~)ek)4VMUtuZH2cF2=T*Ia+ZH2Pp+{-Oi*DEWv>}ZpgtyUxH6L=?9W9w_Iu3_*a=?Lb5wA(+oIEqRad<6^)oNg4fl{U37VybpFdE>3?pL3CT~;hr_Sbj(eDmfl)zr@Y##2Q~ zFxnAy5Am3Fpq^;bv?GLZ9&IJ`*m&weH95_1Pa8=%X9iSxPsK*zH>e4T36u4bXjS7B zWL2mT$zJSQ{pTacE|J)<$;S@-x{yWVo2F%D72Ffi=1x%5So$h?z1X#NmU~@vMLa?ryE;LJ?=j0SL}k~IThYP;p)*np5T7Gm!>-- zZNvVcXaDi2tjg5xhF?AO@C!?QXB++?j3)!;oLikc_xE2_vH8)T?4rJhxQ;_BaNKnv zuHp;B;Zt29*T|s(J$;JLcdytwrEIV)bcKFD1ELDC>XlnJVcuyC8*2GCijkO-T|{^t z-orhxiB;iEWi!W$Az@5m={JkG+~-05?S9SUyLYDYwm3zlD2@94#hI_|jxqIYP`_g~ zM`F-LJ-C7&;(lrITZ18Ymn|`#(Q8JmQKENP_IA08W`KS%1JLxl%E~gr)m2XCaL;h3 za+=CMEh^Ie*5}>}>*LGgZ8P-t!g1rK(O|w2didz?UU=d8-yb-zcY}2FUngq)IA8lU z38W``Of-U-Cot5CYLrTg4NKA@J;(XkE-)0~YP_p{MO`OJ%%kfrj6kzywM5RI>4ByV zAB+ZZfHWMo+>Ykv4?jH}(GrJyy<<|6lXW7R<19S)QUON16(w?Vx{Q*(BBCYd!UOW_ z#(!J{&%(+}+nb&%#HE!#DwJ$%Yx?!GGD@C)sqsY0;3fyFT}RVa{GnTA$TT!OCn$fj zaiYsCo4fSsVktBmPrs$0;PUi9T7paO`jDuLaBD+Z*?IcM=wly~DJMR9+LYfqe^8$D zuAJjwHcsvUKygNoJ}9pgDieQv^lVg&!4+ji!*xgZ+YNs??MR#Hn~@e9Nu{NC`e^Ey zG4ctE&)o$F%N?dUY^wg~wr#DflU)L~{;JXL&9xc>yaB z7p9d!Qus`AvRxsw`6+nxl8pxjnvc{H(G8i97L6E_IR*lLg#?o=A9Wl%c1A^CurRF1 zJ)x=W?y%TQvIm=1{X(Kxg9jdQEU@@@E~7OigS$jtiU+t*v|7THu8d|z+Gv-m=xs_S z9mA(?=eye?orqY)U#%XVE&20`{rbcm+O$V832sz3O0%i;YOC6;?u7d+psocp+N>;A zbG1Amqhtuz)~_#T!V7@$)LdIZD4P?ROk4*nxy|mf8Oj09m=i75s=URR1xfsdci7#1 zBtp)Vx$4?Q1=vC=jcN>~DP(}~Sr1qbMEm-3`|?DkvPQJ74!0*@@#sNlkxjX?hkM+> zJzmQ_PU9Y9d3ZY2{aeb=;A>Dbk4D~y$U(qWBO={s?o!&(^7BkcK`JKYHY*82`NJT)Ua4Qx(BqyYr&AwM_Ot)_0D1%u`HNKH1K^ks*l zmswD`ucH=d)her2XKoRmDsX&oX_+uvZ_WQEwl$uw-^l&iQWrGBMeDycr|1 z7sBb%PC7lHUj+*bv1HU(ezdEWldeK?FJ6Q)S;eTOSibkonUjn? zlbw1*&#|38^2Z&&edGUW={$9ov%xQotEIiYqw{FfTl)_73_Iq`mFN_&7s@bQPxMU4 zGuALPew`|_ehAVWs}k-z6Y8@k!&|5M$zCx$efUs^(i)$Le&)22!AxtK>-0NDDQ!O;ARGO0t6@%5jHG3Qva*H{ zi_->)Oj}sdhGZ21`Du<`qU~0SeaaiLL=DQD+H7TaVf2znGeCbooCwDVP(IlaPEHC~ zl9I#q;=^awrCg)E9>%w}H9l)?RVG5rR47xaWnE4W+<1c7SY>&!C#T$p=R8J`wOuRE zS?Gi7CWh7gv3+5V@+SoApQ>LROP;(=CJ6y(Fki3%Q&B`8mOWwoP)nq@?cGD~AL}&~ z2@qc+FkLl(eh)aB*@j%XL~4<=jqB~}$Mn?~)+|x~V2c(G;&eUuQ7~*vr?ZZ*8861P zv2t2Lw6V#wLLsdn+SsU#8!Ic1Sp{1;%6jatyTDcM`s=Y1;}$JiH15Q)wwGagk)mxs zs(?80lU1C*B$r!1(@Xyd_2?v}Hff0Uhu_hse1Cv+`1@1zcOI5Z1%)y#r#3a^Bz7Ea zJ=&3&Gw;s3SKNK)yqx3fioipF$*`^*-+N|Or2)EG=aXUNy$dtsFtEv2y-wb z#Di*T_OvM;A8-<%M``!Z8Hu81~FJFI|4`27Zp@xS$R+Q5?M*;hT zTV7Q~M225Tmp3`M?jvo%BkdsuqN(~uf1uYN2~PSxvy3IDwl>FbZrM^*<$vLD*p>~2 zOqG4I%CLpo_WeAivonR{MQv?#=iW2qFSU^@K0ST-2)7dHJo<^5kM}uN3M4e^ zk80tlNQ>6ik5ABpU7nH7o*t+1oGCY?$CglEGM7s1wpm~8#Fy9u9|3gBI=aS;HEEY% zDapSW3;Pwz;?>cGT6;r-*)^*GZISB19GV!iUkp0FK7+-&*);}H<;i0m!GClEnJe49 zyUZA#ozwD^K+Cp=q}K9p6yVerSjJ$RuJnA$YF_6durwj@47psPc#R2W&PI(1 z8f5_6=2zDHt6ARejRp5t$B+;I3|;3Z`mLJy`GFl{awD7H%;Gl%(>8#E)3#g-HSj_; zxU(qIBb~$|xjhPH%dBqDw`;IauhmL-<`pP4s;g4gsTgG~&CS7JAyaBQ6=y4_UM=_q_Te+H*T+Mv0rieZSt!NSi)Sp0^6R%t%A{C!<-08P^?&;; zU_JYBeg0^BKpiu~aCUUO{_vJx)%SR&Es?xi`VIzCJWgY_}v5Gzjs(Gr+JRO zSXGE{yhDBXEj+9v@dY^jYWrsaEfVIpLnQcs^U#<*O=E*~{4b&w-? z@<`+1v!{c>=unRyInxt#*u!DRpd=^1@NppROpg*7Cg~K%MOes06I+xF@PD8BLy>L9XK-c^COeb zITErI&Cd_?4a6SV=}q=?#*3Zf34K=D*-Oh(d@<(gDvbpIpNQ{7e8Ab>7=CMb{ET*Q zeSL1xRVA!{0}ud;;dxsuVnf-l-+9$|Z>BMH|9)uqF27XZIc#`O3&-Ri_rr|A{Q)CT znL)JKtdB}~<{@a(G19sj3AxcLRzn&$-|Q}C&!mU#jjeWR`E6!z-3ghQcr;tla-laf zo*Wtq3CAJJ?nEaWHU%f)nKL2d$p@AGN1rsuwJLFJ5$@zy)ZJgX6VsBsu*g(X9WxeUQAujYnDcv9r!b9Rn>z+S5Sgt~zC7V6njP&Bj533n>u z=w_yrJMkMX=XDwHD%e_vTl@!Vb=94iURJVQ!9@S%y~IZ*hQbm6vBH<=#>74vM}(Kx z3=@l?MD6CMp6C#~ZVvIh@OcKlme^jy2|E=Zh^5-}glq&@Vs7y2*I?5$VFH$`P4nBU zW{Wi7-=*OJ9*EO?xAF_EqT-%7yXeq+Dk|<^=DVY-OJn+ihDktOy@lcs)gRfsdGjN& zP5=7!>-|^bC&|Y(8ngAyHs6{2P~1@A|Mo|XKfH22kS&yV=+2!96x5EhP}c#v!&)N^ z#XA}cY?l?>N4U4IH|z(6Me!37)7KmIPc+|s`8eL42}$^j*}5q3{0gom^H&gi%wELQ z$?KZ)q4p=@MxOEj;L4mWPkHb&2t;|xBX-=H5nn#y%ljBVG23H@`TE=+Ua68SMb|Nw zFF=mXWGs(kERQc=I=koa2UDg^3MHc`B<;Z;fwJ8%P;?T{Dbj~&K z;RG@#fttviSX{U7kayC7cgRf;>I)Uvy30yS@{YVV+v_?|mtly>BKMLy$~)yYoqz$60g2|{AV6$RW8 z#i>OQXU@JJh+g}8Y{oB5nXGa5R_^{>?xgB!zp`AknFe{ui@(G)8sQRfBKgkUAGKu_ z+~WS#GMFXoeVxBbStzp&oKgW1|FL6b#z^2?_V|nwn=#faN0=W9l$t6fU#1SSAj!WF z-muUA$?Wmf`9@~CDy;z&6uT`}GUAyM;^!Ke-9(p@c~QeUCCxBF8C~iAqm>0iP8Y@7!r5mKKke zQ8a2+$+b)!rc$nK8g$=+()m{w7hiczN%3`MW!KFI1&*e7eM5`9?zQ#ht>?R*mNDPg*Oxx5DGDhqzF5a7QdOuWc8AWhX6t(_--MV#ktxkxg zorb#i;MJsn>FB3K@<|i3G16g{r`gW$@6b1I4ra|Ql3T~@RhAXpY*eK;H!H3Q;6E-L za3Qdr>pEUnS9cslU$fad&8RECj$4HVY_*ALU&A|a8lP}x#mVI3*!MLmiF zqv(mLsY6}i(c8{hdweM{xD)b_~gO{VX2-v+-4tM3@a=AT#Ni zne@y#rhWWU0t?@cXQX(WIpWf2xw_Ojlkm`8ggrWxkCbity~J_eTZAg|k?Jr;WQ5E* zn@*igFW$SixV4UY`~AmKZ+1h?zibZ3%H7H*>Ln0(T>_!XZr)!;PhY5JyM3g$d;rU+ zE1DlmRGSa%;r+-1hRb!KS#j<7UfP@eu4Y%Ryib(MYp3%5Ri$mBTBTzDRptGdNod5} zs|pGVX3w2}(~>1ZQNCc-^!)tGr_Gwfnsg4NY3kal#B-`IRE6dqBD*9r#A^E9 zx9EF!}SHmB=j&L?(gY5{%QLsM?d<<;X{9Kdavo7gNKy<&mieL0-o=qPrE?vc6NkQ z@tb(ZdPv4x9$h*tP!;&i?%(`&FDZccyz+AG%dhNV>!<6gL~Xi`BC$VLV=pCp0neFi z$3FWyN8gIdbSwV_hDr>Pkt@sm?DJDcjy>rB1k4+0v-&O$za_q)T!OB44ejd#$X)=l364t;UOB8rz3|D6Fk$Xu!I9|G z1Tvm@_%w@e&u1TD_n*Z6Q#tl3E>h4>f}@slU9{BLRdq3zlL&4H9)$F8?z4TpXEF7K zHBG+hM~~INnH@CEYDVN)ztOu2;qIvmbK3Fl8_L2KgooTLNA zd4XZeqCK=LCSN?X@jwiX_}V2#P^-*ZS;&}Or}=VL8usdN);8};+p`RHUENGnS3#4M zP@8#%eW7E2YC}fqe&b3cP`$Yp-pPQjB@*Ug`+@eZ!(B~>y9C66wG4o@9Was(!;~;? zRY?yU%Grm~!v@jA5;(iCiV448*=}gfMC4!q6!fwL zR+>Y?c+jeMw)WvFeNf{R0?B#MJjW2uks3dT@IA^oWZ`nmqAwgZN+>S0>grUZ2q(sh zXqmRQp}|m^{eWa+Cy*bPlWgJyBz-^Dp>scLF&kqyeQvT8PK?x(W_J#{2P%5brX=A6?A#Ip~lAldP7;waP?(<^(+HiZ-Rmn43ETB z`7mj$1oXRK_2@4hSXx0;WU3zv6K0@-RKpk95ZOR~2h*kQt(6=CB}$c?RdM(+0M#}F zeu{~%FYai47Zo48;Z?8C=%%_|2k3^OwUjTZ`eqwudk{) zQd_(0ciVo419oS_)~zoMfcJ2Qy+?+3<62~k$tz}e?Lgb0A;VqD%24)4@wdi0hb>smmwAvaxDM-GDeiFNjTQ^Jluu& zEcI+x=G83V14IPwwR*F!S~L$uK0p)|XsZx{r=hX&@yFKxs0f@to@PVaTleZ5ys{+( z?7tbQM;?mUEkTZf;-nAbiW!9r$}KA^XX-33D>LSqmWH3leaXL#&;2nciKz=1PxzD0 zhHb9?aQI|r%SSL;V776rR`k^jHa(EwWTMCF$ZOm$DZbad_d>2-lI+|#1XtvO$gcGKYXARp&U{-V{lV-`wE6f7g0|6}*4y{>d zjq3D|AhEYDevPrTcoa0H>mfSo|-ESjc{AwoMbD=V*P z#tnBZ&nQ~5bS9=w(;|k!XOrf=Aj_CZhQUpdJq*aR(aY2)j+78h_dw(uk#e3gJbxH@ z7L{x{p5AIh-@5hZTM=8pqqLfXwO10t>%&A~lHW5|lDl;4R-~nvzTQUH+9uS@%aJx1 z_@8Iu`E6X+`~&i|3FBC+u`xB=Px!oZkXx}2N=`X1Ys4_JSocFzz$!~Kv|bSWzc|-Dl1o4StdkZ!u=~ z8^eRa-M@et$R|EI4otcoLMZ#y4;=%A>WZ9X30Gyyu${%s!e&446`cv9JKJ zSEe~zr($Hnuul=C$P1fYUtf18^mXvp@#yR#ZIWpR5vb}j%Edy^3wdAJmVJT%1z48=-aW(XChkO zGW+^7VxOf58^;cMxRh7f{+W4%eDe(NerH-+8~IKsCpM8Hx94nBA`Ov0_&XiRIQ1x9>^V#h4p zhJBfjmLTPvq{tz6je7r5qHI!zMtXV!#D89X(=}t1Eq@<(sdfSL>5!gJ2yp(xTYX46 z2H6~9%`QZnx)9yk7rkCLezk4eh6OMMNbFD+@m1Fm(z1-_&9u$^^z-FB@8`e;um{LA zP!W}r0pEf}Q9pC!{i8v@BWuEhW`;I@*pleLw>9j$^0UThr~9fc13fY;O;|h&&aLiKG}uZmspZ zSPbxMSoaw(Bo1U{fR~l_3dnGBIM$HpmeoWoNBp(4lEiiiFPc~mMb_gAwiFb69Sq6y zxD)Wz!TBQK0eP7WQ}zrPO4%AfY{KgC<6 zE&dj6UmpYFK15$RZvU%TCrwq?Jz7G=m(v`xSO={D;&LMbX9n#DFhE`V&rttK!KYK+HL0|Ud)&uv-EAdc9k5vxVkT<8}H)4xU?#d4KRzvY%&uFOe3 z*1lljtej++s+KHCu`utuMqPgGor`8(QdGtc(^I@t7cS*--Hd`EDJdxvC$c`ia#}XK zciI!vy;t~>&qj>%Y<*t}&+h7AH9X7=%&u<;3lu{M_H+1uz|4Y&z?GchaoHTI-9hrZuv51i(B|MNFeAqkjw_wa z1sx{{XJfI42SK+f-O{w$Kp3+*6@DJZobEE?eZL4Nr!(lWKyn+wKV}?x%WNg3$Y(L91EaiEAJ7By01~5j8Opob$hUz=!B zDg#flVFN?th3bcHL1ih%I{~DQY2Y@qe=lQ#*npf8*(BdeDdZ`fJ@>{36sv0XC_@E` zdGT{u`z*#v%?Z{C4(i_w29I*iV4zcoILGVWgXx#J=m}|l$B|fIbXKnM|HoL^YpMsW zpn}XOe5MWIt!iWniv?%yV49QnX0Y{4BCWoNww7^FMU3Y3o?t)G>@pPW&^?8^IzyU+ zp%Ci)@K~4(XErB8Ar#U`q!;Yz`tWau{?XROAp&3q|7<7#TO>i0nO?;zvEFv1`WM08G7_p3HRcI{6q9*e zQEp=_+=x`agt4H{U2-_Ia0b;Q zwJhG38yaag{DX79EXe;GLXPiz5!Xf~{5#40f1&1Bt!UdXP8*e(;msH|{*t`Q$7OoQ zj?Ty)lR1h^HKRtQdonY}jLq;2PEH_9(>rqHs4;l{2YbZ$A+7)4({$ia`%joURx6S1 z=Gysg`piT0nZ@*(dGr}sl_XV8om_DKgbOY&Td@4T`|c}1LRKy&fl$o%A+L{FD(6ls zl2r5C6Tg4UH5alF@JyIfzN!#&!b_H^7f-oHQcHAoo^TBr?G5!q8Kco{JBh0w6i6NI z@k~bz{yeV!b!e(iLT6TN+qCJaXEr@!F3?t>O^H3`YSi2kQ^Ni4L+%HK!(FG2b$!s# zzzTxYQQ#l{T@1d@oORa;=FYLQvK;%*T`Pa^4RaMB)ARo&IRBN4h>x}F&ZHz#0lA#^ z1SiaA{ox)mAD`&&>FIZ;rzQ0DgnL7$I@><#>pRgAG=79JTx2;ii&)*OK-gMo_p@O zeZj2kAs3VuC|eS4&stD|4X)tYyJyB@$#)`Nw-}B^jyJZ{cV-RI10y1K&*&@wxwCKd zrQS++xz5wfU0I5$IBVeQpBl%f1QzAWH#^(tUFh+ z=KQ{_I+>`%>mht-Qb55Oj-5xE`$uJ$Oio?x37tUY2z57g9A>HsDnrq|7S0`Se{YX* zE7-PTwMflE@E>6o*oWYX=~U054%NdrdYZHz6uxg`4@rF<^O3&Gw?eBUMd&(?z*##? z%`slUbrD@X-mUfaMj{S4IY3}oYz}A<5|Z8IKqtY%AX^wP8ENXH{ZJFE~vL;bh0uihvz1U{_3Bp+nWsw#-&3SN)#N_xbw9+bCshn1lm8f{G z{uixeNvpUk>)fUq{qLG8ZSttdInA~7|JGc{Z)v#Y=Qdl$zihUqj!>&{`~TNX_y2PD zE^txR`TzepXD$rGfCG+*I2tM$85x-wwWJ7$m#C<$%viHBvzE$j{kCpvHNzPd&C1GL zE4Q_xa$C2k+}1U>+?H)w*EMs=$jHb@QIQZ42N=%$pYL;qwA=Uc|6LxB|9?JQX3pHs z`CQ(g_vQ6|y|HdRc>ap4AzXIWe|HGoX+FHpCxDDzA6`Wg=( z53gVU=Ju=$hzcj|-}jI8xQfg02mOQ*s>I1q%A?7#C0S$(1OlP!&?RTE$%<=1+H@8z zu0Z_aMJ&`3{!T?EFJzZ4G~ahI_ZB)Hm-2S2b@H<9E#3=Ye90db@pv+_GlYtsU%7R) zcK9;=uKfI|C7b>Q==g}sb9TONn+=J%1bzY<$g5&vwyRir7FA4z`jgqS%mpl*9CeT{ z*{I1Q&5oTfBq*Cr9xUm=O-QCj7PGM7MOfT*=JH=pcu4zgPRFqmk(R^w?b_NqI;n^b z==0c-wzgw!%}rmnp6G6G@95yk7Acslw70c^p%3DfVDF9S#3k%rUwRtFe8Qa%+1%+q zS11|w;Ru<>5W@nU!AIe=FZ1$NyOWG0@yVT_`-P6j!`B_;D~ z+C8i6#@VxPoH={)l<5=Ez;kM1@M(^+vZA6vIXHY>zWUCJ0sZi7 zUNim5#LjN2AXmRrm!D7Nq9b^c79cP!I>}k4zwb`>DHXg%;tS`Yge}`%?7(sTT4qD^z6`I9S5}=mqb?( zH0}u6Bp-o5W1>XTD*M3?Bh-n#MEL1xyM6id)-EQj#zW~z!P!fdH-M3 z48eBc65z;oCX)~ZBkyq)DdGJQmzSX064ljR83HGz*ef43$5l{If&Z17C-i{DVi zKjvD*ER}l--imTHq7?SA%uuG%ZeP3<8i&P8&Clq^XY}JU`tunQ<(24(RYAb!4|m=k zAjc&3a6{$x%7Bs+oQ$$6j^hog-#mRkA?t3sRMr{sX(G(7r4}2~FnVhky)}%_PT{lp zWYoQUA`iKKi6jTKth~HJMh^BiB>-KduDtzd5!1uR@}3u+ZCkZ*-8!LsEi;!p{uo^; zd-O7*Q$lnsU1z3eSof?)blhV}Q2S^RA@#Lx;Nrb8O#GRg(V3jlxt!4%oROb1@@?Fh zm9=AgQ&UURaq>CHHqZCA5X&Zh)(<{97*smWc7(KRqj~1>JUn+6cA;2bu11Xqeg5=xKUJUx zotf@QMFb0Mo%iG9!7)V1wO){0A5L#u%GoYKv) zp?)Nx-Js@6>;^$&SaGees%rG1UT&msub^**d(l2SBjZZ&$d6*jJ+3^a&GmRD%2*GY zTY@KK(D(~4y?OTBnODvBr^3n1ZLr^8j7y&N8*58+w}_dRq|9Oz_fYB(|De;dv(L@V z{n5qa^TS$d|FB1mI@vKJO`h=S69_$6)g#0%!*$BKrrFW5_}~+du3Y)(L(3{Fi+O7aC=)5Ba7FY=-QCcDZ0&6N2OSZW29UN@}^(i>* ze}JA7(PcHsgxg^zF05w|)*^{zt*ycn^a4B0Mv2DiuaEXpPEd*Wc%7|6s?^pJ?@1Vx zloaVsiK@w7JE#@PJI6V3(;^G(o@8bcxe7~dr1ILxQ|*;P?J$k^MwYVG;5rMrBjP2B zVh+F$>ZA5LE2l>QxZQ|BXl2Qm(;dB09z^ul&6##F7jzjjO)?e7FxnZ6cGB2+0 zFBZ3VDZ_AGbe1!)f-QaXYT5B+omi3kxgZ?>gF-BFWP!SJr9Nm=N9$qc#^)b>;ToP% zdZxGK15jZ#O6e3&XeNOKJ2SYSwP`B`+w)$!dNW;ELjY7LqK=}8ck_FU?yX^`p_>tp zq&KJga13gi&8ayOsURpm4wl#lvV`Bl!1A4{8H5I_Cvc!h>%XvDQGuA_b~f)UqEn>;o5qI1XO4rC`omvD!iS5Bug+Gz3w zHc6!-X?M9-u6=dgrnlbOv|-aGUS;p8aP=zN-)H0a!mhgkTyqmUQJpFi5)nLB_HHbc z91>;x%cv=#MJrsC-5TKYCOI^{lJzX&I7GfdNEk9v|6=?q{tQ*g%&@eTWX@DDYQn}T zDuPXm%Pq;toHy^9*#YNTWH-~Mxh`A*3 z_z5VeKL&GfEB*m87@24D;{uPr_Lr?&-~H88W|l;R?qRc7V5XXsNAFaZtSrQlC^d4> zlh2Ox`aHrZ+Pu3y;!D9Ptu)((us?xX=ePoj5_ruHfsrwz*(mg-6JrgpNKNE(ioL}`S6ag>CDr4fXO3Uf({>@QO-s&7?Ztw+j`_4QMQ!o>Z+AbKL7mMwa-8M#ER8y z=F5I1{QtKQija85L||Cu(OYe6Hf(r|3}HSv63O98&Y6~5v*nWtD)Mp#xw+Xc`xmHL zf7w)0n5*B!LKK=t>0p_8Yw6rtHtH6F)n+V!YBJ*a{{zp-P<)eg^)Lfg!*H&LvIZM4 z(%E_RSSQwC`_Zqeu-0kIr0Ad1v93cm3{U!XwS=jRzQN;O65_Y7}7-i$EHHU){m3 z)Y;Zmk?0+jt2oII%nCOGGq3P9D?EcT@Wp4fJbuq;Y*h9i4&5dNplBa602|DqTS=UP zf@PqcgqdHOaBBV=lZ$4Ssv4>KU@#z-Pc!NN5XN5QuvO419i>7_nu~ILo|>mWhxVjs z%Z5cFT}q@U3K@0Rq1LaCx3z>LQDQk@2fIO=fiE~7#3|Q}2QFyqK5^`*UZJVoy~|ND z93ibM+_hNi>FI_>WSNL?b|5G#oz$jdF2tV76uB%gO~`zJNXA{L*`hn7US@z|>9SbLLTmVzKManML$v-qfq~ z;DEy<2>Sh=L$7Su@VRO`m(_J)R!2ewRZWHQEM&28m{rCc>(;@X`1s{W)4R=$!m1@v zhSDKar~=WJu=fJza^XaMZZ#i%kX&&}bi`rlpQrYGjynBOqc4dfLLCt$%@?}S93wG> z`zq#`3&$KMLFeFyvBm`DjnQGN>J+yfg2?yUJWro$OB;lmEI4=iBiyoer!gIE|*ih3{IJ9VK5vaFq6`BO`CRU-bG{2&rL@uut*)hp&8g$t_%cX z=E-f*pSUa6ys~D)8-J{R;k9Z#ARLaW-8fZ4_?p8}cHghH1JMvH9YOR2Q&Z4?Wm@Im zRu=+@`el78gGuLjirNsX-E=EgbstxCGgl?L{cx`8tkSI0v&T#*xw`D?t4kOD^5=Kn ze%%zVlcQ&T_h>#DswpY_)z9AFnT&LhTcXc(jJ(ih!F0BErd)in0za^#0FflFpW5ymO7GWVma9@2TqTR;2~+oP+N>!Q6>i4LPX{T@MM z*+T<;133xd3poW)@BKKFMbZ7k{0WJwi#hq8HydGSWFp_oO9u(lke9FP+btw?7& zI>@)=H04ZXFXjo8>_pSw&|ng%6!aLm3G%eCZ#%@7AB80kZE*1$U$6Wd7_&*Sl`mrk z3OS`r8&x)Uo=}Y5Q8raJ*l93d2EN{4gU;FG=!>@VbzA$^<_r@eAQa{a!G2u;1U~D- z2N+P83jkoYx^C4JM&>%qVk-gTS^{O|j%7OVz9sTZ8KWip>;w#Jq9?Ye*RFj!9~2+; z-y4GxwHH$H)}Y6w(OV7NyKL=7vh&EHLr0v+S^YoUwry|9@C${MdV;R` z`Ft>g{otk0`?oh_C6h-nsP zRbFC(EmFk!MC&DuIg2fJ8k(?_I2Ryb9#OFYBsohPYQ7qlAYEvmho{Qo^~5LpQU>== zN%AIx%1KU48|H^FtXE-~`v!WUeMv$Cgqw6QT8mm?3-1}_sjwv|J#nGoI~&MP`uf&D z(#DQm^+3nBH+_y(`AI!qEWRkZ*xJDg>EEm9-wT>E+1(F}fE!?>qH-2i@6-2BBzq-@C zV$I8Is^5I0x~jSw?`Rz6!RxCY30$kNe~ISgE* zuT8)5zmmYB&nuM)^Mz)rOb8qoEP`4R$8?e>$rI;EN^+%w(ew9nOKy?Jg-&Oj=n0>2 zxX}RZcoh~aJ-UFKxMK^6b!T$Mhr0!OXM#$}ND?^`(PQ3e@yQg?ce(W4S@fOoX-Wuv zdiQ9HCS8aMmMbd~7c97A!7W&c1r_V(&M!!6$Zq$GIv|4y%vT!R&z%kC~p zSqUx|Avza0&-K{ZQ&{(t#bpR|=fO%r$jypQ)`MD8qi31Lz8^;{W*E!*+SszLmd#o^ z%@mp6W#Jdln6y8G;MN{Y^E$nLZwl}*pRd0yC1pS=Qw_?q;|Yum=B}{uqc1H{5_uen zJYpAJ$;Mmzn4-tg8~OBx)DIH=31M9p7*@bJ+CTknW9Uu7+C5*qjn3?g%KhoHfg7w* z?$(vjL51$ls!*ncl;WVWio!?JMUg@DVKAucRwD4Y@Hs4#ERKih5GmPGMpsdcfKo<5 zrKm#LRH4*{KM?Y!JIK(bWhp4`QO(ea$k;7aM}wc1&QbsJ+n)?1LlbJx81Hk zN%AwMfzkoqEo9ygS@nS4;!1aMrF5I3bEQ+cQmeel@1c-<00{R3MO<1nUqW!twQ%-i z6!*!q$?&L*>4Hz#?k&q5SAg_=QCSstZ<#2A<8y^o;uWIrBqhYnz9K(Ae`Yxq4Oim3 z*~qbVLE4MD(W_*|%iu5Xv#Io?g_ouLBU zbeW}h2D(ozz4HJGA5yAB+BZs-{Lpc__kSxMsOTiHQ-7y&g3C^JfZdglA z|51`Rx=&!7MiV^AaCh~bfc(6>)2sv2jtSG%-O+Y%|L2X(t>NRxJG<=Af*)+7ri!fs z6lbJDvz@H2B1p{t8Z>k!={@oTyG;+9^2z(;wQ&f|%itLMb#IiU23Z5PsNw)qtWxQd zyRf@rYH=;ru5lkL;4xOfd{)5CtbmJH0T#ttrE~tZXg$}?m*B^m!E@%6<_>3+hUb>f z`S0mP1Ak~z_vuP0NlH|}l;6;mE@hgHFuh8b<4qDo$>r#<7jcZrHm=p{*8jEUufJQj zdMXO;LT2$y=BKn9P^=a@9(xdx`q*TinP-Vu{!;PKvE=!xs^^#J1HUmTr8G`#Que7= zaUDuj)T=XscC%DWP^DDNf*+b|KXm+mK@EFei9SBo=sw!o-fgIMr_E??`lP;rs(`I+ zN1Bros4t;)eV=w_)0k8CQ|DBVS+OS=Q`u~X6%`k*6r&N9ZJ^8xZsKyoE;DcD{r^;t zdtOmvnPcLMyq8%cXcs|8WSO&O9g=N@^PXAwGHw7J@DNNr^XARSrzT6<8Tm8jO+-jm zso%4c4z_mEv{MD&srOIWU3ap({+qgIlGHp2ki$%q;Nxy~&{81&V-hNtSFL|@$Mzj> zuCKyzf>o`qTQ`;YBiqpJXx<{wu94#u8+i%};|1t(*XU`d3aHo|F@@E4D&mxzV?IG0 zPw}Mxo;>=m_U@Avbe?DL4xAO~Xs3b}XeEboX#b~s_8vTRsIC30L*Z`pX~HCjyI~OQ z?v8-h{< z6t5mqn)x+#ddcd{=N+OceZctf zm(QGmSAWJ#@Ty}5bYaqVrH<8|`CGRoO&D5Jz*1-Bs(-E#hw>N-2ONqPsx<`@%{-SY z^#M3c*1nD=U%h7K+O@xHNWv46xaVb3qa@+$EJQ>f40{syv(2MpOt-YSQsy!6)5!C9 za)8g5l9-T~;!906@48@BRGdlr0CD7g>tL_KJ!^ggA0esS9DoZ`b&?(Fw z*hmljiXOO?9+*cD2o^J6+2*-&LgDQBzgVL-}!)4#nP1rIPiw~ zs)@7iTKL^p6`8NPUtXpE)OgW&&iK3Wl@&UUI?3=)H``FmkyOwx9~p0(t(wq6<0KYdaV=C6k?YP*kZR=>>f}`t6Oy0Gx zZ>WCrGhU@(XX*kqE;m11CWXM5E|=9yD>ikS%f3#N6QU}q>m(6~JmkYrRFnR+LC{iJ zIe~*9rSfuIiVsN}YidZ@(F>?wUi02RKcIGf-R_U-Kl-G8Pu-4f+qTud_qX@{o-zE4 zvqztE&N=5w&BL){&pC7C$kRt;WDFawpNs7LAKrunCMj;|5R`G@8S$kMH}Fz3>_pp9 zNtT9;g&SZ2s;%{H75h`%H*)k)ohAza-6S#2=mvOM1^VHVCpj}-&`0wzi+zcTO)HEA=vY)mkiudH%h zz&cVjDH#83Ea&7QwDBBN{H;ok4qGIi^3P5$y?q*L&kA1k0)B3RNc|fhDjq8v(5*$m zptG)p&pF;MnZmKAJy8b{0cx~Tt*e2+WvBsvR4mFo@sUeZ#%eF{%sTSj@?rJia+S1% zULdE6AX$bEOmo7Fj2){%qgM$LqEX?AMjF2WHt|)st*NOk))T@nB^*&At2KH;BsSv~ z$T!{&hVqr>K)#k1Bo|k1mZVDH9SN~_^kJS9?D%}%GdQ?-B5aREfqYw*@IzHV7sMZ! zrL6Z3%>ccXVWDFr9x7O;IHwu=(zIeDJ6el$*kqI%k>2BqFF(34bn;muF=gr|>SENX zYi#qBqI@L~DxyaPlV1HbkGK@ZkOCNwBp$NcDYX>vRKa4)jX zH&70PKG+K#o+#yIkHQ*h8jFc$}6!|1X3($f1WVIyteK%d8+q8>SL=-^QzGfAmB5FL=z zAlF?CW)q}S7CG1_YL2=3 z7)+-*m|mm88qK>VVxGRPF34uaIhX&_@cZjWN#=rxo~G6-`K^ zH%fT<62DlJX4zHpY6R)z}+ggJ|CT3?a0uk?zuNu&;b(^FfE? zA>dSsfBcyZ1SS5p{+WmJqnA)VdH5uCC~<~zbtD5=m5@KWDD`ivR;{Y>70oF^DqFG5 zzxBJPs9*vPn~6omC3rt4qq$YHM{EjebNt+2sn*q1sAt_hg@LVAQ(|t25d@{zY74Rf zbcp-rHPWrBfNRMNA;|_eSrv4r8})!y)~Bi?U)dD^v|2z3BcMW_M>p2))v$=vhT4sf zk`bF&RkdMD?Wb)1&AV>kQpX#ugYHw?^LGxt&-==aEBS*1x}V$Hxa-T00|+pEeQ% z>g+uJ)xkpt_UM#LmFiep$ZivYB?x_cfTn@GL3j$o1jN^&c)y{5YfB@aIXKwm^AA58 zEhcBA-{(?@=M41^LJdhx_n(##<2e+6KqVt7aZs`BM4v4%cA@3np5Uw5eRRnAW6z81 zey2~&By8Msd_;c!#M3+Xy#2^Tu;~kI&h~pTz2-;nwXJwV*&bvFSD>eAV5J0FI4AzW z)i1J{)%<2PrJM>O2xxo*WB!+nqm|ZpDS7g%qn8=a1#PSU(A3L@yh~lUC_h?~)=)Iz z!V7XQ$S;~yJb4O$p@gl(zW5_x%v`III2p_*Zgsyeln)ZLe#OdSSfd4rEr7f7 z=>0Zwmn$KO;{HsI`e|cObIP58=Lz&bPb41#2X*cJMZ9eWy3birKO=14-q>J2bl?zf zBPKS9C~aT3-L|fdwl6>3+wkSF&O& zrXug^(^LXl3N%!U18NF`v?2CB^bYGCeY#EGI|Q8_P^tQYrpkK?lzdgFFNHNzR2A-j z^Sb1FPF|PwP1-)CR5Y8|8S>U|zDN2Zj`?nWmzJZr`2uZ+;+20+^IEj9d{Y2b+d4~k zhQ;tHywFbGDTrYKh(RP{YzUh7l)c)NU?3m-%HjZ2=H}m-ecznPN;{2y5yY`DB1v7e zIHEnr24u{l4$?!W7ilH$elQq_&l@vlq@ou9Ll7(nv&9&B#3hv(Kkz3Q>5-@d`n*-A^#X$i(ROYPZk_moRY zb?=mmnS+E)%jVyE_ksnpOBmu6!JtQl(p4D>k6(7ST@77s8e^Fl2NGO@fq`-(eJuqG z7rrGMaUN<2N6<2&K~#9)RYG5hlQgtu%WiM33B0j|f&mQ16oYjC19) z^@5YJ$d?v4)_>;Ov}r{#vNIEh5DkNFhPGnUhKYhicj>F2TKnXaYgYirzdvE?wpZ5u z_T^_+uX_GDy4D>$E5qc`%qSp!Sdh_!Zqbu5iFBn&kG-<--@A5wX~2aMZQcFB%P+tD zD|RPXV54^_6*?fEVR_faD1Kbm=4Cd!T;t1rUO>;$>_0CX@5&V(z_lO-CGxbyb~g|K z6P1^MM>#9&f~hlROwDB=)&$RKi?SA?Z6AUz{;&u421*vXz{-3!o{H4+?1pBGSt?F{?Q9c#+J8Kv}1?y-bC_ZH{sdsDw zV(ow;x?(y{RDa_fr+TdYxav$Am_8uE9zEK2OtZ%i@(+xsQj7!UV@EV%^18I{YdmnQ z*XTH`o372sI?!UTDGOvV(LAm#hjXP(J7-c5MsnP)bCx<9j&O0*2;98=YCSGX)ms0_^uC6|;G zjUCI+`8j81W@Li*rq4G9A5v_KOWEK>(-hp3G!clujtRuICT^`xUnS+bg6?hw(+8SL zqGq9`&aQ5|D@8LF2ZVo1&Tmx4spmHoL*q{M;fM2$*F6tE{P4^F+U?6PE-qG9!wNy} z9@ji})Tp6aO*nOISob8b8$i3yR=_Upo>Nv*a_N-3+`NnPP%{%mUYfU_FpAdy;^|s@ z+4-EW;H&%kQ=-_A$h2H@{Q`C7j?pw;&K&TbkXRPI@ib| zm!3>!!NP^}n41?&oL)3zLVi9yyM?fgx56D!8tXr1vl*G#7%HWUSC}2VlY4d8FdLbw zM3&fho+Qy+cAZthB-Bww^El$b(b{e7JSV$(i7SFHTk*uJ@Q_4;t4?0W=u@skYT{mE zYW-D4Ev*@6lC)Cv%|*`5`_cSiU;du!Fgb-n<|+*(%$RZQRX?6Td%^W(W#&BjKYBHx zRi=y+RH0yACNslFA>&4HB?I?WJ@u#UJ9oYR{;qf5-q;>#+WqO?-P^Z)TrVjGG}q!4 zyGgcdQJxA8dvjO)iO$aW;p4`Q8#Co?RcFfk<1p zu>AVVO0JwUhnmXXq`{-}^3Ka33NyfyHjW*e%dHG5{?OoFDN1~l(zYzg6cf-DY1;gm zlIx47?%IvW5#f!pR?NpBv@GA%$L1>9kKm?}_93V)Y25&Mg$?f^Q_T=;D9PIT3mKi^ z9(PJgk{gZ4p(#fD{x6U8IGnvl0m+jzO_E2*k{r+2Try|MM5uF^FgYemVUbz_pE*FwVK*(fB*Zo&2Mfv)X}ix!`(Y--u+-_U(xyd;zBzl z*$5rwztfFMb`jSRYyO3|&YUr8{`|Bwbm}uMnlfcVHXHA-v`mrL^yZ5HFZZVCt$q4< zpO$QCtIwfdlT6sBUi;Bk6}PDJUu)PRVa{eGL@N|-aM7+NNd-OZ9{j9E8I0M5aDqrH zvxnZ@=|;rt4)%*l7=+A7S6vERr}3LMK`~Gr3Izg%L~?J#G%nYc=m`3}pytIf0h6n< zF>z#(vhM@^@^6U8t>z4^LA*SPm{*(g1vt15w0Zn|JIersGM=im596)iiU#d>tH*f&Q2 z(Qoau=BSuuj724YF9S%9+b$NNje+P4+GI%dB~(@b&W$wi#CTQZ8crPzxdsBdwC9X> zY5T~sT8`#aWMWi21a`&;*ml2r4aj^!5R+_>uqb~Xnc8T~lS==uT!L&@LW0rVS1ZpUP~tf&wYeZ&8BFVJ5YMpc zlN#UA>FRIo0ir#!G~E#!n?X;JcbwIS%I>;saG|BasQ?k>cWFKywFik)9}|Iof5 z`@nyrYaJye1SD^gDTFsqEje{tNcrxzU~UHgzvyC9UlGqs96kIEZwRU%`+zt?R$2a# zOv@ia$mvvn$Tb-%9O_oxi1V2DlB+bp#}?1zH3{skWN>bB1RP z4&6!>ZVRPypcr9&1{p@!*9IBo54M{25l;B;wYApbMiEEKw{5dE)Q-?1VFN?zYoluD zAnU%}nJ`#~;74FNrtK6LvzSUm~p&C6rGIrh}vl)l8OuzFG~ z3${GhXIJ#~Vf3?a^q}|K9D_I$G|2Y%gs z-?C@F?qj<0+nw}Z7_fa^Pgj23hkgAieMo;A?d`_*8=*@F_t~4@wmqefV|_W0zU<@U z7tViohFx)pP==XgOG5#exbkR;-IGFEfwLr!WG>5PDvLjsPqeKA*XEQWX{4uvJ+=I2+_!wCbHZ;mpQYJUgJg91Pe9ZFh&9vr9`! z-lj)a26ZJZ^sO(5D=3;WzF<6s5*?Q9tOMtRo3W)WQel2mGT-FOI9bC$e3n$hn_XG? zI#Mn`AzMCFiUG(ZiP#0sCmVJeSMm)0Z&BWxm1m^7KnDd+G?@Ms`_fn*)c?uP_H*7t z>7haFjFSH=+M{Ru_$5o0Ec^AQPWyP}g`ithk(@y%P!iAA6Q)ncWG=k8XzaDP09eT= zg>j8WdXA|TPWxKt*n|sz_1C)K!^kSanb8x6G%8h~1;(Lrh#CmtRwNh~hAPlh10Oc~ za`^Y0lRA2IA=#?Ze&Kv*{r-;8jKw$4Z2tUt^KQH0y4j^avpjD92hPlwVU2Pky(P0& zV(u29h_bZ+SZ{;z9-?h+Aa<<0K*dX>d59tB2Q*57nl*!!=?rt4AcxXmwQ1D(v1(K> z{Y@)?N*!N&uK``_ggbKh*Z_c_^Z@Sv5RQF=zdreE_Snt5a~7j0yYP=WuQOy6H`#u4 zj_;L!@7uIC^vH|CkbEYQ+dHCLNbwyBOLAG_%a2#C+p_2nqMs$#G|3!<6$OQd2q0SGK)%J__gRIqE3vSCg+!V3hykIf_ zsy`_Q;Cx|yzeNSCO!1y=nztsI^dyPkHI2zIV z1#plKgS6FYVIJgf6wr3Bke6W`8|2vmSc&Q*>g#vc)ipq#(e(M=hPvHmX2|ZkhP|J2 zWM4xaM<@{%)0Nzel7~?`H5Ot6BK!#Qp-tCF8kDXHfFN3ofoGyUC`f5(u$M6NX7JuK zdAIof2Q$L`Q_P**EHa2s3(3iEK{UtM6J4b3s;!dfo|7F1y8HYcA1*V z?z}#bui1n8K>O)$wBHov7hwXrTha$&3UmA z+e-@Q*FyS6qBhy|O)7n(Y?U0{`Kga?-Man5-P^xvZOj;?)O}Fm>0OFYR8UbU{}WUkdLXfBFZsZqeM*K=VJsV?3SKo zs?8P(dPoV5goWU%E8?;*j`ft`Ht-#o z^U-xiwNVtv?`;a&rcbY_nWk(2_cTW-iI(I1+F<@I;c=~gxz?ntQ`Tus+E`^B$dV>4 zSIbpP)FQQ%qhqxua8@BIY{QB`O7t|NNtvy>$c7GsRBDpH(GYH!*?Pa07LRAc*piyE zwQI{Z)Rc_Hu$D5;{&2I0Oyg$1r#Z}_=4P*Vr#Gu5tFA6_(2Qu2PqBTF~ZIynbCR?;xP1brAEnHQAeX>PwdjR@S92wF$IQw^*|fBVZD(b8_=J zq!lZUwN-1Ys_>Xx5mYkCXr#Ii5XntUIH?D(1}mND{>{zk zI#x94RC(8TezvV!O?j88Yvtvpyi@Hp$U7#jv8za!zSMTTKn0#zl&f#zl&@s4um8{;mv_v$q)U#RqU9SDA^^OpqCt zTJ}T#gTpR+J(cRx+t#evHg4X$afdc-I@I^S@3?x|>%r4zxW3%9=}U^?#r{tTf4F}A zhv`%L{ujy&RP$-mrd_74rsb;xiSp6l$jn!7Qy)=R@_U=I&i-?R1q_Dkp!xZV7ktJ4 z*ug7KJ@`YPKzHC8dU58=7xicR-q-D| zDJiXhWdcedC$Q@A=QjNDZ|}YL#|_V|I`#fVKbkiEhC9mdxMBLVADwz%f6GQnvPVBB zsh>*|LeB`bCQiNYNkDoZZ9f_|>xE{L*9_ zN~MZZ?(1)TcWp`Z-^Bx0^cCOd0OWBTe#Fu7#r zS}QA&nJ0FG%)GveWDfdB=B_q2%^R`{me8EOwhaw@%F?C6C?QjLsRL0hlh|5YUS^#) zL*Y}bIqb?HqKXZG?1O;=fC87)+RH3zjTW0@jc9OC*c@*^sfZrT! zOpCYc_J)Rc;DPyq|z^SY-UtxY8&ywiwSEA!DK0o-y7uc2ibrKkZ+}JH`%>7M4d|>dFkK zG|uT}^lTiOgq_cMjCz}M&33o38W)TQB<+42#Oc96Q8dliMw;dg(Yq5i_PF!zy?0ST z>RCl2Ct}hT+Fm+fbX2H4VFHRc@NY&rnX5guBfx$a51?55j`(^9+k?%mtv(d_ka z?DUt0=CB&JsAJhI-%}dd{v}dNzUb3Wx00WqWdld`Xzj2gVkB;uhq4*N7SFISF^P>ss2E|<_`u` zfGAw>6t3k~7!nqexozq1;~Db%;{LRys9@SaDJ8RHutarZ5{Ux?pB~>f0!0#)} z=XtToHyrG730N@e`-RMPUi1N5Wl`yE)08E=YXdrw6?)sj{WZ#B?V5pqW@}Yz1Nz&6 z3mdkzHXrJUY6%0=2E=PFw{z#-wjRT9yKIWlM5frGBc1Js4<#k1BvRVxSUVz-8?;?M zr&)js+62|cZ+A2Vez#`{3*J~p4j5D!6nLrScd$%D;k2hq*J@I`Z-YQVK*;QfJVY zGgK=0YM;DXwR9rNZ=LG(UWv)jVz!9dq_(M_0laQj-&UW%%$f%n6v(H#P+h1=08dkb zAoGZ|25caeNb$9*ilfA-V0E?L(TkSa7EYf|4jX6~SIr+V8?b8vF=(~+$SYg(P2f6z z^|eVxYO3L~w;X8P_eIlwqZjyPd%IA>_7jIRbLqvQ`wXCsl zzonUt^6XJJbM+o=d)xL&boZ?2C?Hr#(JQqrVYD>LSK5Wus=dOIc|Lxu38B8nY1U(V z|Ex)~ZocZg3_m%&uB_aQjQ_B>N~@Izy;J=5&$q5$^V$JLlT`d8uT74gWo!g5dXv=T zk)|&BP`3*r2Kvhi3FIg%JxKML(=VA`TI%tXPM<7}IC7(^Ky{ehj~dq1MBq4;>I2i~ z0f=#_=c)^k0*@h5Eb^hNxxYc(tbQ)Ltoe$I)OBFFJz9p@;?;V!npQ8*^NP>a&=cGgP2En#DGO400jvt|@zMA|FV)-@Bsu&1fzGm5xQYYHw^@^yF>cCaz* z*)mbgS?8v0*skx^nGfRI+P?8*QtZk75szP|=qWz%N&~njyVW-j zYOWFaQ!dIHl9q~)aU`-K`_BYwHrUs{U+Tb7em78o)bX?Kysap@tJPP0>A18=w_fFb z?;nlu<)3y=dOwG3l(;-9JZik}tc>3Fqo3Dq`FDGTv$x~R`ue8M3ibFWIIdt&1XTF2 z*ZS`w-KMRLT6yfFK1mBYhHyH7d=tz=q6eP$iiF;;c2xVk0#G05;c6^tRL?rw&N{o6 zk^L#_Y$EIII)LTU{ub3ti~3^L5`;?v(KeeTn4M;2A+Y@0t83LwEHCQVsEgD&Y{;n)Q__R90VYLKF7os@YOUE`qB!GpwG{Ww zbag(MQI23>xoc5(7Ldz4K>h zjm`1wtJ|@1WiVk-c53s#x4e$js&CX`;7DkzdtF3t<&$sJw@pSAJju04Gb5EwfG-G& zyNh|^cMP$#KPs!!>y#{4mZJ5`$hrtAzVNoo$7ZD*-CI}JR@b4w6C9A@={<6wS+hIr z4u{h|U|@P$f48$YczSyJ5E53pJHw8YwDvL1mtnC<6{Mh~$#p{JWPb0~fazhDt>LOjo$qDR$HujyMsU7yAqD8wG9JSz$3(%w9 zgoI>C0gPR5;s#k#ppKM=sj)=_d?Yjd-u}9-YaA8Us`CrpHEnd zY0D=#F%7=){qpU7c;|^&i%XO;`TlaI_8jwTApj-7kI2xMSnvE1b4PG#XYkHpoVoZ} zrl8AJV_Q52Zhr%nOaPra{F(QTYRJh~0&1q8+(uHL66fwsEv|aU%4u@e#6?Py1H<4q`t06Pu{tGYq+W2Lq37aTi+b6*}hZ10+F{H?DHO`d=fJ^ zg}FVAzd33W+Q1&3*-aGWi8yDPx7+FMXbr}-btGxwlys*~#07LyKR5ja-+jw)XecJ7DVC_yBUED4GafA%S&&DLb2( zVdtQN5)Gn_LIJ9wPO!A~#$SxT8m|~@NNuVSClKv-#@$pEcA9O3G0`YAvS>xdgKXH6 z@B5zdviXYP#@R-;ah5TYcfW!>^TbeomraYF%U8UE2(m=o7kqs|^jgOgf2*n4v9Xxb zE9S(`Gu`jEs2i00-Zs)D*mI!yw5>m!dP{+2n%U;2w*IaNFP~5e&WZlg_S?g$bNimV zCH3%ci})y^1HGB&UOw`T=hh2DE~Y`yKIF`#5rZo1gGMBs;jgftc2?4evwOt;SG>_oofo8fo$HH*a{DmZ}+TPNn57=!Q8gb z)pBS9HMcfWE7Km)ey=^Jt)M-m{XwhOdTnRhvT6NoPTO$X4BHItn6_NIMVrI#gW6ws z#aFg7Y**My`OVh;dZkvToz-{v8M3M#()9^<=fJ)ZIo$m|B2seVeD`J?Do~8`DZ8JJX$$|2gM6d@&I^GF`wxEA8FeNPO!p@{qaBC7+`s?uF~gaRjP392 zZ9lkw|ACg{JU=Mi-`{B*{ql?biY-3g4nnXqti{>m;xdS7CdAw0)e{|I#Gw;=+I)f9 z*>QpwIEn4S_30oc#y^SWhOlHH&?2x!@dq9&T7{iw9X1^b1SJlYLnJaLI@XXYuEGux z3RTb~r^e;1utV+L(;EupWMrfz+LWVc7Dp9Zzd z&ieMNU8j7mgU{940Ih{k1O$&}zL-rbXhrhA|2)>2=TZBOPkxE>c#TiKhjYD-GoHyO z=VMHWwdRW!I3C7Vzh&7(1WGo?F5#G$oLs8To9!U?d&M82Zr+?9^}5$RTP^;r*VjF= zqQp!CSwvN^erA3y{6!>--2_>=7d5FW7%Vg`oicQl_H*@Icni0vr0QtX zgTVqz(XuZ}57)m^h+H(SvkK>--SuIYH-4$JUsAY!_r7BlQs+b3FKxB;;VTPKU`!27 zj}HXM_^1i{M_)A=<;_ywEtURd=gm1oyWUyN$nR8T{CCC$0)ZD>{G+E&K?T|z)BLTs zJREl|FRtOU^pGRcj?Q5$hF-e4`KvBtDNB&LDm~G~4mr{uS#rLnH8p+qX^Y`Z9YGm0 zyj}D#st`RZw>^hCN$l;{f52(kn!os>(Su#eS9|`kr3qMHoG&eYiL*B@&F5D5;KV^> zJb2?4JK`x!FwnCkD9U&$sNUlTa0c;FJtrcX!_LeP@{?+4PP@_5BPE)6y16r=B@g8d zoU%O$-fC^JQ}d*yCC6z?oi+}59qM9-97(cUn$0?9<{y}umoYP^GBZn=nKO-Ia`KCf zS@^{MOuDeuYVdB|gAP86<1>wXV^pl2XN)(B1;a|*=W63#w#01wYR?(~X{?5;VmUFV zY-5S>3sT&zc7yRVCa4k&x)_1g{|tLZ%oNNR4OUF5$l^;5(E*TJy!N?f_v6t->x;l! z=^luVUWH;khrideiNsg|sB8XnHDDeOkTw1m8;;f9Q(whY&7)13QUo978Wi+QN6S{~Y~nbbh{vdhshGjqA;2bWjV;I9wxST-!wh0qI1e|rc?S(l2u)Jc zX?L2fzqT-a-{j~8#=~aYW6+{EX#3Oeo~V4GrpvTsr+B9;W6brF31hN6Xx6mc;JkJ0 z@W|Fvrln`g7UGAkNtroUVVcKu1;-6JnU39CK=Y}O1QSq^T2H`z?Mq8dt%#G#3QeWDc`RDwICS zta?_lD-RfR5ltz^{YDku)xKL3-qzL3nNb|Sm-6z{V(lts*<3WTHR9_Ah1-cLwiYcf zYFd((efTn>r8WxGh<+DKbJw!ads1dVQnww|^@3u&jRZ;F(aM)YEyR!v)>jg6U{wQ5+qURfvFAi=4F z=v$%%N*hgiikc$xi5j-6N;7bB|FtA%SK())YABxO#cC@F{AOeQ<(Y25H1(%yL#%C3 zr=q*9``^2G*u^aP$UNK5Ht&K$U@hj#tcV+s;cYu`@VHVeV~c>1_BpQJJt>owKdW=i zCTlcZc|uFtgTo-%*uzq+ceLf$i7mxR z?1j4k(r?6Bw5s3rV~2PBrK;+=icn~MYsMJ7QjdeesY9NuPPu2{!nwscnd(RNyWiaO z$K#nfm){2Bg8r{gg&Dqv+s4Wuw5$oC;vDS4@ zv&)`7bm(BJU>Y4?wYLG`cPF^u^L04JYia(WX^`UE+q=V_Bww7%o!Bqqhs3}Va?v27 zkbjWdX^U0du*!+WiX%w5hR_5fLb1d2cr9{xPhH(EvKWsa3$x=Wu!={zM`h(+bkUh! zt$W|wZwFRv+qS=3>o;svxO>;mU7sH5==Ka5F?>WOycVhr*>b!yynV;pTmHNQzteyV zbMLu5`)qHdCh3>f#R5(Ix%*@_O8qZZ@&3B}q1^>U8%M~!)s{UuaGSwJ=RUyRA! zvAGccn8_oQxca^Kwjbnsjs4qlhdK#Jr0ecOhiYYm=}aAeQxSpoSIqXHIuFXZM}Ul@iX5Gt{jE_bJG0ICC3I^oTW7)E!e+i7>;RO!)|De4l5 zaY$rS?FG~V1L82ZJK0oC+~JOc`}XZ??d&`e!EQKlw8Nbw&XuSG2L^_wN;EebC96$z z_Zu0dpD;=}jMC|h(nuMl@Iu`lu?W|hP50#FTsVvclb+h@YCl?`?%$y+loMzXWSjfv z(@+2RvvgDaIj9?}NZ)O7cx?Wn%jQf{7PC;LJ*g~n%qbY#-=>H)p-rDYuL#f)sxGb4 zmY3PaIQ+yiIPHW7_B$#Z3C^}m4X11GP~Eq4=U-oW?z!jQ`XX!}Ty(>%8^&j5=KrKX z2}yI@c!oXv(QgXy1uTj(5#G{Y^o7Iihv@!8$F+!O(4h460VLwsE8I4_p&2$}?%D~8 zHzXw`OS)OA+i4tc{;aX_aC>`?3hq`_0qS6gMcLtBH2Zfx{d+(CJCXhseNOl&le72K zzVr9(AGHgdq-|I2^OY4?nf58y9D4idNkl=cY{0S6dG=Sg?f5KiqPSPIu_UiV?+x0j zG7_L)F$Uyr`wDYxz!{mDeSQu5eZy;W32-ckEskp`rd_3JRk~7I2-IN&IEdf4uQ@Lc zUwnt_+{^ANAR73wQg3gvr4`*&%!B4w+oFVQ^NUYAd!jh;wc1)betWP03gZ^#MI{gZ z|BT$)rbvaobyrOd<^65bTdOD3Zg^&SFcf^TC2jmq zCc!1L8|T7q5Rc2%+ix$zB6y9JQLU_U&mN!F{a5C~@3%IaF*9iSo@S!180qp;;MAL% zpn4*4$sQ%i8}D}aKQHr~Gy6q69j)C)Pq*SuPj}JurD@%oLPe`K;RNdGc4>U%MacDvxSA&GnKh){GZev+r-#;YD7~98~?eFoffaRl-3^?dewK zohGiMk?XjN>-ag>aR=9-HZ)uc2-ijR+xv~DU?b{^k@CSwkGl7|x_tRmj<3d)u!8Gz zjRl5IcQ0Qt4TkZ5M;&m1SaG3z0u9Z^d+L(VR1%&3guiY@tUYbKYP?B3d7&Gbjz%{( z)@BkUTLsN&30?SRtR09J(S1e1(ANgZb$tej!+}9^v@>{i>gv_2tG4b}w3LZ+=gwu- zw&C{ebqz?(0nhQy-bhD(^kr1##?J1fb8>VwFYf_Un`*@1-AFXx3NUO|`x$s5%wUeM z)4Vk7*D1j3lGt}Gm-ajy_DjY5Q+Pp)36$3!m9Q@}VuQFyF8Yw`? z;)@h-%b}pJkr2u!b&-z2M6_UVKD#6GVIyGZz(m^@9y-yhY4#L1pUq0M+m@+4k;QzB4F+2(a`dvj8OCC^w;);YWQjzM zEe=V!v7`ihFHSKcQG8Plb{cL@d_`p7D&Y!`fvRk9h)a@>!`;0U zslo-w0}Aw8bL zvdS~AHI^H%nfc+8BmR)SN{5s|HKyE{oY$!r7~o(`u3Wsz)mjU1y-9xV!?{&bdaQnf`RWY*YnNgdICn( z?^~5WxQ3yB!Zh=`EBcJKStIRj|9TpuO+Ob;!7z%HAN=4iTeq@uvJ*QZ``+c#*(Z{z zM5U=62lnqrBwTqOr4S)xTD@9-0Andb%TdEX)@x(!D=kIyn8!W1+NW!?W9@1U@k<17 zy1Je4q@L!gXEB1f%?UGEvMsMMI%ZAM7I)xl2l4Vjl2AeJH|tM-R7AG$7td+_L@1k=9lOvRyF(DR78>!v2KJXS9&}HasPf-o^cUWq)wQ_J=qexDbvl(NAs# z%f2D_zqu)}^T}?3S3s)tvUe=SMZoJ9lV$)A63!_}O_L**7k3C6*6HjRg2eZ-V@SP4 z+pb8Yt`N;fKv1RVHoJpy4Joa|tE$S%^vU=vWKnKpIf`pEE0C|Y1#R`~W@ibYbPZ0i zdAbzYScG2PqIyUTDUW7TZyBCY(6>@iip#Yxjf=E-U1=23rv9>Ne_$zMZYs(RoQWW} zrAo~mK&HonTWnLyrG^$JZyA`0S`6ZmYA$fUFx8EwV+t2zkL~4E*#rk`IW?)VJQU}R z4;}RkiAd2brAH_uePABphGG81 zVzdg~v#BZ7lC%n`mQ*W}SVj4>q>?CU)yhaLNy9KRyMNDf-}gfAKD~Q?zMs$c@%TNy zJf1t}KG(U!?hl zI4Y_*^9nXJt`PcI;HnBf7u6py#nhLle%{2(8II3BR26;XNOa~zMxtpjsDC%*?NfsXM#?KY(d(C1xy_A5m zURr8qhU-nY#i=TEcARf~cF_2KvPafye*+Jho>5VCT&!se&YVcETTc~~)MTu821p;Z z$q{nYTr!jY4u^c{;jcakSpP5MF17vS!_PlBStu=)K_R zgX+b1^O{mN*a41>5OuC<-Lf={`9qfr^vCH8=$>PZtH*birv7@VGr6tTqz3uh7`>{t z#j5ToGT0L$%Z_wInZ3>Mur-M#`hzxojABB6<`G6^sAolLHUrz)*>RjTW5##)*6#W; ztVK5#30Ap$oBq`%iP@=0I@_#x_M^$Oz*h#0(X9A zKCQ|`y=-+<)X#pJqVLM~{_*X9eIse;OB(bSv{#S@z2ANu>n9dGqz@1q#%t6h?;13w zo;+>LjbDDV{vo|OJH{h<{d$BpbW=uy=;(gKhw@&3=<@M)R ztk_i5j$+-eYExzdPB{+nF2M_6fx8TAN0%n5iDK)04ju}r!x`3fLTbBQwVkuSmi~Ii z4$7R*(~@n)c);u3_RCJ_v$XY6zp~Rpf1wvBPu1+U--`6NA^kO{wCgX3Rbt}Zy(wsW zX;VY^wz3!jBg6}tLGG|7!PRVY^~G}!x;ZjJzlYgc-T2(DbMMe_rktC5?xl0bs#m&2 z2pcFC7Z<#^#pU{B%^o&TEb$iIwY>UW%InqLDdw>R4Ik<8B(8 z<7Fo^6g!(_J??vcv_L}rB&(6I4iaXFwY~UKatkf-R31qQo_pn+hcbhhig@t3FWBR? zI=D$@Mj!EkoK4S{83}sP8<^A>CSJ+pgHG4itGBsaTV5i&A%)teSCiz* zB9qTEy)U!3^R3h=I&XXsrVlrM=--5slK4kB37$!R3a5hJ-aiay=J{}<|3NrclK!jy zl#h~q{lvFSM=ap`f-F`>UMG9X*0gLvBA6;NE~IYimkAuKA@S$ z20!^4@04IiXZBYif4%vsYeTC)$=K5q&copoO8RNf0~z9}?tFb+$I~b?sJQr$)gmUQ z{N%5Di!yt%Ji1)*YF)l7zTrLb+pK0-Al;b^Y1*9rC@(K0q;MET7Ql zIz`D)7NaKeE!uQmeD{^Dxn^h9-Eqf|A?&v`uv55g{>(zrPqt>>OteG1tJH5|Yo-%S z3cO#PP2Xh}Gi0Chy<`K1)-5vY#)d|=W1q~hvfcgr4$@oXByeW}3w(V`E%e{^Eawg9 zEon5PeZ7c&gnmk9K2^6o&=rVw18ufNt>9CzQ{_0)AJb=5Sk)A?+B8LVg8gg%`1;+q z%TGsAr@xVIOzJX>6FYY->CboX`Ur~a+3k2J`5D3q9jBNmyxbFGJ@Uy1D|c`l~rDOTQnn(Th#4U)09L@CGB3j-5C{JEQ;bF=dvo-fREP zpZ%w3|8brn7vJzl_kpPlW@g6F~4Hb?92 zy9TUbHDo&3rH@wb%42kT!^d-;cyh_x+rB?`mf>Eb&I1!}?$fBa_`z;`Z*iw`yZIJn ztX}No{eP?R)JI}I?|Aj<$YGw_gP;0NwTNtc{m?0Qv@^}_WYqIwZoplsBX926A)HTk z<^-sK2H_og-aImu4bkUvbs0x=x4UD?&`yz8)%uPqdpp4-X9gs-EY+vm?>We;nfCgy zLH4%lN9S~-9-;C7Fhg?P&)&#;hnMQjPP(D79={#^lC@Zsv2k(HxAx-=uI|ef^1}Hi zx+VJm@4UlU?2Z%bdAYA|eIh8KVer{s4jvB-8+vC4|9Y!oo^)r`=FO{@=kF}fa>{q+ zFJHZRGY3JYBN$aCBe27rL&L0J51tNgn4mwr*q9lcpI`9V-qI6xqc+#Y_ZdDuEp5n< zL4D(*n+G2+*|qvv_C|Yl^{$fR!Of%N`VJa0BrR>it$pIVTv7W}>E6!@@-shl$FhgP zPe)Ew@x(A)!2!m(>iYHBr;v?g`L2l-LX~H$Sifi30c>GhM^6bDfx#{gIy-mj$WQwZ z=l~ivtYcSKojHB#^x0~*8mz3`zklDsqsNZ_e)Q;xGwjH~VQeRk^67i|(VzG2-(OiN z1Dxv0)2BH9z^>CUb2)=i|0%wggtIScxL~gm-*@4<<+8jVEGRQ%VdIBiG#7`Jh1EET z(jJWCLPZv{Nin;5D=v2n!OQbJPduwTDm$SjnV+8(&?5doVd3s*y|t2CCM9L?y24*WEJ|?AQ~UgC!D8MJiP)M&dgq^^fyk|Q zq_!yQ%<1}`#bL#AyU(^WRvr*;4)4sI>lVlLp9(g|^VXEBiRWr+N;B>b=59R(*SqYF zaI5&HJ9@Gfg>xo6YiY{@)#|Mxu6lQdD9A9vW`Bt{I?&l7Hcq&W^iWq(PX@?(frDFa zl({NCl&)}jhKSBE%JU0FH$4WDzB^8>(z|`rRb%2|E{FZ1 zSARP7SF*LxQcaH~fOPu5l1=ec@a8a{eH|F8C^acKovnsN55@ud8qGxzqP=?crv|fhHR~70)_r*O>TmTX%#2N{c5L5&XjRUQ zJX@m}(AB)Zyj_w8YL`ZxJyM*Zia(@TyUne?Rl7}PepuX#0qNH)%FzE`6}fJc-Sy0v z?hHzcM1?B;mA!=$5}FsUD=6@NaJ5oAbjhs=2|XIoji~s#pr}?%i<|nz_2Cq%4c_6K z9>Q&svjkg|^X`#z4^AH}%8*69c#|dy7?5BMZIVkZ}2`W^~Z{7ZVuD5Yt=fu zzUbiTtd{xnA6fcw>C~yEyVkuiKmUz&yGlF7GZYxmf6|ocX=&pVyLBr4cn2jsep^Dh3hhVha?3Y4<#HRRX(&ENS+IWJ4%SI< z0uW>58fEuG`F-@ZkE;$Jchw58%_AojUv<{k3pT@BXR;UH9LD!gUQWqp5gr@! zdZ-41B-zHf%BqHSYVnjhdz5+E-^wx{rCRCf+DvW|(!X~U*+%Q(o5iacVT=2EF)?t2 zX@KL5p=OIknNICBC9w^=?td@yMslfym!aFM*I<@cZ+DBh3@0+S>_B8`c?@%WiRU zcB75kyYqU7o+jV$XJwsg)q`A0^c?jJH|9LnqE|PX(4j_~HtY(M;mUhLuM2tR={&3@ zas1nxM<0dBCbs3taM-4}1r)L}JTp#|up8O0EfOci(;wWxSK`c}S*4|iI_i%HU#75? z=psgQm+b1n48(TMqWjU9#9k!b^yG_TBM+u0h%)91GCMS^O$@KM*Y(g7PWr$7NsL&v ziZ|_ce!d6=e=C&Pi0S_yNMLZqr+HXEqY{>WmZv|BE$b%c(7uvZA8ms`o2Sf$GIOyBWOSOVJB8J#F}`r+Q0oe$QaA#CcHICeSjpmCJVaWGtaP zxh(wU{ARhMteak&qIU1*+43E0N#f%2<~qJ?d*a{cno&}+eY^fds!Xm~6DL#kXR5vE zE0l^VmQs0Vf>nBY`Y`bkow-uRL#g~{A*6Rww49DaF3-^lIhm{FRG>sAo+s(KNtz0_ zpb4EnKXk6+%g`(SVSXCHrKQ2-7*kOE4JAvz*SY(B9=1<)=6?G3nfsPeS`l28*|NI2 z?AYO>M}PUf4BNQ?+YYEIt2)}%t~y>xS*Z?Y-le+w6x|z_>mi-JRp&F=V4}j*Ap{2U z#>5Kb8^*v>d=B!x!r)=t{G8^ z1-uxLE4KAxZSGO3+G;W^%sbX$@rYiap^A#gysa5=vKO;)*kvzH*%0d!6W5nzuoYH6 z+LrlfJc$YUEZ!yvz7w9wTg(EMTletxn3)B3>koc8E;&QR$5T1#I~bwcw};MWwMu5) zNVhvZ-5m*~g@vUhZg&Yo$5_4=tF&X8wl1$-TYrRK#n7=RgORc*0^VbpM=}@-`MxC+ z1HvWv`Vb8%$@+_V-=15#C&E9PW|}ai2C?*SEVH^Dst0&Vc$!UOLHg0^?yMfIWQKn` z^9(Pt5V_PHCnsg8^@(MfSln3ti_qj`RZo_wWonX#ujoD7dHebu+m&UpYmq6BC}ug- z3R&fjtKONVLU+&4#Nt+=>{Q{7_I{a9N%EQj?#%}eZg&6pqyM)R?RCgpB30ajcI{KA z*jIorA-kK}nz_U+c06cTnk*XTrJA)vR4{Rms~$l*h&ySTyo=YqQ~+zZ;#?yC^R$KTiI zABZ1rN!W9`q-ti^gkb$s_uus$LjMh1aV}Aa%iO0+%FDwh_}#r1^`C$ffn{_&_~)dG z-v3KP|L5UWZ*x*TQ4kOH;Q$o<^KkzD{=fsG_k}nSqT(V7MWSmr2lx5i`6z0IYbI#( zzb02-b4o=;KpyvE{xzQUwTeZB#$Nc3Dftil60WECFZ>s1Hz!vlI~8z1BvS~J0}3Dy zc8g?J8n9R1zucRKoN1n&w$~J^T#@KOHoWbu2M-z^mX+p!m_(&}=|-M;&AqnD-aMxqG8eT|tawwWWu zHai!hAPm?p#+nJp>#eC7=mxK7S{|#Axece-bp*!(r+ga#xBP2pRq)}FN zd0llr4yQi;3T0@`y)0==`!h}?W$7<)MT<};hil2c>!h>dU-2xvz%AB}@~n4lCvUd> zJ+9v5`9EQZr}&@v3tUflNtDeC$@35XFE9gXtL!TDegUo(Ta)zv#m7 z0wYDvh1k2f|3AW0^q=|v+wd#w-JSx%tFYGy9WKB9wBSBXfi^uyy!INmzcOpmum=By zz;B-aInGp{UH`t2pgc~P@DrSdPO|*hQ!xM6@T~cFVH*`P&ZrQ*jWyu6Q|@}BpB#H5 zX!GxIqem~ET-yz){D#03pS#mvq&qW3y7!u!=YSW=v+tf9pXu|f^p4bvd4?|b+4E8y4Ytiece-w7VzAit(Do#!inH+!p)M z{)@R@WK}`2->mX1^ZwRuJ|g_GR^fk6yG6P)fXw?*E1uIu{6xnG29b_U!S`+Q*leTSo8MZWIpMsuo=slAu`V71(NB45RqsNVJuUDT@Z(M|64p2 z-m;?0i>Am=A%n^qxBtvs^Kb8~iQ_^uTqM~S;3^YI{|<|dDlUY+Zu%c#9KJZbKin^f zA&x3sOrqmunUnrGlJ^e3aO?Apd748L$ zjdEP{nZ13va`G$1v(2^5vn?QkzDF7TzHCT?Jlu9e3B><M?CfYW)|i~$iZzPWMdD(EQAtR59P1|QXvHrwTV1By=y2F$#!qXqJQAYqD<%D zo@Yggi2n(>br>$4kERg}o==^hNg5)_SDs~7h&DZL%5ii+s7TjXsk9M1 zKON+;N@?r#^DzyQa4Vp$%oGVu3kVSj)X^eWjh_mx`|Vuw-bdMS)33=vpWb$ev6e5q z1k3|~Ngux`ARBuq_eWFC36nU(G=UMq9e_XDlpN|q3Ua3rR#9LJ+{#2Gd9lzT4i|f$ z>3U-4i6lK1^Y%+!s6 zu5=OSoy!r_ML+tUTGWGpWMrmpQ|@;LQ}4COJka`@c`-c(;bm*Sy+Z8Pc-xN%C@(O*S&W9o5lFo^<4W)5HCU=W6Nz$xXgzT>?MF3?MgUdhKq9e#&6gD z*8A<+f1uYN&ut?F8St-7SDx5yEflFi5h4|PD)#yMw>FI`8EI7U#ch@B??WWn-@28so{EgfDb!LCiz)`xu5>+Hg6v{ zO1l5-|L^>&D3PsPB2uM#*=FjwB-|iU!}SO?Nz6CXc;7oy%x7L<{)NBQGEr#8ibA8l zSZ}z*&H%7M+yB6KZPg#YU1H4z_Vq>?_X6e0ixVe#mRv*(zcs-SegXQKa}a*U?LWRp z$7fb}^s{oOF4GqIYPs2l0(h?E1cr!18f~{%iBx+5&(>w+eF$|}*W>+q;$5sUbvR{W zu`Chk=r4;tLM~L;A%qd@ZSP8mgXc1vg@t%@`gvw~XuSk&}0^W)AjzG0BW4tTp`37pZESSP#8n2Sk{=ssBE9{{KqW6fweR zD3U0fX=ZQImMBJ;5!hpKr_Vv(dj$3*HUvmOm;cBw{+4-3=6ibj^APucyK%Uci8MZ5NTGc{62v)MwaPI!iXlNOAP*=j_!(lQt0-NL ztaMqR_%y)szZc0GeC&5 zLpXw$_dS)x*m+rWHU?@7Q8fY+KW8I>_eE9FmI}=kcn#YPYX_q+Rj)mH5&Bf-0EPFA-~k(s(xLd1Ze; znL4;W&@CI*-Y6ShhFN3BOu{V*x1<_-pj!=vwtj}{doGFd-K$OfeE=IZ!3$(VsEz#} zh5hHS0#?bWfK{qRP^g%%q5a7Y43VzC_#Ic%KI!X!CMZW_Uj!!!QYOlS*q!YU+$>nr z#9e?XhqyM%NFT`HzealEYN(YYj@C-z9{S$_Zcz}p2OanbtuX__WoS@1e!$N2QKz>E zhh*~Fgx>z&+U@@Zl6BhuUqFw~Xp2_WjOA)Gc5_NS>#1{PkVhNl9Rq4R)pZ3X?>FiH z>G^se%k&r$_d@!~g{~6bb>UZ!;c)8uS zny~Y{eN)=cnz61?q+6Y{ZpwFzQKtIyBa!wl(mO`id?uuxWyMCs`&#_+1F^X*Wz-#I2tlXX~Fgz0Z(f{B6S>6`mF3e+kbu zJzulTHQy_L7}sa&aSCDT@n$wG)^>DLV(5Om9?$s31UoScxvu9ak}BaxFc!!@r-r8asZLfqqUd({2bCrSBz=UAS!|O~_oGNcb_Ny-1sO zj(6Nrq)o0*(qk)^iT`72>a#6)JST=HjTII4{%Sso_j-oE9@kZME*tNmWNz9UI+{Q=DM~a zFKI)zRIYD?T;$TfM_^7Oyb++E&-GQQj{9r~{îYvCH0N!H^J`?#$^q3r3Hez3a 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 GxATAG856z$ literal 0 HcmV?d00001 diff --git a/example/assets/rating_animation.riv b/example/assets/rating.riv similarity index 100% rename from example/assets/rating_animation.riv rename to example/assets/rating.riv diff --git a/example/assets/rewards.riv b/example/assets/rewards.riv new file mode 100644 index 0000000000000000000000000000000000000000..e05416e2781859a31419d5f8b8c378281448fd71 GIT binary patch literal 216579 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
t<|Q+TsSF1y8UqUV80l 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 d createState() => _ArtboardNestedInputsState(); -} - -class _ArtboardNestedInputsState extends State { - Artboard? _riveArtboard; - SMIBool? _circleOuterState; - SMIBool? _circleInnerState; - - @override - void initState() { - super.initState(); - - _loadRiveFile(); - } - - Future _loadRiveFile() async { - final file = await RiveFile.asset('assets/runtime_nested_inputs.riv'); - - // The artboard is the root of the animation and gets drawn in the - // Rive widget. - final artboard = file.artboardByName("MainArtboard")!.instance(); - var controller = - StateMachineController.fromArtboard(artboard, 'MainStateMachine'); - // Get the nested input CircleOuterState in the nested artboard CircleOuter - _circleOuterState = - artboard.getBoolInput("CircleOuterState", "CircleOuter"); - // Get the nested input CircleInnerState at the nested artboard path - // -> CircleOuter - // -> CircleInner - _circleInnerState = - artboard.getBoolInput("CircleInnerState", "CircleOuter/CircleInner"); - if (controller != null) { - artboard.addController(controller); - } - setState(() => _riveArtboard = artboard); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Nested Inputs'), - ), - body: Center( - child: _riveArtboard == null - ? const SizedBox() - : Stack( - children: [ - Positioned.fill( - child: Rive( - artboard: _riveArtboard!, - fit: BoxFit.fitWidth, - ), - ), - Positioned.fill( - bottom: 32, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - ElevatedButton( - child: const Text('Outer Circle'), - onPressed: () { - if (_circleOuterState != null) { - _circleOuterState!.value = - !_circleOuterState!.value; - } - }, - ), - const SizedBox(width: 10), - ElevatedButton( - child: const Text('Inner Circle'), - onPressed: () { - if (_circleInnerState != null) { - _circleInnerState!.value = - !_circleInnerState!.value; - } - }, - ), - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/example/lib/basic_text.dart b/example/lib/basic_text.dart deleted file mode 100644 index 5c8af76..0000000 --- a/example/lib/basic_text.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// Basic example playing a Rive animation from a packaged asset. -class BasicText extends StatelessWidget { - const BasicText({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Basic Text'), - ), - body: const Center( - child: RiveAnimation.asset( - 'assets/text_flutter.riv', - fit: BoxFit.cover, - ), - ), - ); - } -} diff --git a/example/lib/carousel.dart b/example/lib/carousel.dart deleted file mode 100644 index ce829a1..0000000 --- a/example/lib/carousel.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example showing how to drive a StateMachine via one numeric input. -class AnimationCarousel extends StatefulWidget { - const AnimationCarousel({Key? key}) : super(key: key); - - @override - State createState() => _AnimationCarouselState(); -} - -class _AnimationCarouselState extends State { - final riveAnimations = [ - const RiveCustomAnimationData( - name: 'assets/liquid_download.riv', - ), - const RiveCustomAnimationData( - name: 'assets/little_machine.riv', - stateMachines: ['State Machine 1'], - ), - const RiveCustomAnimationData( - name: 'assets/off_road_car.riv', - ), - const RiveCustomAnimationData( - name: 'assets/rocket.riv', - stateMachines: ['Button'], - animations: ['Roll_over'], - ), - const RiveCustomAnimationData( - name: 'assets/skills.riv', - stateMachines: ['Designer\'s Test'], - ), - // not a pretty out of the box example - const RiveCustomAnimationData( - name: 'assets/light_switch.riv', - stateMachines: ['Switch'], - ), - // v6.0 file, - // 'assets/teeny_tiny.riv', - // const RiveCustomAnimationData(name: 'assets/teeny_tiny.riv'), - ]; - - var _index = 0; - void next() { - setState(() { - _index += 1; - }); - } - - void previous() { - setState(() { - _index -= 1; - }); - } - - @override - Widget build(BuildContext context) { - final indexToShow = _index % riveAnimations.length; - return Scaffold( - appBar: AppBar( - title: const Text('Animation Carousel'), - ), - body: Center( - child: Row( - children: [ - GestureDetector( - onTap: previous, - child: const Icon(Icons.arrow_back), - ), - Expanded( - child: RiveAnimation.asset( - riveAnimations[indexToShow].name, - animations: riveAnimations[indexToShow].animations, - stateMachines: riveAnimations[indexToShow].stateMachines, - ), - ), - GestureDetector( - onTap: next, - child: const Icon(Icons.arrow_forward), - ), - ], - ), - ), - ); - } -} - -@immutable -class RiveCustomAnimationData { - final String name; - final List animations; - final List stateMachines; - - const RiveCustomAnimationData({ - required this.name, - this.animations = const [], - this.stateMachines = const [], - }); -} diff --git a/example/lib/custom_asset_loading.dart b/example/lib/custom_asset_loading.dart deleted file mode 100644 index 34b06e4..0000000 --- a/example/lib/custom_asset_loading.dart +++ /dev/null @@ -1,208 +0,0 @@ -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; -import 'package:http/http.dart' as http; - -/// An example showing how to load image or font assets dynamically. -/// -/// In this example you'll note that there is a delay in the assets -/// loading/refreshing when you tap the back/forward buttons. -/// This is because the assets are being loaded asynchronously. -/// If you want to avoid this delay you can cache the assets in memory -/// and provide them instantly. -/// -/// See `custom_cached_asset_loading.dart` for an example of this. -/// -/// See: https://rive.app/community/doc/loading-assets/doct4wVHGPgC -class CustomAssetLoading extends StatefulWidget { - const CustomAssetLoading({Key? key}) : super(key: key); - - @override - State createState() => _CustomAssetLoadingState(); -} - -class _CustomAssetLoadingState extends State { - var _index = 0; - void next() => setState(() { - _index += 1; - }); - - void previous() => setState(() { - _index -= 1; - }); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Custom Asset Loading'), - ), - body: Center( - child: Row( - children: [ - GestureDetector( - onTap: previous, - child: const Icon(Icons.arrow_back), - ), - Expanded( - child: (_index % 2 == 0) - ? const _RiveRandomImage() - : const _RiveRandomFont(), - ), - GestureDetector( - onTap: next, - child: const Icon(Icons.arrow_forward), - ), - ], - ), - ), - ); - } -} - -/// Loads a random image as an asset. -class _RiveRandomImage extends StatefulWidget { - const _RiveRandomImage(); - - @override - State<_RiveRandomImage> createState() => _RiveRandomImageState(); -} - -class _RiveRandomImageState extends State<_RiveRandomImage> { - @override - void initState() { - super.initState(); - _loadFiles(); - } - - RiveFile? _riveImageSampleFile; - - Future _loadFiles() async { - final imageFile = await RiveFile.asset( - 'assets/image_out_of_band.riv', - assetLoader: CallbackAssetLoader( - (asset, bytes) async { - // Replace image assets that are not embedded in the rive file - if (asset is ImageAsset && bytes == null) { - final res = - await http.get(Uri.parse('https://picsum.photos/500/500')); - await asset.decode(Uint8List.view(res.bodyBytes.buffer)); - return true; - } else { - return false; // use default asset loading - } - }, - ), - ); - - setState(() { - _riveImageSampleFile = imageFile; - }); - } - - @override - Widget build(BuildContext context) { - if (_riveImageSampleFile == null) { - return const Center(child: CircularProgressIndicator()); - } - - return Stack( - children: [ - RiveAnimation.direct( - _riveImageSampleFile!, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, - ), - const Positioned( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Text( - 'This example loads a random image dynamically and asynchronously.\n\nHover to zoom.', - style: TextStyle(color: Colors.black), - ), - ), - ) - ], - ); - } -} - -/// Loads a random font as an asset. -class _RiveRandomFont extends StatefulWidget { - const _RiveRandomFont(); - - @override - State<_RiveRandomFont> createState() => _RiveRandomFontState(); -} - -class _RiveRandomFontState extends State<_RiveRandomFont> { - @override - void initState() { - super.initState(); - _loadFiles(); - } - - RiveFile? _riveFontSampleFile; - - Future _loadFiles() async { - final fontFile = await RiveFile.asset( - 'assets/acqua_text_out_of_band.riv', - assetLoader: CallbackAssetLoader( - (asset, bytes) async { - // Replace font assets that are not embedded in the rive file - if (asset is FontAsset && bytes == null) { - final urls = [ - 'https://cdn.rive.app/runtime/flutter/IndieFlower-Regular.ttf', - 'https://cdn.rive.app/runtime/flutter/comic-neue.ttf', - 'https://cdn.rive.app/runtime/flutter/inter.ttf', - 'https://cdn.rive.app/runtime/flutter/inter-tight.ttf', - 'https://cdn.rive.app/runtime/flutter/josefin-sans.ttf', - 'https://cdn.rive.app/runtime/flutter/send-flowers.ttf', - ]; - - final res = await http.get( - // pick a random url from the list of fonts - Uri.parse(urls[Random().nextInt(urls.length)]), - ); - await asset.decode(Uint8List.view(res.bodyBytes.buffer)); - return true; - } else { - return false; // use default asset loading - } - }, - ), - ); - - setState(() { - _riveFontSampleFile = fontFile; - }); - } - - @override - Widget build(BuildContext context) { - if (_riveFontSampleFile == null) { - return const Center(child: CircularProgressIndicator()); - } - - return Stack( - children: [ - RiveAnimation.direct( - _riveFontSampleFile!, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, - ), - const Positioned( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Text( - 'This example loads a random font dynamically and asynchronously.\n\nClick to change drink.', - style: TextStyle(color: Colors.black), - ), - ), - ) - ], - ); - } -} diff --git a/example/lib/custom_controller.dart b/example/lib/custom_controller.dart deleted file mode 100644 index 2954dc4..0000000 --- a/example/lib/custom_controller.dart +++ /dev/null @@ -1,46 +0,0 @@ -/// Demonstrates how to create a custom controller to change the speed of an -/// animation - -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -class SpeedyAnimation extends StatelessWidget { - const SpeedyAnimation({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Custom Controller - Speed'), - ), - body: Center( - child: RiveAnimation.asset( - 'assets/vehicles.riv', - fit: BoxFit.cover, - animations: const ['idle'], - controllers: [SpeedController('curves', speedMultiplier: 3)], - ), - ), - ); - } -} - -class SpeedController extends SimpleAnimation { - final double speedMultiplier; - - SpeedController( - String animationName, { - double mix = 1, - this.speedMultiplier = 1, - }) : super(animationName, mix: mix); - - @override - void apply(RuntimeArtboard artboard, double elapsedSeconds) { - if (instance == null || !instance!.keepGoing) { - isActive = false; - } - instance! - ..animation.apply(instance!.time, coreContext: artboard, mix: mix) - ..advance(elapsedSeconds * speedMultiplier); - } -} diff --git a/example/lib/event_open_url_button.dart b/example/lib/event_open_url_button.dart deleted file mode 100644 index a8d6cce..0000000 --- a/example/lib/event_open_url_button.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; -import 'package:url_launcher/url_launcher.dart'; - -/// This example demonstrates how to open a URL from a Rive [RiveOpenUrlEvent].. -class EventOpenUrlButton extends StatefulWidget { - const EventOpenUrlButton({super.key}); - - @override - State createState() => _EventOpenUrlButtonState(); -} - -class _EventOpenUrlButtonState extends State { - late StateMachineController _controller; - - @override - void initState() { - super.initState(); - } - - void onInit(Artboard artboard) async { - _controller = StateMachineController.fromArtboard(artboard, 'button')!; - artboard.addController(_controller); - - _controller.addEventListener(onRiveEvent); - } - - void onRiveEvent(RiveEvent event) { - if (event is RiveOpenURLEvent) { - try { - final Uri url = Uri.parse(event.url); - launchUrl(url); - } on Exception catch (e) { - debugPrint(e.toString()); - } - } - } - - @override - void dispose() { - _controller.removeEventListener(onRiveEvent); - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Event Open URL'), - ), - body: Column( - children: [ - Expanded( - child: RiveAnimation.asset( - 'assets/url_event_button.riv', - onInit: onInit, - ), - ), - const Center( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Text('Open URL: https://rive.app'), - ), - ), - ], - ), - ); - } -} diff --git a/example/lib/event_star_rating.dart b/example/lib/event_star_rating.dart deleted file mode 100644 index 0d73376..0000000 --- a/example/lib/event_star_rating.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// This example demonstrates how to retrieve custom properties set on a Rive -/// event, and update the UI accordingly. -class EventStarRating extends StatefulWidget { - const EventStarRating({super.key}); - - @override - State createState() => _EventStarRatingState(); -} - -class _EventStarRatingState extends State { - late StateMachineController _controller; - - @override - void initState() { - super.initState(); - } - - String ratingValue = 'Rating: 0'; - - void onInit(Artboard artboard) async { - _controller = - StateMachineController.fromArtboard(artboard, 'State Machine 1')!; - artboard.addController(_controller); - - _controller.addEventListener(onRiveEvent); - } - - void onRiveEvent(RiveEvent event) { - // Access custom properties defined on the event - var rating = event.properties['rating'] as double; - // Schedule the setState for the next frame, as an event can be - // triggered during a current frame update - WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() { - ratingValue = 'Rating: $rating'; - }); - }); - } - - @override - void dispose() { - _controller.removeEventListener(onRiveEvent); - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Event Star Rating'), - ), - body: Column( - children: [ - Expanded( - child: RiveAnimation.asset( - 'assets/rating_animation.riv', - onInit: onInit, - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - ratingValue, - style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w600), - ), - ) - ], - ), - ); - } -} diff --git a/example/lib/example_state_machine.dart b/example/lib/example_state_machine.dart deleted file mode 100644 index 451ee99..0000000 --- a/example/lib/example_state_machine.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example showing how to drive two boolean state machine inputs. -class ExampleStateMachine extends StatefulWidget { - const ExampleStateMachine({Key? key}) : super(key: key); - - @override - State createState() => _ExampleStateMachineState(); -} - -class _ExampleStateMachineState extends State { - Artboard? _riveArtboard; - SMIBool? _hoverInput; - SMIBool? _pressInput; - - @override - void initState() { - super.initState(); - - _loadRiveFile(); - } - - Future _loadRiveFile() async { - // Load the animation file from the bundle. - final riveFile = await RiveFile.asset('assets/rocket.riv'); - - // The artboard is the root of the animation and gets drawn in the - // Rive widget. - final artboard = riveFile.mainArtboard.instance(); - var controller = StateMachineController.fromArtboard(artboard, 'Button'); - if (controller != null) { - artboard.addController(controller); - _hoverInput = controller.getBoolInput('Hover'); - _pressInput = controller.getBoolInput('Press'); - } - setState(() => _riveArtboard = artboard); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Button State Machine')), - body: _riveArtboard == null - ? const SizedBox() - : MouseRegion( - onEnter: (_) => _hoverInput?.value = true, - onExit: (_) => _hoverInput?.value = false, - child: GestureDetector( - onTapDown: (_) => _pressInput?.value = true, - onTapCancel: () => _pressInput?.value = false, - onTapUp: (_) => _pressInput?.value = false, - child: Stack( - children: [ - Rive( - fit: BoxFit.cover, - artboard: _riveArtboard!, - ), - Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: const EdgeInsets.all(18.0), - child: Text( - 'Try pressing the button...', - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - color: Colors.grey[800], - ), - ), - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/example/lib/examples/animation_painter.dart b/example/lib/examples/animation_painter.dart new file mode 100644 index 0000000..ebbbb10 --- /dev/null +++ b/example/lib/examples/animation_painter.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +/// This is an alternative controller (painter) to use instead of the +/// [RiveWidgetController]. +/// +/// This painter is used to paint/advance a state machine. Functionally it's +/// very similar to the [RiveWidgetController], which we recommend using for +/// most use cases. +class ExampleSingleAnimationPainter extends StatefulWidget { + const ExampleSingleAnimationPainter({super.key}); + + @override + State createState() => + _ExampleSingleAnimationPainterState(); +} + +class _ExampleSingleAnimationPainterState + extends State { + late File file; + Artboard? artboard; + late SingleAnimationPainter painter; + + @override + void initState() { + super.initState(); + init(); + } + + void init() async { + file = (await File.asset( + 'assets/off_road_car.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ))!; + painter = SingleAnimationPainter('idle'); + artboard = file.defaultArtboard(); + setState(() {}); + } + + @override + void dispose() { + painter.dispose(); + artboard?.dispose(); + file.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (artboard == null) { + return const Center(child: CircularProgressIndicator()); + } + return RiveArtboardWidget( + artboard: artboard!, + painter: painter, + ); + } +} diff --git a/example/lib/examples/databinding.dart b/example/lib/examples/databinding.dart new file mode 100644 index 0000000..b08db6d --- /dev/null +++ b/example/lib/examples/databinding.dart @@ -0,0 +1,105 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +/// Example using Rive data binding at runtime. +/// +/// See: https://rive.app/docs/dart/data-binding +class ExampleDataBinding extends StatefulWidget { + const ExampleDataBinding({super.key}); + + @override + State createState() => _ExampleBasicState(); +} + +class _ExampleBasicState extends State { + File? file; + RiveWidgetController? controller; + + late ViewModelInstance viewModelInstance; + late ViewModelInstance coinItemVM; + late ViewModelInstance gemItemVM; + late ViewModelInstanceNumber coinValue; + late ViewModelInstanceNumber gemValue; + + @override + void initState() { + super.initState(); + _init(); + } + + Future _init() async { + file = await File.asset( + 'assets/rewards.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + controller = RiveWidgetController(file!); + _initViewModel(); + setState(() {}); + } + + void _initViewModel() { + viewModelInstance = controller!.dataBind(DataBind.auto()); + _selectRandomToken(); + // Print the view model instance properties + print(viewModelInstance.properties); + // Get the rewards view model + coinItemVM = viewModelInstance.viewModel('Coin')!; + gemItemVM = viewModelInstance.viewModel('Gem')!; + print(coinItemVM); // Print the view model instance properties + + coinValue = coinItemVM.number('Item_Value')!; + gemValue = gemItemVM.number('Item_Value')!; + // Listen to the changes on the Item_Value input + coinValue.addListener(_onCoinValueChange); + coinValue.value = 1000; // set the initial coin value to 1000 + + gemValue.addListener(_onGemValueChange); + gemValue.value = 4000; // set the initial gem value to 4000 + } + + void _selectRandomToken() { + final random = Random.secure().nextBool() ? 'Coin' : 'Gem'; + // We randomly select to reward either coins or gems + viewModelInstance + .viewModel('Item_Selection')! + .enumerator('Item_Selection')! + .value = random; + } + + void _onCoinValueChange(double value) { + print('New coin value: $value'); + } + + void _onGemValueChange(double value) { + print('New gem value: $value'); + } + + @override + void dispose() { + coinValue.removeListener(_onCoinValueChange); + gemValue.removeListener(_onGemValueChange); + coinValue.dispose(); + gemValue.dispose(); + coinItemVM.dispose(); + gemItemVM.dispose(); + controller?.dispose(); + file?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final controller = this.controller; + if (controller == null) { + return const Center(child: CircularProgressIndicator()); + } + return RiveWidget( + controller: controller, + fit: Fit.layout, // for responsive layouts + layoutScaleFactor: 1 / 2.0, + ); + } +} diff --git a/example/lib/examples/databinding_images.dart b/example/lib/examples/databinding_images.dart new file mode 100644 index 0000000..79e9dde --- /dev/null +++ b/example/lib/examples/databinding_images.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +/// Example using Rive data binding images at runtime. +/// +/// See: https://rive.app/docs/dart/data-binding +class ExampleDataBindingImages extends StatefulWidget { + const ExampleDataBindingImages({super.key}); + + @override + State createState() => _ExampleBasicState(); +} + +class _ExampleBasicState extends State { + late ViewModelInstance viewModelInstance; + FileLoader fileLoader = FileLoader.fromAsset( + 'assets/databinding_images.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + Future loadBundleAsset(int index) async { + final ByteData data = + await rootBundle.load('assets/images/databound_image_$index.jpg'); + return data.buffer.asUint8List(); + } + + Future _clearImage() async { + final imageProperty = viewModelInstance.image('bound_image')!; + imageProperty.value = null; + setState(() {}); + } + + Future _swapImage(int index) async { + final imageProperty = viewModelInstance.image('bound_image')!; + final bytes = await loadBundleAsset(index); + final renderImage = + await RiveExampleApp.getCurrentFactory.decodeImage(bytes); + if (renderImage != null) { + imageProperty.value = renderImage; + } + setState(() {}); + } + + @override + void dispose() { + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: RiveWidgetBuilder( + fileLoader: fileLoader, + dataBind: DataBind.auto(), + onLoaded: (state) { + viewModelInstance = state.viewModelInstance!; + }, + builder: (context, state) => switch (state) { + RiveLoading() => const Center(child: CircularProgressIndicator()), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget(controller: state.controller), + }, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: _clearImage, + child: const Text('Clear image'), + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: () { + _swapImage(1); + }, + child: const Text('Swap image 1'), + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: () { + _swapImage(2); + }, + child: const Text('Swap image 2'), + ), + ), + ], + ), + ], + ); + } +} diff --git a/example/lib/examples/events.dart b/example/lib/examples/events.dart new file mode 100644 index 0000000..75ed744 --- /dev/null +++ b/example/lib/examples/events.dart @@ -0,0 +1,81 @@ +// ignore_for_file: avoid_print + +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; + +/// We strongly recommend using Data Binding instead of Rive Events for better +/// runtime control if you need to do more advanced logic than simple events. +/// +/// See: https://rive.app/docs/runtimes/data-binding +/// +/// This example demonstrates how to retrieve custom properties set on a Rive +/// event, and update the UI accordingly. +/// +/// See: https://rive.app/docs/runtimes/events +class ExampleEvents extends StatefulWidget { + const ExampleEvents({super.key}); + + @override + State createState() => _ExampleEventsState(); +} + +class _ExampleEventsState extends State { + File? _riveFile; + RiveWidgetController? _controller; + + @override + void initState() { + super.initState(); + _init(); + } + + Future _init() async { + _riveFile = await File.asset( + 'assets/rating.riv', + riveFactory: Factory.rive, + ); + _controller = RiveWidgetController(_riveFile!); + _controller?.stateMachine.addEventListener(_onRiveEvent); + setState(() {}); + } + + String ratingValue = 'Rating: 0'; + + void _onRiveEvent(Event event) { + // Access custom properties defined on the event + print(event); + var rating = event.numberProperty('rating')?.value ?? 0; + setState(() { + ratingValue = 'Rating: $rating'; + }); + } + + @override + void dispose() { + _controller?.stateMachine.removeEventListener(_onRiveEvent); + _controller?.stateMachine.dispose(); + _riveFile?.dispose(); + _controller?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: _riveFile == null + ? const SizedBox() + : RiveWidget(controller: _controller!), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + ratingValue, + style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w600), + ), + ) + ], + ); + } +} diff --git a/example/lib/examples/examples.dart b/example/lib/examples/examples.dart new file mode 100644 index 0000000..297c04a --- /dev/null +++ b/example/lib/examples/examples.dart @@ -0,0 +1,17 @@ +export 'animation_painter.dart'; +export 'databinding.dart'; +export 'events.dart'; +export 'hit_test_behaviour.dart'; +export 'inputs.dart'; +export 'network_asset.dart'; +export 'out_of_band_assets.dart'; +export 'out_of_band_assets_cached.dart'; +export 'responsive_layouts.dart'; +export 'rive_audio.dart'; +export 'rive_widget.dart'; +export 'rive_widget_builder.dart'; +export 'state_machine_painter.dart'; +export 'text_runs.dart'; +export 'ticker_mode.dart'; +export 'time_dilation.dart'; +export 'todo.dart'; diff --git a/example/lib/examples/hit_test_behaviour.dart b/example/lib/examples/hit_test_behaviour.dart new file mode 100644 index 0000000..baf87ff --- /dev/null +++ b/example/lib/examples/hit_test_behaviour.dart @@ -0,0 +1,168 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart'; + +class ExampleHitTestBehaviour extends StatefulWidget { + const ExampleHitTestBehaviour({super.key}); + + @override + State createState() => + _ExampleHitTestBehaviourState(); +} + +class _ExampleHitTestBehaviourState extends State { + FileLoader fileLoader = FileLoader.fromAsset( + 'assets/button.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + int count = 0; + RiveHitTestBehavior hitTestBehavior = RiveHitTestBehavior.opaque; + MouseCursor cursor = MouseCursor.defer; + + @override + void dispose() { + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: Stack( + children: [ + Center( + child: MouseRegion( + cursor: SystemMouseCursors.copy, + child: GestureDetector( + onTap: () { + setState(() { + count++; + }); + }, + child: Container( + width: 300, + height: 300, + color: Colors.red, + ), + ), + ), + ), + Center( + child: MouseRegion( + opaque: true, + cursor: SystemMouseCursors.click, + hitTestBehavior: HitTestBehavior.deferToChild, + child: RiveWidgetBuilder( + fileLoader: fileLoader, + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget( + controller: state.controller, + hitTestBehavior: hitTestBehavior, + cursor: cursor, + ) + }, + ), + ), + ), + ], + ), + ), + Text('Underlying Flutter container tapped: $count'), + const SizedBox( + height: 16, + ), + Text('Current hit test behaviour: $hitTestBehavior'), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + hitTestBehavior = RiveHitTestBehavior.none; + }); + }, + child: const Text('none'), + ), + ElevatedButton( + onPressed: () { + setState(() { + hitTestBehavior = RiveHitTestBehavior.opaque; + }); + }, + child: const Text('opaque'), + ), + ElevatedButton( + onPressed: () { + setState(() { + hitTestBehavior = RiveHitTestBehavior.translucent; + }); + }, + child: const Text('translucent'), + ), + ElevatedButton( + onPressed: () { + setState(() { + hitTestBehavior = RiveHitTestBehavior.transparent; + }); + }, + child: const Text('transparent'), + ) + ], + ), + ), + Text('Current mouse cursor: $cursor'), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + cursor = MouseCursor.defer; + }); + }, + child: const Text('defer'), + ), + ElevatedButton( + onPressed: () { + setState(() { + cursor = MouseCursor.uncontrolled; + }); + }, + child: const Text('unconrolled'), + ), + ElevatedButton( + onPressed: () { + setState(() { + cursor = SystemMouseCursors.contextMenu; + }); + }, + child: const Text('context menu'), + ), + ElevatedButton( + onPressed: () { + setState(() { + cursor = SystemMouseCursors.text; + }); + }, + child: const Text('text'), + ), + ], + ), + ) + ], + ); + } +} diff --git a/example/lib/examples/inputs.dart b/example/lib/examples/inputs.dart new file mode 100644 index 0000000..3d151ca --- /dev/null +++ b/example/lib/examples/inputs.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; + +/// We strongly recommend using Data Binding instead of Rive Inputs for better +/// runtime control. See: https://rive.app/docs/runtimes/data-binding +/// +/// An example showing how to drive a StateMachine via one numeric input. +/// Triggers and boolean inputs can be driven in a similar way. +/// +/// See: https://rive.app/docs/runtimes/inputs +class ExampleInputs extends StatefulWidget { + const ExampleInputs({Key? key}) : super(key: key); + + @override + State createState() => _ExampleInputsState(); +} + +class _ExampleInputsState extends State { + File? _riveFile; + RiveWidgetController? _controller; + NumberInput? _levelInput; + + Future _loadRiveFile() async { + _riveFile = await File.asset( + 'assets/skills.riv', + riveFactory: Factory.rive, + ); + // You can access nested inputs by providing an optional path to the input + _controller = RiveWidgetController(_riveFile!); + _levelInput = _controller?.stateMachine.number('Level', path: null); + /* EXAMPLE BOOLEAN INPUT API */ + // var boolInput = _controller?.stateMachine.boolean('some_bool'); + // boolInput?.value = true; + /* EXAMPLE TRIGGER INPUT API */ + // var triggerInput = _controller?.stateMachine.trigger('some_trigger'); + // triggerInput?.fire(); + setState(() {}); + } + + @override + void initState() { + super.initState(); + _loadRiveFile(); + } + + @override + void dispose() { + _levelInput?.dispose(); + _controller?.dispose(); + _riveFile?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: _riveFile == null + ? const SizedBox() + : Stack( + children: [ + Positioned.fill( + child: RiveWidget( + controller: _controller!, + ), + ), + Positioned.fill( + bottom: 32, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + ElevatedButton( + child: const Text('Beginner'), + onPressed: () => _levelInput?.value = 0, + ), + const SizedBox(width: 10), + ElevatedButton( + child: const Text('Intermediate'), + onPressed: () => _levelInput?.value = 1, + ), + const SizedBox(width: 10), + ElevatedButton( + child: const Text('Expert'), + onPressed: () => _levelInput?.value = 2, + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/example/lib/examples/network_asset.dart b/example/lib/examples/network_asset.dart new file mode 100644 index 0000000..2335848 --- /dev/null +++ b/example/lib/examples/network_asset.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleNetworkAsset extends StatefulWidget { + const ExampleNetworkAsset({super.key}); + + @override + State createState() => _ExampleNetworkAssetState(); +} + +class _ExampleNetworkAssetState extends State { + late final fileLoader = FileLoader.fromUrl( + 'https://cdn.rive.app/animations/vehicles.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + @override + void dispose() { + // This widget state owns the file loader, dispose it. + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return RiveWidgetBuilder( + fileLoader: fileLoader, + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget(controller: state.controller) + }, + ); + } +} diff --git a/example/lib/examples/out_of_band_assets.dart b/example/lib/examples/out_of_band_assets.dart new file mode 100644 index 0000000..b30029d --- /dev/null +++ b/example/lib/examples/out_of_band_assets.dart @@ -0,0 +1,232 @@ +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:http/http.dart' as http; + +/// An example showing how to load image or font assets dynamically. +/// +/// In this example you'll note that there is a delay in the assets +/// loading/refreshing when you tap the back/forward buttons. +/// This is because the assets are being loaded asynchronously. +/// If you want to avoid this delay you can cache the assets in memory +/// and provide them instantly. +/// +/// See `out_of_band_assets_cached.dart` for an example of this. +/// +/// See: https://rive.app/docs/runtimes/loading-assets +class ExampleOutOfBandAssetLoading extends StatefulWidget { + const ExampleOutOfBandAssetLoading({Key? key}) : super(key: key); + + @override + State createState() => + _ExampleOutOfBandAssetLoadingState(); +} + +class _ExampleOutOfBandAssetLoadingState + extends State { + var _index = 0; + void next() => setState(() { + _index += 1; + }); + + void previous() => setState(() { + _index -= 1; + }); + + @override + Widget build(BuildContext context) { + return Center( + child: Row( + children: [ + GestureDetector( + onTap: previous, + child: const Icon(Icons.arrow_back), + ), + Expanded( + child: (_index % 2 == 0) + ? const _RiveRandomImage() + : const _RiveRandomFont(), + ), + GestureDetector( + onTap: next, + child: const Icon(Icons.arrow_forward), + ), + ], + ), + ); + } +} + +/// Loads a random image as an asset. +class _RiveRandomImage extends StatefulWidget { + const _RiveRandomImage(); + + @override + State<_RiveRandomImage> createState() => _RiveRandomImageState(); +} + +class _RiveRandomImageState extends State<_RiveRandomImage> { + @override + void initState() { + super.initState(); + _loadFiles(); + } + + File? _riveImageSampleFile; + RiveWidgetController? _controller; + + Future _loadFiles() async { + final imageFile = await File.asset( + 'assets/image_out_of_band.riv', + riveFactory: Factory.rive, + assetLoader: (asset, bytes) { + if (asset is ImageAsset && bytes == null) { + http.get(Uri.parse('https://picsum.photos/500/500')).then((res) { + if (mounted) { + asset.decode(Uint8List.view(res.bodyBytes.buffer)); + setState(() { + // force rebuild in case the Rive graphic is no longer advancing + }); + } + }); + return true; // Tell the runtime not to load the asset automatically + } else { + // Tell the runtime to proceed with loading the asset if it exists + return false; + } + }, + ); + + setState(() { + _riveImageSampleFile = imageFile; + _controller = RiveWidgetController(_riveImageSampleFile!); + }); + } + + @override + void dispose() { + _controller?.dispose(); + _riveImageSampleFile?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_riveImageSampleFile == null) { + return const Center(child: CircularProgressIndicator()); + } + + return Stack( + children: [ + _controller == null + ? const SizedBox() + : RiveWidget(controller: _controller!), + const Positioned( + child: Padding( + padding: EdgeInsets.all(8.0), + child: Text( + 'This example loads a random image dynamically and asynchronously.\n\nHover to zoom.', + style: TextStyle(color: Colors.black), + ), + ), + ) + ], + ); + } +} + +/// Loads a random font as an asset. +class _RiveRandomFont extends StatefulWidget { + const _RiveRandomFont(); + + @override + State<_RiveRandomFont> createState() => _RiveRandomFontState(); +} + +class _RiveRandomFontState extends State<_RiveRandomFont> { + @override + void initState() { + super.initState(); + _loadFiles(); + } + + File? _riveFontSampleFile; + RiveWidgetController? _controller; + + Future _loadFiles() async { + final fontFile = await File.asset( + 'assets/acqua_text_out_of_band.riv', + riveFactory: Factory.rive, + assetLoader: (asset, bytes) { + // Replace font assets that are not embedded in the rive file + if (asset is FontAsset && bytes == null) { + final urls = [ + 'https://cdn.rive.app/runtime/flutter/IndieFlower-Regular.ttf', + 'https://cdn.rive.app/runtime/flutter/comic-neue.ttf', + 'https://cdn.rive.app/runtime/flutter/inter.ttf', + 'https://cdn.rive.app/runtime/flutter/inter-tight.ttf', + 'https://cdn.rive.app/runtime/flutter/josefin-sans.ttf', + 'https://cdn.rive.app/runtime/flutter/send-flowers.ttf', + ]; + + // pick a random url from the list of fonts + http.get(Uri.parse(urls[Random().nextInt(urls.length)])).then((res) { + if (mounted) { + asset.decode( + Uint8List.view(res.bodyBytes.buffer), + ); + setState(() { + // force rebuild in case the Rive graphic is no longer advancing + }); + } + }); + return true; // Tell the runtime not to load the asset automatically + } else { + // Tell the runtime to proceed with loading the asset if it exists + return false; + } + }, + ); + + setState(() { + _riveFontSampleFile = fontFile; + _controller = RiveWidgetController(_riveFontSampleFile!); + }); + } + + @override + void dispose() { + _controller?.dispose(); + _riveFontSampleFile?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_controller == null) { + return const Center(child: CircularProgressIndicator()); + } + + return Stack( + children: [ + _riveFontSampleFile == null + ? const SizedBox() + : RiveWidget( + controller: _controller!, + fit: Fit.cover, + ), + const Positioned( + child: Padding( + padding: EdgeInsets.all(8.0), + child: Text( + 'This example loads a random font dynamically and asynchronously.\n\nClick to change drink.', + style: TextStyle(color: Colors.black), + ), + ), + ) + ], + ); + } +} diff --git a/example/lib/custom_cached_asset_loading.dart b/example/lib/examples/out_of_band_assets_cached.dart similarity index 55% rename from example/lib/custom_cached_asset_loading.dart rename to example/lib/examples/out_of_band_assets_cached.dart index 176f81b..4e2266b 100644 --- a/example/lib/custom_cached_asset_loading.dart +++ b/example/lib/examples/out_of_band_assets_cached.dart @@ -1,12 +1,11 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; import 'dart:math'; import 'dart:typed_data'; -import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; -import 'package:rive/rive.dart'; - /// An example showing how to load image or font assets dynamically. /// /// In this example there is no delay in the assets loading, as they are @@ -15,20 +14,26 @@ import 'package:rive/rive.dart'; /// The example also shows how to swap out the assets multiple times by /// keeping a reference to the asset and swapping it out. /// -/// See: https://rive.app/community/doc/loading-assets/doct4wVHGPgC -class CustomCachedAssetLoading extends StatefulWidget { - const CustomCachedAssetLoading({Key? key}) : super(key: key); +/// Note that this swaps out the image/font on the Rive File instance. All +/// artboards created from this file will use the same asset reference. Meaning +/// that if you swap out the image/font on the Rive File instance, all +/// artboards created from this file will use the new asset reference. +/// +/// See: https://rive.app/docs/runtimes/loading-assets +class ExampleOutOfBandCachedAssetLoading extends StatefulWidget { + const ExampleOutOfBandCachedAssetLoading({Key? key}) : super(key: key); @override - State createState() => - _CustomCachedAssetLoadingState(); + State createState() => + _ExampleOutOfBandCachedAssetLoadingState(); } -class _CustomCachedAssetLoadingState extends State { +class _ExampleOutOfBandCachedAssetLoadingState + extends State { var _index = 0; var _ready = false; - final _imageCache = []; - final _fontCache = []; + final _imageCache = []; + final _fontCache = []; @override void initState() { @@ -42,7 +47,7 @@ class _CustomCachedAssetLoadingState extends State { loadImage() async { final res = await http.get(Uri.parse('https://picsum.photos/500/500')); final body = Uint8List.view(res.bodyBytes.buffer); - final image = await ImageAsset.parseBytes(body); + final image = await RiveExampleApp.getCurrentFactory.decodeImage(body); if (image != null) { _imageCache.add(image); } @@ -51,7 +56,7 @@ class _CustomCachedAssetLoadingState extends State { loadFont(url) async { final res = await http.get(Uri.parse(url)); final body = Uint8List.view(res.bodyBytes.buffer); - final font = await FontAsset.parseBytes(body); + final font = await RiveExampleApp.getCurrentFactory.decodeFont(body); if (font != null) { _fontCache.add(font); @@ -75,7 +80,9 @@ class _CustomCachedAssetLoadingState extends State { await Future.wait(futures); - setState(() => _ready = true); + if (mounted) { + setState(() => _ready = true); + } } void next() { @@ -86,49 +93,53 @@ class _CustomCachedAssetLoadingState extends State { setState(() => _index -= 1); } + @override + void dispose() { + for (var image in _imageCache) { + image.dispose(); + } + for (var font in _fontCache) { + font.dispose(); + } + super.dispose(); + } + @override Widget build(BuildContext context) { if (!_ready) { - return const Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Text('Warming up cache. Loading files from network...'), - ), - CircularProgressIndicator( - strokeWidth: 2, - ), - ], - ), + return const Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.all(8.0), + child: Text('Warming up cache. Loading files from network...'), + ), + CircularProgressIndicator( + strokeWidth: 2, + ), + ], ), ); } - return Scaffold( - appBar: AppBar( - title: const Text('Custom Cached Asset Loading'), - ), - body: Center( - child: Row( - children: [ - GestureDetector( - onTap: previous, - child: const Icon(Icons.arrow_back), - ), - Expanded( - child: (_index % 2 == 0) - ? _RiveRandomCachedImage(imageCache: _imageCache) - : _RiveRandomCachedFont(fontCache: _fontCache), - ), - GestureDetector( - onTap: next, - child: const Icon(Icons.arrow_forward), - ), - ], - ), + return Center( + child: Row( + children: [ + GestureDetector( + onTap: previous, + child: const Icon(Icons.arrow_back), + ), + Expanded( + child: (_index % 2 == 0) + ? _RiveRandomCachedImage(imageCache: _imageCache) + : _RiveRandomCachedFont(fontCache: _fontCache), + ), + GestureDetector( + onTap: next, + child: const Icon(Icons.arrow_forward), + ), + ], ), ); } @@ -155,34 +166,46 @@ class __RiveRandomCachedImageState extends State<_RiveRandomCachedImage> { _loadRiveFile(); } - RiveFile? _riveImageSampleFile; + File? _riveImageSampleFile; + RiveWidgetController? _controller; // A reference to the Rive image. Can be use to swap out the image at any // point. ImageAsset? _imageAsset; Future _loadRiveFile() async { - final imageFile = await RiveFile.asset( + final imageFile = await File.asset( 'assets/image_out_of_band.riv', - assetLoader: CallbackAssetLoader( - (asset, bytes) async { - if (asset is ImageAsset) { - asset.image = _imageCache[Random().nextInt(_imageCache.length)]; - // Maintain a reference to the image asset - // so we can swap it out later instantly. - _imageAsset = asset; - return true; - } - return false; - }, - ), + riveFactory: RiveExampleApp.getCurrentFactory, + assetLoader: (asset, bytes) { + if (asset is ImageAsset) { + asset.renderImage(_imageCache[Random().nextInt(_imageCache.length)]); + // Maintain a reference to the image asset + // so we can swap it out later instantly. + _imageAsset = asset; + return true; + } + return false; + }, ); - setState(() => _riveImageSampleFile = imageFile); + if (mounted) { + setState(() { + _riveImageSampleFile = imageFile; + _controller = RiveWidgetController(_riveImageSampleFile!); + }); + } + } + + @override + void dispose() { + _riveImageSampleFile?.dispose(); + _controller?.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { - if (_riveImageSampleFile == null) { + if (_controller == null) { return const Center(child: CircularProgressIndicator()); } @@ -191,10 +214,9 @@ class __RiveRandomCachedImageState extends State<_RiveRandomCachedImage> { Expanded( child: Stack( children: [ - RiveAnimation.direct( - _riveImageSampleFile!, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, + RiveWidget( + controller: _controller!, + fit: Fit.cover, ), const Positioned( child: Padding( @@ -212,8 +234,11 @@ class __RiveRandomCachedImageState extends State<_RiveRandomCachedImage> { padding: const EdgeInsets.all(8.0), child: ElevatedButton( onPressed: () { - _imageAsset?.image = - _imageCache[Random().nextInt(_imageCache.length)]; + _imageAsset?.renderImage( + _imageCache[Random().nextInt(_imageCache.length)]); + setState(() { + // force rebuild for Rive widget to update the image + }); }, child: const Text('Random image'), ), @@ -244,32 +269,42 @@ class __RiveRandomCachedFontState extends State<_RiveRandomCachedFont> { _loadRiveFile(); } - RiveFile? _riveFontSampleFile; + File? _riveFontSampleFile; + RiveWidgetController? _controller; final List _fontAssets = []; Future _loadRiveFile() async { - final fontFile = await RiveFile.asset( + final fontFile = await File.asset( 'assets/acqua_text_out_of_band.riv', - assetLoader: CallbackAssetLoader( - (asset, bytes) async { - if (asset is FontAsset) { - asset.font = _fontCache[Random().nextInt(_fontCache.length)]; - _fontAssets.add(asset); - return true; - } - return false; - }, - ), + riveFactory: RiveExampleApp.getCurrentFactory, + assetLoader: (asset, bytes) { + if (asset is FontAsset) { + asset.font(_fontCache[Random().nextInt(_fontCache.length)]); + _fontAssets.add(asset); + return true; + } + return false; + }, ); - setState(() { - _riveFontSampleFile = fontFile; - }); + if (mounted) { + setState(() { + _riveFontSampleFile = fontFile; + _controller = RiveWidgetController(_riveFontSampleFile!); + }); + } + } + + @override + void dispose() { + _riveFontSampleFile?.dispose(); + _controller?.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { - if (_riveFontSampleFile == null) { + if (_controller == null) { return const Center(child: CircularProgressIndicator()); } @@ -278,10 +313,9 @@ class __RiveRandomCachedFontState extends State<_RiveRandomCachedFont> { Expanded( child: Stack( children: [ - RiveAnimation.direct( - _riveFontSampleFile!, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, + RiveWidget( + controller: _controller!, + fit: Fit.cover, ), const Positioned( child: Padding( @@ -300,7 +334,10 @@ class __RiveRandomCachedFontState extends State<_RiveRandomCachedFont> { child: ElevatedButton( onPressed: () { for (var element in _fontAssets) { - element?.font = _fontCache[Random().nextInt(_fontCache.length)]; + element?.font(_fontCache[Random().nextInt(_fontCache.length)]); + setState(() { + // force rebuild for Rive widget to update the image + }); } }, child: const Text('Random font'), diff --git a/example/lib/examples/responsive_layouts.dart b/example/lib/examples/responsive_layouts.dart new file mode 100644 index 0000000..6665440 --- /dev/null +++ b/example/lib/examples/responsive_layouts.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleResponsiveLayouts extends StatefulWidget { + const ExampleResponsiveLayouts({super.key}); + + @override + State createState() => + _ExampleResponsiveLayoutsState(); +} + +class _ExampleResponsiveLayoutsState extends State { + late final fileLoader = FileLoader.fromAsset( + 'assets/layout_test.riv', + // Choose which renderer to use + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + @override + void dispose() { + // This widget state owns the file loader, dispose it. + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return RiveWidgetBuilder( + fileLoader: fileLoader, + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget( + controller: state.controller, + fit: Fit.layout, // pass Fit.layout to use Rive's layout system + // layoutScaleFactor: 1 / 2, // Optionally: scale the layout + ) + }, + ); + } +} diff --git a/example/lib/examples/rive_audio.dart b/example/lib/examples/rive_audio.dart new file mode 100644 index 0000000..1262f0e --- /dev/null +++ b/example/lib/examples/rive_audio.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart'; + +/// An example showing Rive Audio working with the Rive Widget. +/// +/// There is nothing special that needs to be done to get audio working at +/// runtime. +/// +/// See: https://rive.app/docs/editor/events/audio-events +class ExampleRiveAudio extends StatefulWidget { + const ExampleRiveAudio({super.key}); + + @override + State createState() => _ExampleRiveAudioState(); +} + +class _ExampleRiveAudioState extends State { + late final fileLoader = FileLoader.fromAsset('assets/lip-sync.riv', + riveFactory: RiveExampleApp.getCurrentFactory); + + @override + void dispose() { + // This widget state owns the file loader, dispose it. + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return RiveWidgetBuilder( + fileLoader: fileLoader, + artboardSelector: ArtboardSelector.byName('Lip_sync_2'), + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget(controller: state.controller) + }, + ); + } +} diff --git a/example/lib/examples/rive_widget.dart b/example/lib/examples/rive_widget.dart new file mode 100644 index 0000000..595aec0 --- /dev/null +++ b/example/lib/examples/rive_widget.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleRiveWidget extends StatefulWidget { + const ExampleRiveWidget({super.key}); + + @override + State createState() => _ExampleRiveWidgetState(); +} + +class _ExampleRiveWidgetState extends State { + late File file; + late RiveWidgetController controller; + late ViewModelInstance viewModelInstance; + bool isInitialized = false; + + @override + void initState() { + super.initState(); + initRive(); + } + + void initRive() async { + file = (await File.asset( + 'assets/rewards.riv', + // Choose which renderer to use + riveFactory: RiveExampleApp.getCurrentFactory, + ))!; + controller = RiveWidgetController(file); + viewModelInstance = controller.dataBind(DataBind.auto()); + setState(() => isInitialized = true); + } + + @override + void dispose() { + // This widget state created the file, controller, and view model instance. + // Dispose them once they are no longer needed. + file.dispose(); + controller.dispose(); + viewModelInstance.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (!isInitialized) { + return const Center(child: CircularProgressIndicator()); + } + return RiveWidget( + controller: controller, + fit: Fit.layout, + layoutScaleFactor: 1 / 3, + ); + } +} diff --git a/example/lib/examples/rive_widget_builder.dart b/example/lib/examples/rive_widget_builder.dart new file mode 100644 index 0000000..4e35b13 --- /dev/null +++ b/example/lib/examples/rive_widget_builder.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleRiveWidgetBuilder extends StatefulWidget { + const ExampleRiveWidgetBuilder({super.key}); + + @override + State createState() => + _ExampleRiveWidgetBuilderState(); +} + +class _ExampleRiveWidgetBuilderState extends State { + late final fileLoader = FileLoader.fromAsset( + 'assets/rewards.riv', + // Choose which renderer to use + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + @override + void dispose() { + // This widget state owns the file loader, dispose it. + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return RiveWidgetBuilder( + fileLoader: fileLoader, + dataBind: DataBind.auto(), + // Optional `onFailed` callback to handle loading errors + onFailed: (error, stackTrace) { + print(error); + print(stackTrace); + }, + // Optional `onLoaded` callback to access the loaded state + onLoaded: (state) { + print('Rive loaded'); + }, + // Optionally specify the controller to create + // controller: (file) => RiveWidgetController(file), + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget( + controller: state.controller, + fit: Fit.layout, + layoutScaleFactor: 1 / 3, + ) + }, + ); + } +} diff --git a/example/lib/examples/state_machine_painter.dart b/example/lib/examples/state_machine_painter.dart new file mode 100644 index 0000000..94cd4ef --- /dev/null +++ b/example/lib/examples/state_machine_painter.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart' as rive; +import 'package:rive_example/main.dart' show RiveExampleApp; + +/// This is an alternative controller (painter) to use instead of the +/// [RiveWidgetController]. +/// +/// This painter is used to paint/advance a state machine. Functionally it's +/// very similar to the [RiveWidgetController], which we recommend using for +/// most use cases. +class ExampleStateMachinePainter extends StatefulWidget { + const ExampleStateMachinePainter({super.key}); + + @override + State createState() => + _ExampleStateMachinePainterState(); +} + +class _ExampleStateMachinePainterState + extends State { + late rive.File file; + rive.Artboard? artboard; + rive.ViewModelInstance? viewModelInstance; + late rive.StateMachinePainter painter; + + @override + void initState() { + super.initState(); + init(); + } + + void _withStateMachine(rive.StateMachine stateMachine) { + stateMachine.bindViewModelInstance(viewModelInstance!); + } + + void init() async { + file = (await rive.File.asset( + 'assets/rewards.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ))!; + painter = rive.StateMachinePainter(withStateMachine: _withStateMachine); + artboard = file.defaultArtboard(); + viewModelInstance = + file.defaultArtboardViewModel(artboard!)!.createDefaultInstance(); + setState(() {}); + } + + @override + void dispose() { + painter.dispose(); + artboard?.dispose(); + viewModelInstance?.dispose(); + file.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (artboard == null) { + return const Center(child: CircularProgressIndicator()); + } + return rive.RiveArtboardWidget( + artboard: artboard!, + painter: painter, + ); + } +} diff --git a/example/lib/examples/text_runs.dart b/example/lib/examples/text_runs.dart new file mode 100644 index 0000000..0d162cc --- /dev/null +++ b/example/lib/examples/text_runs.dart @@ -0,0 +1,88 @@ +import 'package:flutter/services.dart'; + +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +/// We strongly recommend using Data Binding instead of updating text runs +/// manually. See: https://rive.app/docs/runtimes/data-binding +/// +/// An example showing how to read and update text runs at runtime. +/// See: https://rive.app/docs/runtimes/text +class ExampleTextRuns extends StatefulWidget { + const ExampleTextRuns({super.key}); + + @override + State createState() => _ExampleTextRunsState(); +} + +class _ExampleTextRunsState extends State { + File? _riveFile; + RiveWidgetController? _controller; + + Future _init() async { + _riveFile = await File.asset( + 'assets/electrified_button_nested_text.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + assetLoader: (asset, bytes) { + if (asset is FontAsset) { + _loadFont(asset); + return true; + } + return false; + }, + ); + _controller = RiveWidgetController( + _riveFile!, + artboardSelector: ArtboardSelector.byName('Button'), + stateMachineSelector: StateMachineSelector.byName('button'), + ); + + // Read/update text runs + // You can access nested text runs by providing an optional path + final initialText = + _controller?.artboard.getText('button_text', path: null); + print('Initial text: $initialText'); + _controller?.artboard.setText('button_text', 'Hello, world!'); + final updatedText = _controller?.artboard.getText('button_text'); + print('Updated text: $updatedText'); + setState(() {}); + } + + @override + void initState() { + super.initState(); + _init(); + } + + @override + void dispose() { + _controller?.dispose(); + _riveFile?.dispose(); + super.dispose(); + } + + // This example has the font asset external from the Rive file, and we're + // loading it manually. If you embedded the font in the Rive file, you can + // skip this step. + // + // See: https://rive.app/docs/runtimes/loading-assets + Future _loadFont(FontAsset asset) async { + final bytes = await rootBundle.load('assets/fonts/Inter-Regular.ttf'); + final font = await RiveExampleApp.getCurrentFactory + .decodeFont(bytes.buffer.asUint8List()); + if (font != null && mounted) { + asset.font(font); + font.dispose(); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: _riveFile == null + ? const SizedBox() + : RiveWidget(controller: _controller!), + ); + } +} diff --git a/example/lib/examples/ticker_mode.dart b/example/lib/examples/ticker_mode.dart new file mode 100644 index 0000000..9d6bcc7 --- /dev/null +++ b/example/lib/examples/ticker_mode.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleTickerMode extends StatefulWidget { + const ExampleTickerMode({super.key}); + + @override + State createState() => _ExampleTickerModeState(); +} + +class _ExampleTickerModeState extends State { + FileLoader fileLoader = FileLoader.fromAsset( + 'assets/little_machine.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + var tickerMode = false; + + @override + void dispose() { + fileLoader.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: TickerMode( + enabled: tickerMode, + child: RiveWidgetBuilder( + fileLoader: fileLoader, + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget(controller: state.controller) + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: tickerMode + ? const Text('Ticker mode enabled') + : const Text('Ticker mode disabled')), + Padding( + padding: const EdgeInsets.all(8.0), + child: ElevatedButton( + onPressed: () { + setState(() { + tickerMode = !tickerMode; + }); + }, + child: const Text('Toggle ticker mode'), + ), + ) + ], + ); + } +} diff --git a/example/lib/examples/time_dilation.dart b/example/lib/examples/time_dilation.dart new file mode 100644 index 0000000..798168a --- /dev/null +++ b/example/lib/examples/time_dilation.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:rive/rive.dart'; +import 'package:rive_example/main.dart' show RiveExampleApp; + +class ExampleTimeDilation extends StatefulWidget { + const ExampleTimeDilation({super.key}); + + @override + State createState() => _ExampleTimeDilationState(); +} + +class _ExampleTimeDilationState extends State { + FileLoader fileLoader = FileLoader.fromAsset( + 'assets/little_machine.riv', + riveFactory: RiveExampleApp.getCurrentFactory, + ); + + @override + void dispose() { + fileLoader.dispose(); + timeDilation = 1; // reset time dilation to normal + super.dispose(); + } + + @override + Widget build(BuildContext context) { + timeDilation = 5; // 5x slower than normal + return RiveWidgetBuilder( + fileLoader: fileLoader, + builder: (context, state) => switch (state) { + RiveLoading() => const Center( + child: Center(child: CircularProgressIndicator()), + ), + RiveFailed() => ErrorWidget.withDetails( + message: state.error.toString(), + error: FlutterError(state.error.toString()), + ), + RiveLoaded() => RiveWidget(controller: state.controller) + }, + ); + } +} diff --git a/example/lib/examples/todo.dart b/example/lib/examples/todo.dart new file mode 100644 index 0000000..3e5fccc --- /dev/null +++ b/example/lib/examples/todo.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class Todo extends StatelessWidget { + const Todo({super.key}); + + @override + Widget build(BuildContext context) { + return const Center( + child: Text('Todo - coming soon'), + ); + } +} diff --git a/example/lib/liquid_download.dart b/example/lib/liquid_download.dart deleted file mode 100644 index cd8f89d..0000000 --- a/example/lib/liquid_download.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example showing how to drive a StateMachine via a trigger and number -/// input. -class LiquidDownload extends StatefulWidget { - const LiquidDownload({Key? key}) : super(key: key); - - @override - State createState() => _LiquidDownloadState(); -} - -class _LiquidDownloadState extends State { - Artboard? _riveArtboard; - SMITrigger? _start; - SMINumber? _progress; - - @override - void initState() { - super.initState(); - _loadRiveFile(); - } - - Future _loadRiveFile() async { - final file = await RiveFile.asset('assets/liquid_download.riv'); - // The artboard is the root of the animation and gets drawn in the - // Rive widget. - final artboard = file.mainArtboard.instance(); - var controller = StateMachineController.fromArtboard(artboard, 'Download'); - if (controller != null) { - artboard.addController(controller); - _start = controller.getTriggerInput('Download'); - _progress = controller.getNumberInput('Progress'); - } - setState(() => _riveArtboard = artboard); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Liquid Download'), - ), - body: Center( - child: _riveArtboard == null - ? const SizedBox() - : GestureDetector( - onTapDown: (_) => _start?.value = true, - child: Column( - children: [ - const SizedBox(height: 10), - const Text( - 'Press to activate, slide for progress...', - style: TextStyle( - fontSize: 18, - ), - ), - Slider( - value: _progress!.value, - min: 0, - max: 100, - label: _progress!.value.round().toString(), - onChanged: (double value) => setState(() { - _progress!.value = value; - }), - ), - const SizedBox(height: 10), - Expanded( - child: Rive( - artboard: _riveArtboard!, - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/example/lib/little_machine.dart b/example/lib/little_machine.dart deleted file mode 100644 index ee3c143..0000000 --- a/example/lib/little_machine.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example showing how to drive a StateMachine via a trigger input. -class LittleMachine extends StatefulWidget { - const LittleMachine({Key? key}) : super(key: key); - - @override - State createState() => _LittleMachineState(); -} - -class _LittleMachineState extends State { - /// Message that displays when state has changed - String stateChangeMessage = ''; - - Artboard? _riveArtboard; - SMITrigger? _trigger; - - @override - void initState() { - super.initState(); - _loadRiveFile(); - } - - Future _loadRiveFile() async { - final file = await RiveFile.asset('assets/little_machine.riv'); - - // The artboard is the root of the animation and gets drawn in the - // Rive widget. - final artboard = file.mainArtboard.instance(); - var controller = StateMachineController.fromArtboard( - artboard, - 'State Machine 1', - onStateChange: _onStateChange, - ); - if (controller != null) { - artboard.addController(controller); - _trigger = controller.getTriggerInput('Trigger 1'); - } - setState(() => _riveArtboard = artboard); - } - - /// Do something when the state machine changes state - void _onStateChange(String stateMachineName, String stateName) => setState( - () => stateChangeMessage = - 'State Changed in $stateMachineName to $stateName', - ); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Little Machine')), - body: Stack( - children: [ - _riveArtboard == null - ? const SizedBox() - : GestureDetector( - onTapDown: (_) => _trigger?.fire(), - child: Rive( - artboard: _riveArtboard!, - fit: BoxFit.cover, - ), - ), - const Align( - alignment: Alignment.topCenter, - child: Padding( - padding: EdgeInsets.all(16.0), - child: Text( - 'Press to activate!', - style: TextStyle(fontSize: 18, color: Colors.black), - ), - ), - ), - Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - stateChangeMessage, - style: const TextStyle( - color: Colors.black, fontWeight: FontWeight.bold), - ), - ), - ) - ], - ), - ); - } -} diff --git a/example/lib/main.dart b/example/lib/main.dart index b771da5..619f662 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,139 +1,434 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; +import 'package:rive_example/examples/databinding_images.dart'; +import 'package:rive_example/examples/examples.dart'; +import 'package:rive/rive.dart' as rive; -import 'package:rive_example/artboard_nested_inputs.dart'; -import 'package:rive_example/custom_asset_loading.dart'; -import 'package:rive_example/custom_cached_asset_loading.dart'; -import 'package:rive_example/carousel.dart'; -import 'package:rive_example/custom_controller.dart'; -import 'package:rive_example/event_open_url_button.dart'; -import 'package:rive_example/event_star_rating.dart'; -import 'package:rive_example/example_state_machine.dart'; -import 'package:rive_example/liquid_download.dart'; -import 'package:rive_example/little_machine.dart'; -import 'package:rive_example/play_one_shot_animation.dart'; -import 'package:rive_example/play_pause_animation.dart'; -import 'package:rive_example/rive_audio.dart'; -import 'package:rive_example/rive_audio_out_of_band.dart'; -import 'package:rive_example/simple_animation.dart'; -import 'package:rive_example/simple_animation_network.dart'; -import 'package:rive_example/simple_machine_listener.dart'; -import 'package:rive_example/simple_state_machine.dart'; -import 'package:rive_example/skinning_demo.dart'; -import 'package:rive_example/state_machine_skills.dart'; -import 'package:rive_example/basic_text.dart'; +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await rive.RiveNative.init(); -void main() { - /// Initialize Rive's text, audio, and layout engines. - /// This will automatically be called the first time a RiveFile is loaded if - /// it has not been initialized. And does not need to be called. - /// - /// However, calling it early here makes the first - /// visible Rive graphic load faster. - unawaited(RiveFile.initialize()); runApp( MaterialApp( title: 'Rive Example', home: const RiveExampleApp(), - darkTheme: ThemeData.dark().copyWith( + darkTheme: ThemeData( + fontFamily: 'JetBrainsMono', + brightness: Brightness.dark, scaffoldBackgroundColor: _backgroundColor, appBarTheme: const AppBarTheme(backgroundColor: _appBarColor), - colorScheme: ColorScheme.fromSwatch().copyWith(primary: _primaryColor), + colorScheme: ColorScheme.fromSwatch(brightness: Brightness.dark) + .copyWith(primary: _primaryColor), ), themeMode: ThemeMode.dark, ), ); } +/// Determines which factory/renderer to use for the Rive examples. +/// +/// In your app you can combine the usage of the Rive Renderer and the Flutter +/// Renderer. For this example app we have a static variable to determine which +/// factory to use app wide. +/// +/// - `rive` uses the Rive Renderer +/// - `flutter` uses the Flutter Renderer (Skia / Impeller) +enum RiveFactoryToUse { + rive, + flutter, +} + /// An example application demoing Rive. class RiveExampleApp extends StatefulWidget { const RiveExampleApp({Key? key}) : super(key: key); + static RiveFactoryToUse factoryToUse = RiveFactoryToUse.rive; + + static rive.Factory get getCurrentFactory => switch (factoryToUse) { + RiveFactoryToUse.rive => rive.Factory.rive, + RiveFactoryToUse.flutter => rive.Factory.flutter, + }; + @override State createState() => _RiveExampleAppState(); } class _RiveExampleAppState extends State { - // Examples - final _pages = [ - const _Page('Simple Animation - Asset', SimpleAssetAnimation()), - const _Page('Simple Animation - Network', SimpleNetworkAnimation()), - const _Page('Play/Pause Animation', PlayPauseAnimation()), - const _Page('Play One-Shot Animation', PlayOneShotAnimation()), - const _Page('Button State Machine', ExampleStateMachine()), - const _Page('Skills Machine', StateMachineSkills()), - const _Page('Little Machine', LittleMachine()), - const _Page('Nested Inputs', ArtboardNestedInputs()), - const _Page('Liquid Download', LiquidDownload()), - const _Page('Custom Controller - Speed', SpeedyAnimation()), - const _Page('Simple State Machine', SimpleStateMachine()), - const _Page('State Machine with Listener', StateMachineListener()), - const _Page('Skinning Demo', SkinningDemo()), - const _Page('Animation Carousel', AnimationCarousel()), - const _Page('Basic Text', BasicText()), - const _Page('Asset Loading', CustomAssetLoading()), - const _Page('Cached Asset Loading', CustomCachedAssetLoading()), - const _Page('Event Open URL Button', EventOpenUrlButton()), - const _Page('Event Star Rating', EventStarRating()), - const _Page('Rive Audio', RiveAudioExample()), - const _Page('Rive Audio [Out-of-Band]', RiveAudioOutOfBandExample()), + // ScrollController for the CustomScrollView + final ScrollController _scrollController = ScrollController(); + + // Examples organized into sections + final _sections = [ + const _Section( + 'Getting Started', + [ + _Page('Rive Widget', ExampleRiveWidget(), + 'Simple example usage of the Rive widget with common parameters.'), + _Page('Rive Widget Builder', ExampleRiveWidgetBuilder(), + 'Example usage of the Rive builder widget with common parameters.'), + ], + ), + const _Section( + 'Rive Features', + [ + _Page('Data Binding', ExampleDataBinding(), + 'Example using Rive data binding at runtime.'), + _Page('Data Binding - Images', ExampleDataBindingImages(), + 'Example using Rive data binding images at runtime.'), + _Page('Data Binding - Lists', Todo(), + 'Example using Rive data binding lists at runtime.'), + _Page('Responsive Layouts', ExampleResponsiveLayouts(), + 'Create responsive Rive graphics that adapt to screen size.'), + _Page('Events', ExampleEvents(), 'Handle Rive events.'), + _Page('Audio', ExampleRiveAudio(), 'Example Rive file with audio.'), + ], + ), + const _Section( + 'Asset Loading', + [ + _Page('Network .riv Asset', ExampleNetworkAsset(), + 'Load and display Rive graphics from network URLs.'), + _Page('Out-of-band Assets', ExampleOutOfBandAssetLoading(), + 'Load Rive files with external assets (images, audio) separately.'), + _Page( + 'Out-of-band Assets - Cached', + ExampleOutOfBandCachedAssetLoading(), + 'Load Rive files with cached external assets for better immediate availability.', + ), + ], + ), + const _Section( + 'Painters [Advanced]', + [ + _Page('State Machine Painter', ExampleStateMachinePainter(), + 'Advanced: Custom painter for state machines.'), + _Page('Single Animation Painter', ExampleSingleAnimationPainter(), + 'Advanced: Custom painter for single animation playback.'), + ], + ), + const _Section( + 'Flutter Concepts/Integration', + [ + // _Page('Flutter Lists', Todo(), + // 'Integrate Rive graphics with Flutter list widgets.'), + _Page('Flutter Hit Test + Cursor Behaviour', ExampleHitTestBehaviour(), + 'Specifying hit test and cursor behaviour.'), + _Page('Flutter Ticker Mode', ExampleTickerMode(), + 'Rive graphics respect Flutter ticker mode.'), + _Page('Flutter Time Dilation', ExampleTimeDilation(), + 'Rive graphics respect Flutter time dilation.'), + // _Page('Flutter Hero Transitions', Todo(), + // 'Create smooth transitions between pages with Rive graphics.'), + // _Page('Flutter State Management', Todo(), + // 'Manage Rive state with Flutter state management.'), + // _Page('Flutter Localization', Todo(), + // 'Localize Rive graphics for different languages.'), + // _Page('Flutter Internationalization', Todo(), + // 'Internationalize Rive graphics with Flutter i18n.'), + ], + ), + const _Section( + 'Legacy Features [Use data binding instead]', + [ + _Page('Inputs [Nested]', ExampleInputs(), + 'Legacy: Handle input [nested] controls in Rive graphics.'), + _Page('Text Runs [Nested]', ExampleTextRuns(), + 'Legacy: Handle text runs [nested] components in Rive graphics.'), + ], + ), ]; + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Rive Examples')), - body: Center( - child: ListView.separated( - shrinkWrap: true, - itemBuilder: (context, index) => _NavButton(page: _pages[index]), - separatorBuilder: (context, index) => const SizedBox(height: 16), - itemCount: _pages.length, + body: Column(children: [ + Expanded( + child: Scrollbar( + controller: _scrollController, + child: CustomScrollView( + controller: _scrollController, + slivers: [ + SliverPadding( + padding: const EdgeInsets.all(8.0), + sliver: SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { + // Calculate which section and item we're at + int itemIndex = index; + + for (int i = 0; i < _sections.length; i++) { + if (itemIndex == 0) { + // This is a section header + return _SectionHeader(_sections[i].title); + } + itemIndex--; + + if (itemIndex < _sections[i].pages.length) { + // This is a page within the current section + return Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: _NavButton( + page: _sections[i].pages[itemIndex]), + ); + } + itemIndex -= _sections[i].pages.length; + } + + return null; + }, + childCount: _getTotalItemCount(), + ), + ), + ), + ], + ), + ), ), - ), + const SizedBox(height: 16), + ColoredBox( + color: Colors.black, + child: Column( + children: [ + const SizedBox(height: 16), + const Text('Factory to use:', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + Radio( + value: RiveFactoryToUse.rive, + groupValue: RiveExampleApp.factoryToUse, + onChanged: (value) { + setState(() { + RiveExampleApp.factoryToUse = + value as RiveFactoryToUse; + }); + }, + ), + const Text('Rive Renderer', + style: TextStyle(fontSize: 14)), + ], + ), + const SizedBox(width: 32), + Row( + children: [ + Radio( + value: RiveFactoryToUse.flutter, + groupValue: RiveExampleApp.factoryToUse, + onChanged: (value) { + setState(() { + RiveExampleApp.factoryToUse = + value as RiveFactoryToUse; + }); + }, + ), + const Text('Flutter Renderer', + style: TextStyle(fontSize: 14)), + ], + ), + ], + ), + ), + ], + ), + ), + ]), ); } + + int _getTotalItemCount() { + int count = 0; + for (final section in _sections) { + count += 1; // Section header + count += section.pages.length; // Pages in section + } + return count; + } +} + +/// Class used to organize demo sections. +class _Section { + final String title; + final List<_Page> pages; + + const _Section(this.title, this.pages); } /// Class used to organize demo pages. class _Page { final String name; final Widget page; + final String description; - const _Page(this.name, this.page); + const _Page(this.name, this.page, this.description); } -/// Button to navigate to demo pages. -class _NavButton extends StatelessWidget { +/// Section header widget with divider. +class _SectionHeader extends StatelessWidget { + const _SectionHeader(this.title); + + final String title; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Text( + title, + style: Theme.of(context).textTheme.labelLarge?.copyWith( + color: _primaryColor, + ), + ), + ), + const Divider( + color: _primaryColor, + thickness: 0.5, + height: 1, + ), + const SizedBox(height: 16), + ], + ); + } +} + +/// Button to navigate to demo pages with hover overlay. +class _NavButton extends StatefulWidget { const _NavButton({required this.page}); final _Page page; @override - Widget build(BuildContext context) { - return Center( - child: ElevatedButton( - child: SizedBox( - width: 250, - child: Center( + State<_NavButton> createState() => _NavButtonState(); +} + +class _NavButtonState extends State<_NavButton> { + bool _isHovered = false; + OverlayEntry? _overlayEntry; + + @override + void dispose() { + _removeOverlay(); + super.dispose(); + } + + void _removeOverlay() { + _overlayEntry?.remove(); + _overlayEntry = null; + } + + void _showOverlay() { + _removeOverlay(); + + final RenderBox renderBox = context.findRenderObject() as RenderBox; + final position = renderBox.localToGlobal(Offset.zero); + final size = renderBox.size; + + _overlayEntry = OverlayEntry( + builder: (context) => Positioned( + top: position.dy - 80, // Position above the button + left: position.dx + (size.width / 2) - 150, // Center horizontally + child: Material( + color: Colors.transparent, + child: Container( + width: 300, + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.9), + borderRadius: BorderRadius.circular(8), + border: Border.all(color: _primaryColor, width: 1), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 8, + offset: const Offset(0, 4), + ), + ], + ), child: Text( - page.name, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + widget.page.description, + style: const TextStyle( + color: Colors.white, + fontSize: 12, + height: 1.4, + ), + textAlign: TextAlign.center, ), ), ), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => page.page, - ), - ); - }, ), ); + + Overlay.of(context).insert(_overlayEntry!); + } + + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) { + setState(() => _isHovered = true); + _showOverlay(); + }, + onExit: (_) { + setState(() => _isHovered = false); + _removeOverlay(); + }, + child: Center( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: _isHovered ? _primaryColor.withOpacity(0.1) : null, + elevation: _isHovered ? 8 : 2, + ), + child: SizedBox( + width: 300, + child: Center( + child: Text( + widget.page.name, + style: Theme.of(context).textTheme.labelLarge, + ), + ), + ), + onPressed: () { + _removeOverlay(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => _WrappedPage(page: widget.page), + ), + ); + }, + ), + ), + ); + } +} + +/// Scaffold wrapper for the page. +class _WrappedPage extends StatelessWidget { + const _WrappedPage({required this.page}); + + final _Page page; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(page.name)), + body: page.page, + ); } } diff --git a/example/lib/play_one_shot_animation.dart b/example/lib/play_one_shot_animation.dart deleted file mode 100644 index 1faf875..0000000 --- a/example/lib/play_one_shot_animation.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// Demonstrates playing a one-shot animation on demand -class PlayOneShotAnimation extends StatefulWidget { - const PlayOneShotAnimation({Key? key}) : super(key: key); - - @override - State createState() => _PlayOneShotAnimationState(); -} - -class _PlayOneShotAnimationState extends State { - /// Controller for playback - late RiveAnimationController _controller; - - /// Is the animation currently playing? - bool _isPlaying = false; - - @override - void initState() { - super.initState(); - _controller = OneShotAnimation( - 'bounce', - autoplay: false, - onStop: () => setState(() => _isPlaying = false), - onStart: () => setState(() => _isPlaying = true), - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('One-Shot Example'), - ), - body: Center( - child: RiveAnimation.asset( - 'assets/vehicles.riv', - animations: const ['idle', 'curves'], - fit: BoxFit.cover, - controllers: [_controller], - ), - ), - floatingActionButton: FloatingActionButton( - // disable the button while playing the animation - onPressed: () => _isPlaying ? null : _controller.isActive = true, - tooltip: 'Bounce', - child: const Icon(Icons.arrow_upward), - ), - ); - } -} diff --git a/example/lib/play_pause_animation.dart b/example/lib/play_pause_animation.dart deleted file mode 100644 index 7334c3b..0000000 --- a/example/lib/play_pause_animation.dart +++ /dev/null @@ -1,54 +0,0 @@ -/// Demonstrates how to play and pause a looping animation - -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -class PlayPauseAnimation extends StatefulWidget { - const PlayPauseAnimation({Key? key}) : super(key: key); - - @override - State createState() => _PlayPauseAnimationState(); -} - -class _PlayPauseAnimationState extends State { - Artboard? _artboard; - - bool get isPlaying => _artboard?.isPlaying ?? true; - - /// Toggles between play and pause on the artboard - void _togglePlay() { - if (isPlaying) { - _artboard?.pause(); - } else { - _artboard?.play(); - } - - // We call set state to update the Play/Pause Icon. This isn't needed - // to update Rive. - setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Animation Example'), - ), - body: RiveAnimation.asset( - 'assets/off_road_car.riv', - animations: const ["idle"], - fit: BoxFit.cover, - onInit: (artboard) { - _artboard = artboard; - }, - ), - floatingActionButton: FloatingActionButton( - onPressed: _togglePlay, - tooltip: isPlaying ? 'Pause' : 'Play', - child: Icon( - isPlaying ? Icons.pause : Icons.play_arrow, - ), - ), - ); - } -} diff --git a/example/lib/rive_audio.dart b/example/lib/rive_audio.dart deleted file mode 100644 index b59e5e8..0000000 --- a/example/lib/rive_audio.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -class RiveAudioExample extends StatelessWidget { - const RiveAudioExample({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Rive Audio'), - ), - body: const RiveAnimation.asset( - "assets/lip-sync.riv", - artboard: 'Lip_sync_2', - stateMachines: ['State Machine 1'], - ), - ); - } -} diff --git a/example/lib/rive_audio_out_of_band.dart b/example/lib/rive_audio_out_of_band.dart deleted file mode 100644 index 388fc1b..0000000 --- a/example/lib/rive_audio_out_of_band.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -class RiveAudioOutOfBandExample extends StatefulWidget { - const RiveAudioOutOfBandExample({super.key}); - - @override - State createState() => - _RiveAudioOutOfBandExampleState(); -} - -class _RiveAudioOutOfBandExampleState extends State { - @override - void initState() { - super.initState(); - _loadRiveFile(); - } - - RiveFile? _riveAudioAssetFile; - - Future _loadRiveFile() async { - final riveFile = await RiveFile.asset( - 'assets/ping_pong_audio_demo.riv', - assetLoader: LocalAssetLoader(audioPath: 'assets/audio'), - ); - setState(() { - _riveAudioAssetFile = riveFile; - }); - } - - @override - Widget build(BuildContext context) { - if (_riveAudioAssetFile == null) { - return const Center(child: CircularProgressIndicator()); - } - - return Scaffold( - appBar: AppBar( - title: const Text('Rive Audio [Out-of-Band]'), - ), - body: RiveAnimation.direct( - _riveAudioAssetFile!, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, - ), - ); - } -} diff --git a/example/lib/simple_animation.dart b/example/lib/simple_animation.dart deleted file mode 100644 index 930098b..0000000 --- a/example/lib/simple_animation.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// Basic example playing a Rive animation from a packaged asset. -class SimpleAssetAnimation extends StatelessWidget { - const SimpleAssetAnimation({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Simple Animation'), - ), - body: const Center( - child: RiveAnimation.asset( - 'assets/off_road_car.riv', - fit: BoxFit.cover, - ), - ), - ); - } -} diff --git a/example/lib/simple_animation_network.dart b/example/lib/simple_animation_network.dart deleted file mode 100644 index 58d498b..0000000 --- a/example/lib/simple_animation_network.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// Basic example playing a Rive animation from a network asset. -class SimpleNetworkAnimation extends StatelessWidget { - const SimpleNetworkAnimation({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Simple Animation'), - ), - body: const Center( - child: RiveAnimation.network( - 'https://cdn.rive.app/animations/vehicles.riv', - fit: BoxFit.cover, - placeHolder: Center(child: CircularProgressIndicator()), - ), - ), - ); - } -} diff --git a/example/lib/simple_machine_listener.dart b/example/lib/simple_machine_listener.dart deleted file mode 100644 index 937ebd1..0000000 --- a/example/lib/simple_machine_listener.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -class StateMachineListener extends StatefulWidget { - const StateMachineListener({Key? key}) : super(key: key); - - @override - State createState() => _StateMachineListenerState(); -} - -class _StateMachineListenerState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Light Switch'), - ), - body: const Center( - child: RiveAnimation.asset( - 'assets/light_switch.riv', - fit: BoxFit.contain, - stateMachines: ['Switch'], - ), - ), - ); - } -} diff --git a/example/lib/simple_state_machine.dart b/example/lib/simple_state_machine.dart deleted file mode 100644 index 87b8dd6..0000000 --- a/example/lib/simple_state_machine.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example demonstrating a simple state machine. -/// -/// The "bumpy" state machine will be activated on tap of the vehicle. -class SimpleStateMachine extends StatefulWidget { - const SimpleStateMachine({Key? key}) : super(key: key); - - @override - State createState() => _SimpleStateMachineState(); -} - -class _SimpleStateMachineState extends State { - SMITrigger? _bump; - - void _onRiveInit(Artboard artboard) { - final controller = StateMachineController.fromArtboard(artboard, 'bumpy'); - artboard.addController(controller!); - _bump = controller.getTriggerInput('bump'); - } - - void _hitBump() => _bump?.fire(); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Simple State Machine'), - ), - body: Stack( - children: [ - Center( - child: GestureDetector( - onTap: _hitBump, - child: RiveAnimation.asset( - 'assets/vehicles.riv', - fit: BoxFit.cover, - onInit: _onRiveInit, - ), - ), - ), - const Align( - alignment: Alignment.topCenter, - child: Padding( - padding: EdgeInsets.all(16.0), - child: Text( - 'Bump the van!', - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ), - ), - ], - ), - ); - } -} diff --git a/example/lib/skinning_demo.dart b/example/lib/skinning_demo.dart deleted file mode 100644 index 4ac4f33..0000000 --- a/example/lib/skinning_demo.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// Basic skinning example. The skinning states is set in the Rive editor and -/// triggers are used to change the value. -class SkinningDemo extends StatefulWidget { - const SkinningDemo({Key? key}) : super(key: key); - - @override - State createState() => _SkinningDemoState(); -} - -class _SkinningDemoState extends State { - static const _skinMapping = { - "Skin_0": "Plain", - "Skin_1": "Summer", - "Skin_2": "Elvis", - "Skin_3": "Superhero", - "Skin_4": "Astronaut" - }; - - String _currentState = 'Plain'; - - SMITrigger? _skin; - - void _onRiveInit(Artboard artboard) { - final controller = StateMachineController.fromArtboard( - artboard, - 'Motion', - onStateChange: _onStateChange, - ); - - artboard.addController(controller!); - _skin = controller.getTriggerInput('Skin'); - } - - void _onStateChange(String stateMachineName, String stateName) { - if (stateName.contains("Skin_")) { - setState(() { - _currentState = _skinMapping[stateName] ?? 'Plain'; - }); - } - } - - void _swapSkin() { - _skin?.fire(); - } - - @override - Widget build(BuildContext context) { - const textColor = Color(0xFFefcb7d); - - return Scaffold( - appBar: AppBar( - title: const Text('Skinning Demo'), - ), - body: Stack( - children: [ - Center( - child: RiveAnimation.asset( - 'assets/skins_demo.riv', - fit: BoxFit.cover, - onInit: _onRiveInit, - ), - ), - Align( - alignment: Alignment.topCenter, - child: Column( - children: [ - const Padding( - padding: EdgeInsets.all(24.0), - child: Text( - 'Choose an Avatar', - style: TextStyle( - fontSize: 48, - fontWeight: FontWeight.bold, - color: textColor, - ), - ), - ), - FilledButton( - onPressed: _swapSkin, - style: const ButtonStyle( - backgroundColor: WidgetStatePropertyAll(Color(0xFF7d99ef)), - ), - child: const Text('Swap Skin'), - ), - const Spacer(), - Text( - 'Skin: $_currentState', - style: const TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: textColor, - ), - ), - const SizedBox(height: 48) - ], - ), - ) - ], - ), - ); - } -} diff --git a/example/lib/state_machine_skills.dart b/example/lib/state_machine_skills.dart deleted file mode 100644 index 5abbeb4..0000000 --- a/example/lib/state_machine_skills.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/rive.dart'; - -/// An example showing how to drive a StateMachine via one numeric input. -class StateMachineSkills extends StatefulWidget { - const StateMachineSkills({Key? key}) : super(key: key); - - @override - State createState() => _StateMachineSkillsState(); -} - -class _StateMachineSkillsState extends State { - Artboard? _riveArtboard; - SMINumber? _levelInput; - - @override - void initState() { - super.initState(); - - _loadRiveFile(); - } - - Future _loadRiveFile() async { - final file = await RiveFile.asset('assets/skills.riv'); - - // The artboard is the root of the animation and gets drawn in the - // Rive widget. - final artboard = file.mainArtboard.instance(); - var controller = - StateMachineController.fromArtboard(artboard, 'Designer\'s Test'); - if (controller != null) { - artboard.addController(controller); - _levelInput = controller.getNumberInput('Level'); - } - setState(() => _riveArtboard = artboard); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Skills Machine'), - ), - body: Center( - child: _riveArtboard == null - ? const SizedBox() - : Stack( - children: [ - Positioned.fill( - child: Rive( - artboard: _riveArtboard!, - fit: BoxFit.cover, - ), - ), - Positioned.fill( - bottom: 32, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - ElevatedButton( - child: const Text('Beginner'), - onPressed: () => _levelInput?.value = 0, - ), - const SizedBox(width: 10), - ElevatedButton( - child: const Text('Intermediate'), - onPressed: () => _levelInput?.value = 1, - ), - const SizedBox(width: 10), - ElevatedButton( - child: const Text('Expert'), - onPressed: () => _levelInput?.value = 2, - ), - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock new file mode 100644 index 0000000..93fd49a --- /dev/null +++ b/example/macos/Podfile.lock @@ -0,0 +1,28 @@ +PODS: + - FlutterMacOS (1.0.0) + - rive_native (0.0.1): + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - rive_native (from `Flutter/ephemeral/.symlinks/plugins/rive_native/macos`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + rive_native: + :path: Flutter/ephemeral/.symlinks/plugins/rive_native/macos + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + rive_native: 9930efc341917c512f451cfe1522d8addf54d569 + url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 + +PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 + +COCOAPODS: 1.16.2 diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 15368ec..ac78810 100644 --- a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/example/macos/Runner/AppDelegate.swift b/example/macos/Runner/AppDelegate.swift index 8e02df2..b3c1761 100644 --- a/example/macos/Runner/AppDelegate.swift +++ b/example/macos/Runner/AppDelegate.swift @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements index dddb8a3..f233e7e 100644 --- a/example/macos/Runner/DebugProfile.entitlements +++ b/example/macos/Runner/DebugProfile.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.server + com.apple.security.network.client + diff --git a/example/macos/Runner/Release.entitlements b/example/macos/Runner/Release.entitlements index 852fa1a..90852b5 100644 --- a/example/macos/Runner/Release.entitlements +++ b/example/macos/Runner/Release.entitlements @@ -4,5 +4,7 @@ com.apple.security.app-sandbox + com.apple.security.network.client + diff --git a/example/pubspec.yaml b/example/pubspec.yaml index d0c54e9..04bd4e4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.17.0 <4.0.0" + sdk: ">=3.5.0 <4.0.0" dependencies: flutter: @@ -24,7 +24,13 @@ dev_dependencies: flutter: uses-material-design: true + fonts: + - family: JetBrainsMono + fonts: + - asset: assets/fonts/JetBrains Mono.ttf + assets: - assets/ - assets/fonts/ - assets/audio/ + - assets/images/ diff --git a/lib/components.dart b/lib/components.dart deleted file mode 100644 index 16162f9..0000000 --- a/lib/components.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'package:rive/src/rive_core/node.dart'; -export 'package:rive/src/rive_core/transform_component.dart'; -export 'package:rive/src/rive_core/world_transform_component.dart'; diff --git a/lib/math.dart b/lib/math.dart deleted file mode 100644 index c2f0a40..0000000 --- a/lib/math.dart +++ /dev/null @@ -1 +0,0 @@ -export 'package:rive_common/math.dart'; diff --git a/lib/rive.dart b/lib/rive.dart index a287b92..acfb84d 100644 --- a/lib/rive.dart +++ b/lib/rive.dart @@ -1,51 +1,25 @@ -library rive; +export 'package:rive_native/rive_native.dart' + hide + InternalViewModelInstanceBoolean, + InternalViewModelInstanceEnum, + InternalViewModelInstanceTrigger, + InternalViewModelInstanceSymbolListIndex, + InternalViewModelInstanceNumber, + InternalViewModelInstanceValue, + InternalDataContext, + InternalViewModelInstanceColor, + InternalViewModelInstanceList, + InternalViewModelInstanceString, + InternalViewModelInstance, + InternalViewModelInstanceViewModel, + InternalDataBind; -export 'package:rive/src/asset.dart'; -export 'package:rive/src/asset_loader.dart'; -export 'package:rive/src/controllers/linear_animation_controller.dart'; -export 'package:rive/src/controllers/one_shot_controller.dart'; -export 'package:rive/src/controllers/simple_controller.dart'; -export 'package:rive/src/controllers/state_machine_controller.dart'; -export 'package:rive/src/extensions.dart'; -export 'package:rive/src/rive.dart'; -export 'package:rive/src/rive_core/animation/linear_animation.dart'; -export 'package:rive/src/rive_core/animation/loop.dart'; -export 'package:rive/src/rive_core/animation/state_machine.dart'; -export 'package:rive/src/rive_core/artboard.dart'; -export 'package:rive/src/rive_core/assets/audio_asset.dart'; -export 'package:rive/src/rive_core/assets/font_asset.dart'; -export 'package:rive/src/rive_core/assets/image_asset.dart'; -export 'package:rive/src/rive_core/data_bind/data_bind.dart'; -export 'package:rive/src/rive_core/data_bind/data_bind_context.dart'; -export 'package:rive/src/rive_core/data_bind/data_context.dart'; -export 'package:rive/src/rive_core/event.dart'; -export 'package:rive/src/rive_core/nested_artboard.dart'; -export 'package:rive/src/rive_core/open_url_target.dart'; -export 'package:rive/src/rive_core/rive_animation_controller.dart'; -export 'package:rive/src/rive_core/runtime/exceptions/rive_format_error_exception.dart'; -export 'package:rive/src/rive_core/runtime/runtime_header.dart' - show riveVersion; -export 'package:rive/src/rive_core/shapes/image.dart'; -export 'package:rive/src/rive_core/shapes/paint/fill.dart'; -export 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart'; -export 'package:rive/src/rive_core/shapes/paint/radial_gradient.dart'; -export 'package:rive/src/rive_core/shapes/paint/solid_color.dart'; -export 'package:rive/src/rive_core/shapes/paint/stroke.dart'; -export 'package:rive/src/rive_core/shapes/shape.dart'; -export 'package:rive/src/rive_core/text/text_value_run.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance_color.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance_number.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance_string.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; -export 'package:rive/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart'; -export 'package:rive/src/rive_file.dart'; -export 'package:rive/src/rive_scene.dart'; -export 'package:rive/src/runtime_artboard.dart'; -export 'package:rive/src/runtime_event.dart'; -export 'package:rive/src/runtime_mounted_artboard.dart'; -export 'package:rive/src/runtime_nested_artboard.dart'; -export 'package:rive/src/widgets/rive_animation.dart'; -export 'src/dynamic_library_helper/dynamic_library_helper_stub.dart' - if (dart.library.js_interop) 'src/dynamic_library_helper/dynamic_library_helper_web.dart' - if (dart.library.ffi) 'src/dynamic_library_helper/dynamic_library_helper_ffi.dart'; +export 'src/errors.dart'; +export 'src/file_loader.dart'; +export 'src/models/artboard_selector.dart'; +export 'src/models/data_bind.dart'; +export 'src/models/state_machine_selector.dart'; +export 'src/painters/widget_controller.dart'; +export 'src/rive_extensions.dart'; +export 'src/widgets/rive_builder.dart'; +export 'src/widgets/rive_widget.dart'; diff --git a/lib/rive_web.dart b/lib/rive_web.dart deleted file mode 100644 index 187c2e5..0000000 --- a/lib/rive_web.dart +++ /dev/null @@ -1,16 +0,0 @@ -// In order to *not* need this ignore, consider extracting the "web" version -// of your plugin as a separate package, instead of inlining it in the same -// package as the core of your plugin. -// ignore: avoid_web_libraries_in_flutter - -// ignore_for_file: avoid_classes_with_only_static_members - -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -/// A web implementation of the RivePlatform of the Rive plugin. -class RivePlugin { - /// Constructs a RiveWeb - RivePlugin(); - - static void registerWith(Registrar registrar) {} -} diff --git a/lib/src/animation_list.dart b/lib/src/animation_list.dart deleted file mode 100644 index ef0d250..0000000 --- a/lib/src/animation_list.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/animation/animation.dart'; - -class AnimationList extends ListBase { - // Lame way to do this due to how ListBase needs to expand a nullable list. - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - Animation operator [](int index) => _values[index]!; - - @override - void operator []=(int index, Animation value) => _values[index] = value; -} diff --git a/lib/src/asset.dart b/lib/src/asset.dart deleted file mode 100644 index 2b8a81e..0000000 --- a/lib/src/asset.dart +++ /dev/null @@ -1,75 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -import 'package:rive/src/rive_core/assets/file_asset.dart'; - -export 'package:rive/src/generated/artboard_base.dart'; - -const _deprecationExtensionMessage = - '''This Extension is no longer maintained. Similar behaviour can -be re-created with a custom extension. - -Example: https://gist.github.com/HayesGordon/5d37d3fb26f54b2c231760c2c8685963 - -'''; - -const _deprecationEnumMessage = - '''This Enum is no longer maintained. Similar behaviour can -be re-created with a custom Enum. - -Example: https://gist.github.com/HayesGordon/5d37d3fb26f54b2c231760c2c8685963 - -'''; - -@Deprecated(_deprecationExtensionMessage) -extension FileAssetExtension on FileAsset { - @Deprecated(_deprecationExtensionMessage) - Extension get extension => _getExtension(fileExtension); - @Deprecated(_deprecationExtensionMessage) - Type get type => _getType(fileExtension); -} - -Extension _getExtension(String ext) { - switch (ext) { - case 'png': - return Extension.png; - case 'jpeg': - return Extension.jpeg; - case 'webp': - return Extension.webp; - case 'otf': - return Extension.otf; - case 'ttf': - return Extension.ttf; - } - return Extension.unknown; -} - -Type _getType(String ext) { - switch (ext) { - case 'png': - case 'jpeg': - case 'webp': - return Type.image; - case 'otf': - case 'ttf': - return Type.font; - } - return Type.unknown; -} - -@Deprecated(_deprecationEnumMessage) -enum Extension { - otf, - ttf, - jpeg, - png, - webp, - unknown, -} - -@Deprecated(_deprecationEnumMessage) -enum Type { - font, - image, - unknown, -} diff --git a/lib/src/asset_list.dart b/lib/src/asset_list.dart deleted file mode 100644 index 0624c67..0000000 --- a/lib/src/asset_list.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/assets/asset.dart'; - -// List of assets used by the backboard. -class AssetList extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - Asset operator [](int index) => _values[index]!; - - @override - void operator []=(int index, Asset value) => _values[index] = value; -} diff --git a/lib/src/asset_loader.dart b/lib/src/asset_loader.dart deleted file mode 100644 index bcaad61..0000000 --- a/lib/src/asset_loader.dart +++ /dev/null @@ -1,212 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:http/http.dart' as http; -import 'package:rive/rive.dart'; -import 'package:rive/src/debug.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/utilities/utilities.dart'; - -/// Base class for resolving out of band Rive assets, such as images and fonts. -/// -/// See [CallbackAssetLoader] and [LocalAssetLoader] for an example of how to -/// use this. -// ignore: one_member_abstracts -abstract class FileAssetLoader { - Future load(FileAsset asset, Uint8List? embeddedBytes); -} - -/// Loads assets from Rive's CDN. -/// -/// This is used internally by Rive to load assets from the CDN. It is not -/// intended to be used by end users. Instead extend [FileAssetLoader] for -/// custom asset loading, or use [CallbackAssetLoader]. -class CDNAssetLoader extends FileAssetLoader { - CDNAssetLoader(); - - @override - Future load(FileAsset asset, Uint8List? embeddedBytes) async { - // if the asset is embedded, or does not have a cdn uuid, do not attempt - // to load it - if (embeddedBytes != null || asset.cdnUuid.isEmpty) { - return false; - } - // TODO (Max): Do we have a URL builder? - // TODO (Max): We should aim to get loading errors exposed where - // possible, this includes failed network requests but also - // failed asset.decode - - var url = asset.cdnBaseUrl; - - if (!url.endsWith('/')) { - url += '/'; - } - url += formatUuid( - uuidVariant2(asset.cdnUuid), - ); - - final res = await http.get(Uri.parse(url)); - - if ((res.statusCode / 100).floor() == 2) { - try { - await asset.decode( - Uint8List.view(res.bodyBytes.buffer), - ); - } on Exception catch (e) { - printDebugMessage( - '''Unable to parse response ${asset.runtimeType}. - - Url: $url - - Exception: $e''', - ); - return false; - } - - return true; - } else { - return false; - } - } -} - -/// Convenience class for loading assets from the local file system. -/// -/// Specify the [fontPath], [imagePath], and [audioPath] to load assets from the -/// asset bundle for a specific asset type. Or use [path] as a general -/// fallback instead. [path] will only be used for an asset type if the -/// corresponding asset path is null. -/// -/// For example, to provide an audio asset path: -/// ```dart -/// final riveFile = await RiveFile.asset( -/// 'assets/ping_pong_audio_demo.riv', -/// assetLoader: LocalAssetLoader( -/// audioPath: 'assets/some/path', -/// // path: 'assets/some/path', // or provide fallback/general -/// ), -/// ); -/// ``` -/// -/// Be sure to provide the correct path where the file is located. -/// -/// If more control is desired, extend [FileAssetLoader] and override [load]. -class LocalAssetLoader extends FileAssetLoader { - final String? audioPath; - final String? fontPath; - final String? imagePath; - final String? path; - final AssetBundle _assetBundle; - - LocalAssetLoader({ - this.audioPath, - this.fontPath, - this.imagePath, - this.path, - AssetBundle? assetBundle, - }) : _assetBundle = assetBundle ?? rootBundle; - - @override - Future load(FileAsset asset, Uint8List? embeddedBytes) async { - // do not load embedded assets. - if (embeddedBytes != null) { - return false; - } - String? assetPath; - - String filePath; - - switch (asset.runtimeType) { - case AudioAsset: - assert(audioPath != null || path != null, - '''Audio asset not found. Be sure to provide either `audioPath` or `path` in `LocalAssetLoader`.'''); - if (audioPath == null && path == null) return false; - filePath = audioPath ?? path!; - break; - case FontAsset: - assert(fontPath != null || path != null, - '''Font asset not found. Be sure to provide either `fontPath` or `path` in `LocalAssetLoader`.'''); - if (fontPath == null && path == null) return false; - filePath = fontPath ?? path!; - break; - case ImageAsset: - assert(imagePath != null || path != null, - '''Image asset not found. Be sure to provide either `imagePath` or `path` in `LocalAssetLoader`.'''); - if (imagePath == null && path == null) return false; - filePath = imagePath ?? path!; - break; - default: - return false; - } - - filePath = filePath.endsWith("/") ? filePath : "$filePath/"; - - assetPath = filePath + asset.uniqueFilename; - final bytes = await _assetBundle.load(assetPath); - await asset.decode(Uint8List.view(bytes.buffer)); - return true; - } -} - -/// Convenience class that extends [FileAssetLoader] and allows you to -/// register a callback for loading Rive assets. -/// -/// The callback will be called for each asset that needs to be loaded manually. -/// See [RiveFile] for additional options. Which assets are embedded are defined -/// within the Rive editor. -/// -/// This callback will be triggered for any **referenced** assets. -/// -/// -/// Set [loadCdnAssets] to false to disable loading -/// assets from the Rive CDN. -/// -/// ### Example usage: -/// Loading from assets. Here only assets marked as **referenced** will trigger -/// the callback. -/// ```dart -/// final riveFile = await RiveFile.asset( -/// 'assets/asset.riv', -/// loadCdnAssets: true, -/// assetLoader: CallbackAssetLoader( -/// (asset, bytes) async { -/// final res = -/// await http.get(Uri.parse('https://picsum.photos/1000/1000')); -/// await asset.decode(Uint8List.view(res.bodyBytes.buffer)); -/// return true; -/// }, -/// ), -/// ); -/// ``` -class CallbackAssetLoader extends FileAssetLoader { - Future Function(FileAsset asset, Uint8List? embeddedBytes) callback; - - CallbackAssetLoader(this.callback); - - @override - Future load(FileAsset asset, Uint8List? embeddedBytes) async { - return callback(asset, embeddedBytes); - } -} - -/// Convenience class that extends [FileAssetLoader] and allows you to -/// register fallbacks for loading Rive assets, such as images and fonts. -/// -/// For example, you can use this to load assets from the CDN, and if that -/// fails, load them from the asset bundle. -/// -/// Alternatively, extend [FileAssetLoader] and override [load] for more -/// custom control in how assets are resolved. -class FallbackAssetLoader extends FileAssetLoader { - final List fileAssetLoaders; - - FallbackAssetLoader(this.fileAssetLoaders); - - @override - Future load(FileAsset asset, Uint8List? embeddedBytes) async { - for (var i = 0; i < fileAssetLoaders.length; i++) { - final resolver = fileAssetLoaders[i]; - final success = await resolver.load(asset, embeddedBytes); - if (success) { - return true; - } - } - return false; - } -} diff --git a/lib/src/blend_animations.dart b/lib/src/blend_animations.dart deleted file mode 100644 index 8566e82..0000000 --- a/lib/src/blend_animations.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/animation/blend_animation.dart'; - -class BlendAnimations extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - T operator [](int index) => _values[index]!; - - @override - void operator []=(int index, T value) => _values[index] = value; -} diff --git a/lib/src/container_children.dart b/lib/src/container_children.dart deleted file mode 100644 index 7287fd5..0000000 --- a/lib/src/container_children.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/component.dart'; - -// TODO: figure out how to make this cleaner. -class ContainerChildren extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - Component operator [](int index) => _values[index]!; - - @override - void operator []=(int index, Component value) => _values[index] = value; -} diff --git a/lib/src/controllers/linear_animation_controller.dart b/lib/src/controllers/linear_animation_controller.dart deleted file mode 100644 index f4c5f99..0000000 --- a/lib/src/controllers/linear_animation_controller.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart' - as core; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/runtime_mounted_artboard.dart'; -export 'package:rive/src/runtime_mounted_artboard.dart'; - -/// An AnimationController which controls a StateMachine and provides access to -/// the inputs of the StateMachine. -class LinearAnimationInstance extends core.LinearAnimationInstance - with RuntimeEventReporter, KeyedCallbackReporter { - final _runtimeEventListeners = {}; - late CoreContext? context; - - LinearAnimationInstance(animation, - {double speedMultiplier = 1.0, this.context}) - : super(animation, speedMultiplier: speedMultiplier); - - @override - void addRuntimeEventListener(OnRuntimeEvent callback) => - _runtimeEventListeners.add(callback); - - @override - void removeRuntimeEventListener(OnRuntimeEvent callback) => - _runtimeEventListeners.remove(callback); - - @override - void reportEvent(Event event) { - _runtimeEventListeners.toList().forEach((callback) { - callback(event); - }); - } - - @override - void reportKeyedCallback( - int objectId, int propertyKey, double elapsedSeconds) { - var coreObject = context?.resolve(objectId); - if (coreObject != null) { - RiveCoreContext.setCallback( - coreObject, - propertyKey, - CallbackData(this, delay: elapsedSeconds), - ); - } - } -} diff --git a/lib/src/controllers/one_shot_controller.dart b/lib/src/controllers/one_shot_controller.dart deleted file mode 100644 index 02a7cb8..0000000 --- a/lib/src/controllers/one_shot_controller.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:rive/src/controllers/simple_controller.dart'; - -/// This allows a value of type T or T? -/// to be treated as a value of type T?. -/// -/// We use this so that APIs that have become -/// non-nullable can still be used with `!` and `?` -/// to support older versions of the API as well. -T? _ambiguate(T? value) => value; - -/// Controller tailored for managing one-shot animations -class OneShotAnimation extends SimpleAnimation { - /// Fires when the animation stops being active - final VoidCallback? onStop; - - /// Fires when the animation starts being active - final VoidCallback? onStart; - - OneShotAnimation( - String animationName, { - double mix = 1, - bool autoplay = true, - this.onStop, - this.onStart, - }) : super(animationName, mix: mix, autoplay: autoplay) { - isActiveChanged.addListener(onActiveChanged); - } - - /// Dispose of any callback listeners - @override - void dispose() { - isActiveChanged.removeListener(onActiveChanged); - super.dispose(); - } - - /// Perform tasks when the animation's active state changes - void onActiveChanged() { - // If the animation stops and it is at the end of the one-shot, reset the - // animation back to the starting time - if (!isActive) { - reset(); - } - // Fire any callbacks - isActive - ? onStart?.call() - // onStop can fire while widgets are still drawing - : _ambiguate(WidgetsBinding.instance) - ?.addPostFrameCallback((_) => onStop?.call()); - } -} diff --git a/lib/src/controllers/simple_controller.dart b/lib/src/controllers/simple_controller.dart deleted file mode 100644 index e7fcc48..0000000 --- a/lib/src/controllers/simple_controller.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:rive/src/extensions.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/rive_animation_controller.dart'; -import 'package:rive/src/runtime_artboard.dart'; - -/// A simple [RiveAnimationController] that plays back a LinearAnimation defined -/// by an artist. All playback parameters (looping, speed, keyframes) are artist -/// defined in the Rive editor. This takes a declaritive approach of using an -/// [animationName] as the only requirement for resolving the animation. When -/// the controller is added to an artboard (note that due to widget lifecycles -/// it could get re-initialized on another artboard later) it'll look for the -/// animation. Not finding the animation is a condition this example deals with -/// by simply nulling the [AnimationInstance] _instance which means it won't be -/// applied during advance cycles. Another approach would be let this throw, but -/// this one is a little more forgiving which can be desireable with files -/// dynamically loaded (downloaded even) at runtime. -class SimpleAnimation extends RiveAnimationController { - LinearAnimationInstance? _instance; - - /// Animation name - final String animationName; - - /// Pauses the animation when it's created - final bool autoplay; - - /// Mix value for the animation, value between 0 and 1 - double _mix; - - // Controls the level of mix for the animation, clamped between 0 and 1 - SimpleAnimation(this.animationName, {double mix = 1, this.autoplay = true}) - : _mix = mix.clamp(0, 1).toDouble(); - LinearAnimationInstance? get instance => _instance; - double get mix => _mix; - - set mix(double value) => _mix = value.clamp(0, 1).toDouble(); - - @override - void apply(RuntimeArtboard artboard, double elapsedSeconds) { - if (_instance == null || !_instance!.keepGoing) { - isActive = false; - } - - // We apply before advancing. So we want to stop rendering only once the - // last advanced frame has been applied. This means knowing when the last - // frame is advanced, ensuring the next apply happens, and then finally - // stopping playback. We do this with keepGoing as this will be true of a - // one-shot has passed its stop time. Fixes #28 and should help with issues - // #51 and #56. - _instance! - ..animation.apply(_instance!.time, coreContext: artboard, mix: mix) - ..advance(elapsedSeconds); - } - - @override - bool init(RuntimeArtboard artboard) { - _instance = artboard.animationByName(animationName); - isActive = autoplay; - return _instance != null; - } - - /// Resets the animation back to it's starting time position - void reset() => _instance?.reset(); -} diff --git a/lib/src/controllers/state_machine_controller.dart b/lib/src/controllers/state_machine_controller.dart deleted file mode 100644 index 1448515..0000000 --- a/lib/src/controllers/state_machine_controller.dart +++ /dev/null @@ -1,231 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_bool.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart' as core; -import 'package:rive/src/rive_core/animation/state_machine_number.dart'; -import 'package:rive/src/rive_core/animation/state_machine_trigger.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart' as core; -import 'package:rive/src/runtime_mounted_artboard.dart'; -export 'package:rive/src/runtime_mounted_artboard.dart'; - -/// [StateMachine]s supports three input types. The StateMachine mostly -/// abstracts types by allowing the programmer to query for an input of a -/// specific Dart backing type, mapping it to the correct StateMachine type. -/// This is the most flexible API to use to check if a type with a given name -/// exists. However, if you need to iterate inputs and query their types, this -/// enum is exposed for convenience. -enum SMIType { number, boolean, trigger } - -/// SMI = StateMachineInstance -/// -/// This is the abstraction of an instanced input -/// from the [StateMachine]. Whenever a [StateMachineController] is created, the -/// list of inputs in the corresponding [StateMachine] is wrapped into a set of -/// [SMIInput] objects that ensure inputs are initialized to design-time values. -/// The implementation can now change these values freely as they are decoupled -/// from the backing [StateMachine] and can safely be re-instanced by another -/// controller later. -abstract class SMIInput { - final core.StateMachineInput _input; - final StateMachineController controller; - final SMIType type; - - SMIInput._(this._input, this.type, this.controller); - - @protected - void advance() {} - - /// The id of the input within the context of the [StateMachine] it belongs - /// to. - int get id => _input.id; - - /// The name given to this input at design time in Rive. - String get name => _input.name; - - /// Convenience method for changing the backing [SMIInput.value] of the input. - /// For [SMITrigger] it's usually preferable to use the [SMITrigger.fire] - /// method to change the input value, but calling change(true) is totally - /// valid. - bool change(T value) { - if (controller.getInputValue(id) == value) { - return false; - } - controller.setInputValue(id, value); - controller.isActive = true; - return true; - } - - T get value => controller.getInputValue(id) as T; - set value(T newValue) => change(newValue); - - bool _is() { - return K == T; - } -} - -/// A boolean StateMachine input instance. Use the [value] property to change -/// the input which will automatically re-activate the [StateMachineController] -/// if necessary. -class SMIBool extends SMIInput { - SMIBool._(StateMachineBool input, StateMachineController controller) - : super._( - input, - SMIType.boolean, - controller, - ) { - controller.setInputValue(id, input.value); - } -} - -/// A numeric StateMachine input instance. Use the [value] property to change -/// the input which will automatically re-activate the [StateMachineController] -/// if necessary. -class SMINumber extends SMIInput { - SMINumber._(StateMachineNumber input, StateMachineController controller) - : super._( - input, - SMIType.number, - controller, - ) { - controller.setInputValue(id, input.value); - } -} - -/// A trigger StateMachine input instance. Use the [fire] method to change the -/// input which will automatically re-activate the [StateMachineController] if -/// necessary. -class SMITrigger extends SMIInput { - SMITrigger._(StateMachineTrigger input, StateMachineController controller) - : super._( - input, - SMIType.trigger, - controller, - ) { - controller.setInputValue(id, false); - } - - void fire() => change(true); - @override - void advance() => change(false); -} - -/// An AnimationController which controls a StateMachine and provides access to -/// the inputs of the StateMachine. -class StateMachineController extends core.StateMachineController - with RuntimeEventReporter { - final List _inputs = []; - - /// A list of inputs available in the StateMachine. - Iterable get inputs => _inputs; - - final _runtimeEventListeners = {}; - - StateMachineController( - StateMachine stateMachine, { - core.OnStateChange? onStateChange, - // ignore: deprecated_member_use_from_same_package - }) : super(stateMachine, onStateChange: onStateChange) { - isActive = true; - for (final input in stateMachine.inputs) { - switch (input.coreType) { - case StateMachineNumberBase.typeKey: - _inputs.add(SMINumber._(input as StateMachineNumber, this)); - break; - case StateMachineBoolBase.typeKey: - _inputs.add(SMIBool._(input as StateMachineBool, this)); - break; - case StateMachineTriggerBase.typeKey: - _inputs.add(SMITrigger._(input as StateMachineTrigger, this)); - break; - } - } - } - - /// Instance a [StateMachineController] from an [artboard] with the given - /// [stateMachineName]. Returns the [StateMachineController] or null if no - /// [StateMachine] with [stateMachineName] is found. - static StateMachineController? fromArtboard( - Artboard artboard, - String stateMachineName, { - core.OnStateChange? onStateChange, - }) { - for (final animation in artboard.animations) { - if (animation is StateMachine && animation.name == stateMachineName) { - final controller = - StateMachineController(animation, onStateChange: onStateChange); - if (artboard is RuntimeArtboard) { - artboard.addNestedEventListener(controller); - } - return controller; - } - } - return null; - } - - /// Find an input with a specific backing type and a given name. - /// - /// For easier to use methods, see [getBoolInput], [getTriggerInput], - /// [getNumberInput]. - SMIInput? findInput(String name) { - for (final input in _inputs) { - if (input._is() && input.name == name) { - return input as SMIInput; - } - } - return null; - } - - /// Find an input of specific concrete input type, with a given name. - /// - /// For easier to use methods, see [getBoolInput], [getTriggerInput], - /// [getNumberInput]. - T? findSMI(String name) { - for (final input in _inputs) { - if (input is T && input.name == name) { - return input as T; - } - } - return null; - } - - /// Find a boolean input with a given name. - SMIBool? getBoolInput(String name) => findSMI(name); - - /// Find a trigger input with a given name. - SMITrigger? getTriggerInput(String name) => findSMI(name); - - /// Find a number input with a given name. - /// - /// See [triggerInput] to directly fire a trigger by its name. - SMINumber? getNumberInput(String name) => findSMI(name); - - /// Convenience method for firing a trigger input with a given name. - /// - /// Also see [getTriggerInput] to get a reference to the trigger input. If the - /// trigger happens frequently, it's more efficient to get a reference to the - /// trigger input and call `trigger.fire()` directly. - void triggerInput(String name) => getTriggerInput(name)?.fire(); - - @override - void advanceInputs() { - for (final input in _inputs) { - input.advance(); - } - } - - @override - void addRuntimeEventListener(OnRuntimeEvent callback) => - _runtimeEventListeners.add(callback); - - @override - void removeRuntimeEventListener(OnRuntimeEvent callback) => - _runtimeEventListeners.remove(callback); - - @override - void applyEvents() { - var events = reportedEvents.toList(growable: false); - super.applyEvents(); - _runtimeEventListeners.toList().forEach(events.forEach); - } -} diff --git a/lib/src/core/core.dart b/lib/src/core/core.dart deleted file mode 100644 index 1f0b849..0000000 --- a/lib/src/core/core.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'dart:collection'; - -import 'package:flutter/foundation.dart'; -import 'package:rive/src/rive_core/runtime/exceptions/rive_format_error_exception.dart'; - -export 'dart:typed_data'; - -export 'package:flutter/foundation.dart'; -export 'package:rive/src/animation_list.dart'; -export 'package:rive/src/asset_list.dart'; -export 'package:rive/src/blend_animations.dart'; -export 'package:rive/src/container_children.dart'; -export 'package:rive/src/core/field_types/core_callback_type.dart'; -export 'package:rive/src/core/importers/artboard_importer.dart'; -export 'package:rive/src/core/importers/backboard_importer.dart'; -export 'package:rive/src/core/importers/file_asset_importer.dart'; -export 'package:rive/src/core/importers/keyed_object_importer.dart'; -export 'package:rive/src/core/importers/keyed_property_importer.dart'; -export 'package:rive/src/core/importers/layer_state_importer.dart'; -export 'package:rive/src/core/importers/linear_animation_importer.dart'; -export 'package:rive/src/core/importers/nested_state_machine_importer.dart'; -export 'package:rive/src/core/importers/state_machine_importer.dart'; -export 'package:rive/src/core/importers/state_machine_layer_component_importer.dart'; -export 'package:rive/src/core/importers/state_machine_layer_importer.dart'; -export 'package:rive/src/core/importers/state_machine_listener_importer.dart'; -export 'package:rive/src/core/importers/state_transition_importer.dart'; -export 'package:rive/src/data_enum_values.dart'; -export 'package:rive/src/event_list.dart'; -export 'package:rive/src/generated/rive_core_context.dart'; -export 'package:rive/src/layer_component_events.dart'; -export 'package:rive/src/listener_actions.dart'; -export 'package:rive/src/runtime_artboard.dart'; -export 'package:rive/src/state_machine_components.dart'; -export 'package:rive/src/state_transition_conditions.dart'; -export 'package:rive/src/state_transitions.dart'; -export 'package:rive/src/viewmodel_list_items.dart'; -export 'package:rive/src/viewmodel_properties.dart'; - -typedef PropertyChangeCallback = void Function(dynamic from, dynamic to); -typedef BatchAddCallback = void Function(); - -abstract class Core { - static const int missingId = -1; - covariant late T context; - int get coreType; - int id = missingId; - Set get coreTypes => {}; - bool _hasValidated = false; - bool get hasValidated => _hasValidated; - - void onAddedDirty(); - void onAdded() {} - void onRemoved() {} - void remove() => context.removeObject(this); - bool import(ImportStack stack) => true; - - bool validate() => true; - - /// Make a duplicate of this core object, N.B. that all properties excluding - /// object id are copied. - K? clone() { - var object = context.makeCoreInstance(coreType); - object?.copy(this); - return object is K ? object : null; - } - - /// Copies property values, currently doesn't trigger change callbacks. It's - /// meant to be a helper for [clone]. - @protected - void copy(covariant Core source) {} -} - -// ignore: avoid_classes_with_only_static_members -class InternalCoreHelper { - static void markValid(Core object) { - object._hasValidated = true; - } -} - -abstract class CoreContext { - static const int invalidPropertyKey = 0; - - Core? makeCoreInstance(int typeKey); - T? resolve(int id); - T resolveWithDefault(int id, T defaultValue); - void markDependencyOrderDirty(); - bool markDependenciesDirty(covariant Core rootObject); - void removeObject(T object); - T? addObject(T? object); - void markNeedsAdvance(); - void dirty(void Function() dirt); -} - -// ignore: one_member_abstracts -abstract class ImportStackObject { - final _resolveBefore = {}; - bool _resolved = false; - - bool initStack(ImportStack stack) { - var type = resolvesBefore; - if (type == -1) { - return true; - } - var importer = stack.latest(type); - if (importer == null) { - return false; - } - importer._resolveBefore.add(this); - return true; - } - - int get resolvesBefore => -1; - - bool _internalResolve() { - if (_resolved) { - return true; - } - _resolved = true; - if (_resolveBefore.isNotEmpty) { - for (final before in _resolveBefore) { - if (!before._internalResolve()) { - return false; - } - } - } - return resolve(); - } - - bool resolve() => true; -} - -/// Stack to help the RiveFile locate latest ImportStackObject created of a -/// certain type. -class ImportStack { - final _latests = HashMap(); - T? latest(int coreType) { - var latest = _latests[coreType]; - if (latest is T) { - return latest; - } - return null; - } - - T requireLatest(int coreType) { - var object = latest(coreType); - if (object == null) { - throw RiveFormatErrorException( - 'Rive file is corrupt. Couldn\'t find expected object of type ' - '$coreType in import stack.'); - } - return object; - } - - bool makeLatest(int coreType, ImportStackObject? importObject) { - var latest = _latests[coreType]; - if (latest != null) { - if (!latest._internalResolve()) { - return false; - } - } - if (importObject != null && importObject.initStack(this)) { - _latests[coreType] = importObject; - } else { - _latests.remove(coreType); - } - return true; - } - - bool resolve() { - for (final object in _latests.values) { - if (!object._internalResolve()) { - return false; - } - } - return true; - } -} diff --git a/lib/src/core/field_types/core_bool_type.dart b/lib/src/core/field_types/core_bool_type.dart deleted file mode 100644 index 3910d23..0000000 --- a/lib/src/core/field_types/core_bool_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreBoolType extends CoreFieldType { - @override - bool deserialize(BinaryReader reader) => reader.readInt8() == 1; -} diff --git a/lib/src/core/field_types/core_bytes_type.dart b/lib/src/core/field_types/core_bytes_type.dart deleted file mode 100644 index 5834b00..0000000 --- a/lib/src/core/field_types/core_bytes_type.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:typed_data'; - -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreBytesType extends CoreFieldType { - @override - Uint8List deserialize(BinaryReader reader) { - var length = reader.readVarUint(); - return reader.read(length); - } -} diff --git a/lib/src/core/field_types/core_callback_type.dart b/lib/src/core/field_types/core_callback_type.dart deleted file mode 100644 index a6b7b5f..0000000 --- a/lib/src/core/field_types/core_callback_type.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CallbackData { - final Object? context; - final double delay; - CallbackData( - this.context, { - required this.delay, - }); -} - -class CoreCallbackType extends CoreFieldType { - @override - int deserialize(BinaryReader reader) => 0; -} diff --git a/lib/src/core/field_types/core_color_type.dart b/lib/src/core/field_types/core_color_type.dart deleted file mode 100644 index cb06568..0000000 --- a/lib/src/core/field_types/core_color_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreColorType extends CoreFieldType { - @override - int deserialize(BinaryReader reader) => reader.readUint32(); -} diff --git a/lib/src/core/field_types/core_double_type.dart b/lib/src/core/field_types/core_double_type.dart deleted file mode 100644 index ce640af..0000000 --- a/lib/src/core/field_types/core_double_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreDoubleType extends CoreFieldType { - @override - double deserialize(BinaryReader reader) => reader.readFloat32(); -} diff --git a/lib/src/core/field_types/core_field_type.dart b/lib/src/core/field_types/core_field_type.dart deleted file mode 100644 index 0caf274..0000000 --- a/lib/src/core/field_types/core_field_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive_common/utilities.dart'; - -// ignore: one_member_abstracts -abstract class CoreFieldType { - T deserialize(BinaryReader reader); - void skip(BinaryReader reader) => deserialize(reader); -} diff --git a/lib/src/core/field_types/core_int_type.dart b/lib/src/core/field_types/core_int_type.dart deleted file mode 100644 index 2ffe277..0000000 --- a/lib/src/core/field_types/core_int_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreIntType extends CoreFieldType { - @override - int deserialize(BinaryReader reader) => reader.readVarUint(); -} diff --git a/lib/src/core/field_types/core_string_type.dart b/lib/src/core/field_types/core_string_type.dart deleted file mode 100644 index b4291a5..0000000 --- a/lib/src/core/field_types/core_string_type.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreStringType extends CoreFieldType { - @override - String deserialize(BinaryReader reader) => - reader.readString(explicitLength: true); - - @override - void skip(BinaryReader reader) { - var length = reader.readVarUint(); - reader.read(length); - } -} diff --git a/lib/src/core/field_types/core_uint_type.dart b/lib/src/core/field_types/core_uint_type.dart deleted file mode 100644 index 503b5c2..0000000 --- a/lib/src/core/field_types/core_uint_type.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive_common/utilities.dart'; - -class CoreUintType extends CoreFieldType { - @override - int deserialize(BinaryReader reader) => reader.readVarUint(); -} diff --git a/lib/src/core/importers/artboard_import_stack_object.dart b/lib/src/core/importers/artboard_import_stack_object.dart deleted file mode 100644 index 3011e68..0000000 --- a/lib/src/core/importers/artboard_import_stack_object.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -/// An importer that will always resolve with the artboard importer. -abstract class ArtboardImportStackObject extends ImportStackObject { - @override - int get resolvesBefore => ArtboardBase.typeKey; -} diff --git a/lib/src/core/importers/artboard_importer.dart b/lib/src/core/importers/artboard_importer.dart deleted file mode 100644 index 25d5de6..0000000 --- a/lib/src/core/importers/artboard_importer.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:rive/rive.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/animation.dart'; -import 'package:rive/src/rive_core/component.dart'; - -class ArtboardImporter extends ImportStackObject { - final RuntimeArtboard artboard; - ArtboardImporter(this.artboard); - final List animations = []; - - void addComponent(Core? object) => artboard.addObject(object); - - void addAnimation(Animation animation) { - if (animation is LinearAnimation) { - animations.add(animation); - } - artboard.addObject(animation); - animation.artboard = artboard; - } - - void addStateMachine(StateMachine animation) => addAnimation(animation); - - @override - bool resolve() { - for (final object in artboard.objects.skip(1)) { - if (object is Component && - object.parentId == ComponentBase.parentIdInitialValue) { - object.parent = artboard; - } - object?.onAddedDirty(); - } - assert(!artboard.children.contains(artboard), - 'artboard should never contain itself as a child'); - for (final object in artboard.objects.toList(growable: false)) { - if (object == null) { - continue; - } - object.onAdded(); - } - artboard.clean(); - return true; - } -} diff --git a/lib/src/core/importers/backboard_importer.dart b/lib/src/core/importers/backboard_importer.dart deleted file mode 100644 index f8eb090..0000000 --- a/lib/src/core/importers/backboard_importer.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/backboard.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/runtime_nested_artboard.dart'; - -class BackboardImporter extends ImportStackObject { - final Backboard backboard; - - final HashMap artboardLookup; - final Set nestedArtboards = {}; - final List fileAssets = []; - final Set fileAssetReferencers = {}; - BackboardImporter(this.artboardLookup, this.backboard); - - void addArtboard(Artboard object) {} - void addNestedArtboard(NestedArtboard nestedArtboard) => - nestedArtboards.add(nestedArtboard); - - void addFileAsset(FileAsset fileAsset) => fileAssets.add(fileAsset); - - void addFileAssetReferencer(FileAssetReferencer referencer) => - fileAssetReferencers.add(referencer); - - @override - bool resolve() { - for (final nestedArtboard in nestedArtboards) { - var artboard = artboardLookup[nestedArtboard.artboardId]; - - if (artboard is RuntimeArtboard) { - (nestedArtboard as RuntimeNestedArtboard).sourceArtboard = artboard; - } - } - - for (final referencer in fileAssetReferencers) { - if (referencer.assetId >= 0 && referencer.assetId < fileAssets.length) { - referencer.asset = fileAssets[referencer.assetId]; - } - } - return super.resolve(); - } -} diff --git a/lib/src/core/importers/file_asset_importer.dart b/lib/src/core/importers/file_asset_importer.dart deleted file mode 100644 index 237f0c7..0000000 --- a/lib/src/core/importers/file_asset_importer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:rive/src/asset_loader.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/debug.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/assets/file_asset_contents.dart'; - -class FileAssetImporter extends ImportStackObject { - final FileAssetLoader? assetLoader; - final FileAsset fileAsset; - Uint8List? embeddedBytes; - - FileAssetImporter( - this.fileAsset, - this.assetLoader, - ); - - void resolveContents(FileAssetContents contents) { - embeddedBytes = contents.bytes; - } - - @override - bool resolve() { - // allow our loader to load the file asset. - assetLoader?.load(fileAsset, embeddedBytes).then((loaded) { - if (!loaded && embeddedBytes != null) { - fileAsset.decode(embeddedBytes!); - } else if (!loaded) { - // TODO: improve error logging - printDebugMessage( - '''Rive asset (${fileAsset.name}) was not able to load: - - Unique file name: ${fileAsset.uniqueFilename} - - Asset id: ${fileAsset.id}''', - ); - } - }); - return super.resolve(); - } -} diff --git a/lib/src/core/importers/keyed_object_importer.dart b/lib/src/core/importers/keyed_object_importer.dart deleted file mode 100644 index a931f7f..0000000 --- a/lib/src/core/importers/keyed_object_importer.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; - -class KeyedObjectImporter extends ArtboardImportStackObject { - final KeyedObject keyedObject; - - KeyedObjectImporter(this.keyedObject); - - void addKeyedProperty(KeyedProperty property) { - keyedObject.context.addObject(property); - keyedObject.internalAddKeyedProperty(property); - } -} diff --git a/lib/src/core/importers/keyed_property_importer.dart b/lib/src/core/importers/keyed_property_importer.dart deleted file mode 100644 index 595aee1..0000000 --- a/lib/src/core/importers/keyed_property_importer.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; -import 'package:rive/src/rive_core/animation/keyframe.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; - -class KeyedPropertyImporter extends ArtboardImportStackObject { - final KeyedProperty keyedProperty; - final LinearAnimation animation; - - KeyedPropertyImporter(this.keyedProperty, this.animation); - - void addKeyFrame(KeyFrame keyFrame) { - keyedProperty.context.addObject(keyFrame); - keyedProperty.internalAddKeyFrame(keyFrame); - keyFrame.computeSeconds(animation); - } -} diff --git a/lib/src/core/importers/layer_state_importer.dart b/lib/src/core/importers/layer_state_importer.dart deleted file mode 100644 index 8b81f1c..0000000 --- a/lib/src/core/importers/layer_state_importer.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; -import 'package:rive/src/rive_core/animation/blend_state.dart'; -import 'package:rive/src/rive_core/animation/blend_state_transition.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; - -class LayerStateImporter extends ArtboardImportStackObject { - final LayerState state; - LayerStateImporter(this.state); - - void addTransition(StateTransition transition) { - state.context.addObject(transition); - state.internalAddTransition(transition); - } - - bool addBlendAnimation(BlendAnimation blendAnimation) { - // This works because we explicitly export our transitions before our - // animations. - if (state is BlendState) { - var blendState = state as BlendState; - blendState.internalAddAnimation(blendAnimation); - for (final transition - in state.transitions.whereType()) { - if (transition.exitBlendAnimationId >= 0 && - transition.exitBlendAnimationId < blendState.animations.length) { - transition.exitBlendAnimation = - blendState.animations[transition.exitBlendAnimationId]; - } - } - return true; - } - - return false; - } -} diff --git a/lib/src/core/importers/linear_animation_importer.dart b/lib/src/core/importers/linear_animation_importer.dart deleted file mode 100644 index 1863596..0000000 --- a/lib/src/core/importers/linear_animation_importer.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:rive/rive.dart'; -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; - -class LinearAnimationImporter extends ArtboardImportStackObject { - final LinearAnimation linearAnimation; - LinearAnimationImporter(this.linearAnimation); - - void addKeyedObject(KeyedObject object) { - linearAnimation.context.addObject(object); - linearAnimation.internalAddKeyedObject(object); - } -} diff --git a/lib/src/core/importers/nested_state_machine_importer.dart b/lib/src/core/importers/nested_state_machine_importer.dart deleted file mode 100644 index 01fcd44..0000000 --- a/lib/src/core/importers/nested_state_machine_importer.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; - -class NestedStateMachineImporter extends ArtboardImportStackObject { - final NestedStateMachine stateMachine; - NestedStateMachineImporter(this.stateMachine); - - final List _inputs = []; - void addNestedInput(NestedInput nestedInput) { - _inputs.add(nestedInput); - } - - @override - bool resolve() { - for (final input in _inputs) { - input.parent = stateMachine; - } - return super.resolve(); - } -} diff --git a/lib/src/core/importers/state_machine_importer.dart b/lib/src/core/importers/state_machine_importer.dart deleted file mode 100644 index 3c408a4..0000000 --- a/lib/src/core/importers/state_machine_importer.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -class StateMachineImporter extends ArtboardImportStackObject { - final StateMachine machine; - StateMachineImporter(this.machine); - - void addMachineComponent(StateMachineComponent object) { - machine.context.addObject(object); - object.stateMachine = machine; - } -} diff --git a/lib/src/core/importers/state_machine_layer_component_importer.dart b/lib/src/core/importers/state_machine_layer_component_importer.dart deleted file mode 100644 index f2bdc0f..0000000 --- a/lib/src/core/importers/state_machine_layer_component_importer.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/state_machine_fire_event.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart'; - -class StateMachineLayerComponentImporter extends ArtboardImportStackObject { - final StateMachineLayerComponent component; - StateMachineLayerComponentImporter(this.component); - - void addFireEvent(StateMachineFireEvent event) { - component.internalAddFireEvent(event); - } -} diff --git a/lib/src/core/importers/state_machine_layer_importer.dart b/lib/src/core/importers/state_machine_layer_importer.dart deleted file mode 100644 index 096b168..0000000 --- a/lib/src/core/importers/state_machine_layer_importer.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:rive/rive.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; - -class StateMachineLayerImporter extends ImportStackObject { - final StateMachineLayer layer; - StateMachineLayerImporter(this.layer); - - final List importedStates = []; - - void addState(LayerState state) { - importedStates.add(state); - // Here the state gets assigned a core (artboard) id. - layer.context.addObject(state); - layer.internalAddState(state); - } - - @override - int get resolvesBefore => StateMachineBase.typeKey; - - bool _resolved = false; - @override - bool resolve() { - assert(!_resolved); - _resolved = true; - for (final state in importedStates) { - for (final transition in state.transitions) { - // At import time the stateToId is an index relative to the entire layer - // (which state in this layer). We can use that to find the matching - // importedState and assign back the core id that will resolve after the - // entire artboard imports. - if (transition.stateToId >= 0 && - transition.stateToId < importedStates.length) { - transition.stateTo = importedStates[transition.stateToId]; - } - } - } - return true; - } -} diff --git a/lib/src/core/importers/state_machine_listener_importer.dart b/lib/src/core/importers/state_machine_listener_importer.dart deleted file mode 100644 index 09ad849..0000000 --- a/lib/src/core/importers/state_machine_listener_importer.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/listener_action.dart'; -import 'package:rive/src/rive_core/animation/state_machine_listener.dart'; - -class StateMachineListenerImporter extends ArtboardImportStackObject { - final StateMachineListener listener; - StateMachineListenerImporter(this.listener); - - void addAction(ListenerAction change) { - listener.internalAddAction(change); - } -} diff --git a/lib/src/core/importers/state_transition_importer.dart b/lib/src/core/importers/state_transition_importer.dart deleted file mode 100644 index e89bf02..0000000 --- a/lib/src/core/importers/state_transition_importer.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/core/importers/artboard_import_stack_object.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_input_condition.dart'; - -class StateTransitionImporter extends ArtboardImportStackObject { - final StateMachineImporter stateMachineImporter; - final StateTransition transition; - StateTransitionImporter(this.transition, this.stateMachineImporter); - - void addCondition(TransitionCondition condition) { - transition.context.addObject(condition); - transition.internalAddCondition(condition); - } - - @override - bool resolve() { - var inputs = stateMachineImporter.machine.inputs; - for (final condition in transition.conditions) { - if (condition is TransitionInputCondition) { - var inputIndex = condition.inputId; - if (inputIndex >= 0 && inputIndex < inputs.length) { - condition.inputId = inputs[inputIndex].id; - } - } - } - return true; - } -} diff --git a/lib/src/core/importers/viewmodel_instance_importer.dart b/lib/src/core/importers/viewmodel_instance_importer.dart deleted file mode 100644 index 449bf44..0000000 --- a/lib/src/core/importers/viewmodel_instance_importer.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ViewModelInstanceImporter extends ImportStackObject { - final ViewModelInstance viewModelInstance; - ViewModelInstanceImporter(this.viewModelInstance); - - void addValue(ViewModelInstanceValue value) { - viewModelInstance.addPropertyValue(value); - } -} diff --git a/lib/src/data_enum_values.dart b/lib/src/data_enum_values.dart deleted file mode 100644 index 945c329..0000000 --- a/lib/src/data_enum_values.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/viewmodel/data_enum_value.dart'; - -class DataEnumValues extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - T operator [](int index) => _values[index]!; - - @override - void operator []=(int index, T value) => _values[index] = value; -} diff --git a/lib/src/debug.dart b/lib/src/debug.dart deleted file mode 100644 index 8d92f07..0000000 --- a/lib/src/debug.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:flutter/foundation.dart'; - -/// Print a message only when running in debug. -void printDebugMessage(String message) { - assert(() { - debugPrint(message); - return true; - }()); -} diff --git a/lib/src/dynamic_library_helper/dynamic_library_helper_ffi.dart b/lib/src/dynamic_library_helper/dynamic_library_helper_ffi.dart deleted file mode 100644 index 395663a..0000000 --- a/lib/src/dynamic_library_helper/dynamic_library_helper_ffi.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'package:rive_common/src/dynamic_library_helper.dart' - show applyWorkaroundToRiveOnOldAndroidVersions; diff --git a/lib/src/dynamic_library_helper/dynamic_library_helper_stub.dart b/lib/src/dynamic_library_helper/dynamic_library_helper_stub.dart deleted file mode 100644 index 19d5be9..0000000 --- a/lib/src/dynamic_library_helper/dynamic_library_helper_stub.dart +++ /dev/null @@ -1,3 +0,0 @@ -void applyWorkaroundToRiveOnOldAndroidVersions() { - throw UnsupportedError('Platform not supported'); -} diff --git a/lib/src/dynamic_library_helper/dynamic_library_helper_web.dart b/lib/src/dynamic_library_helper/dynamic_library_helper_web.dart deleted file mode 100644 index f7bf967..0000000 --- a/lib/src/dynamic_library_helper/dynamic_library_helper_web.dart +++ /dev/null @@ -1,2 +0,0 @@ -// Mock implementation for web -void applyWorkaroundToRiveOnOldAndroidVersions() {} diff --git a/lib/src/errors.dart b/lib/src/errors.dart new file mode 100644 index 0000000..e1fc34a --- /dev/null +++ b/lib/src/errors.dart @@ -0,0 +1,45 @@ +/// A base class for all Rive exceptions. +class RiveException implements Exception { + RiveException(this.message); + final String message; +} + +/// An exception that is thrown when a Rive FileLoader fails to load. +class RiveFileLoaderException extends RiveException { + RiveFileLoaderException(super.message); + + @override + String toString() { + return 'RiveFileLoaderException: $message'; + } +} + +/// An exception that is thrown when a Rive Artboard fails to load. +class RiveArtboardException extends RiveException { + RiveArtboardException(super.message); + + @override + String toString() { + return 'RiveArtboardException: $message'; + } +} + +/// An exception that is thrown when a Rive State Machine fails to load. +class RiveStateMachineException extends RiveException { + RiveStateMachineException(super.message); + + @override + String toString() { + return 'RiveStateMachineException: $message'; + } +} + +/// An exception that is thrown when a data bind fails. +class RiveDataBindException extends RiveException { + RiveDataBindException(super.message); + + @override + String toString() { + return 'RiveDataBindException: $message'; + } +} diff --git a/lib/src/event_list.dart b/lib/src/event_list.dart deleted file mode 100644 index f1ac211..0000000 --- a/lib/src/event_list.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/event.dart'; - -class EventList extends ListBase { - // Lame way to do this due to how ListBase needs to expand a nullable list. - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - Event operator [](int index) => _values[index]!; - - @override - void operator []=(int index, Event value) => _values[index] = value; -} diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart deleted file mode 100644 index e111ca0..0000000 --- a/lib/src/extensions.dart +++ /dev/null @@ -1,27 +0,0 @@ -/// Extensions to the runtime core classes -import 'package:collection/collection.dart'; -import 'package:rive/src/controllers/linear_animation_controller.dart'; -import 'package:rive/src/controllers/state_machine_controller.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart' as core; - -/// Artboard extensions -extension ArtboardAdditions on Artboard { - /// Returns an animation with the given name, or null if no animation with - /// that name exists in the artboard - LinearAnimationInstance? animationByName(String name) { - final animation = animations.firstWhereOrNull( - (animation) => animation is LinearAnimation && animation.name == name); - if (animation != null) { - return LinearAnimationInstance(animation as LinearAnimation); - } - return null; - } - - /// Returns a StateMachine with the given name, or null if no state machine - /// with that name exists in the artboard - StateMachineController? stateMachineByName(String name, - {core.OnStateChange? onChange}) => - StateMachineController.fromArtboard(this, name, onStateChange: onChange); -} diff --git a/lib/src/file_loader.dart b/lib/src/file_loader.dart new file mode 100644 index 0000000..d564632 --- /dev/null +++ b/lib/src/file_loader.dart @@ -0,0 +1,121 @@ +import 'dart:async' show Completer; + +import 'package:rive/rive.dart' as rive; +import 'package:rive/src/errors.dart'; + +/// {@template FileLoader} +/// A class that loads a Rive file from an asset, URL, or file. +/// +/// To be used with [RiveWidgetBuilder]. +/// +/// - The [riveFactory] parameter is the Rive factory to use to decode the Rive +/// file, and determines the desired renderer to use. +/// +/// This class caches the loaded file, and returns the same file instance +/// for subsequent calls to [file]. +/// {@endtemplate} +class FileLoader { + final rive.Factory riveFactory; + final rive.File? _providedFile; + final String? _asset; + final String? _url; + Completer? _loadCompleter; + rive.File? _loadedFile; + + /// {@macro FileLoader} + /// - The [asset] parameter is the asset to load the Rive file from. + FileLoader.fromAsset(String asset, {required this.riveFactory}) + : _asset = asset, + _providedFile = null, + _url = null; + + /// {@macro FileLoader} + /// - The [url] parameter is the URL to load the Rive file from. + FileLoader.fromUrl(String url, {required this.riveFactory}) + : _url = url, + _providedFile = null, + _asset = null; + + /// {@macro FileLoader} + /// - The [file] parameter is the file to load the Rive file from. + FileLoader.fromFile(rive.File file, {required this.riveFactory}) + : _providedFile = file, + _asset = null, + _url = null; + + Future file() async { + if (_providedFile != null) { + _loadedFile = _providedFile; + return _providedFile; + } + + if (_loadCompleter != null) { + return _loadCompleter!.future; + } + + _loadCompleter = Completer(); + + try { + rive.File? file; + + if (_asset != null) { + try { + file = await rive.File.asset(_asset, riveFactory: riveFactory); + } catch (e) { + // Handle the case where the asset doesn't exist or has empty data + throw RiveFileLoaderException( + 'Failed to load Rive file from asset: $_asset. Error: $e'); + } + if (file == null) { + throw RiveFileLoaderException( + 'Failed to decode Rive file from asset: $_asset'); + } + } else if (_url != null) { + try { + file = await rive.File.url(_url, riveFactory: riveFactory); + } catch (e) { + // Handle the case where the URL fails to load + throw RiveFileLoaderException( + 'Failed to load Rive file from URL: $_url. Error: $e'); + } + if (file == null) { + throw RiveFileLoaderException( + 'Failed to decode Rive file from URL: $_url'); + } + } else { + throw RiveFileLoaderException( + 'No asset, URL, or file provided to RiveFileLoader'); + } + + _loadedFile = file; + _loadCompleter!.complete(file); + return file; + } on RiveFileLoaderException catch (e) { + _loadCompleter!.completeError(e); + rethrow; + } on Exception catch (e) { + final riveException = + RiveFileLoaderException('Unexpected error loading Rive file: $e'); + _loadCompleter!.completeError(riveException); + throw riveException; + } + } + + /// Returns the file synchronously if it's already available. + /// + /// This will return the file immediately if: + /// - The FileLoader was created with [FileLoader.fromFile] + /// - The file has been loaded via [FileLoader.file] and is cached + /// + /// Returns `null` if the file is not yet available. + rive.File? get fileSync => _providedFile ?? _loadedFile; + + /// Returns whether the file is currently available synchronously. + bool get isFileAvailable => fileSync != null; + + void dispose() { + _providedFile?.dispose(); + _loadedFile?.dispose(); + _loadCompleter = null; + } +} diff --git a/lib/src/generated/animation/advanceable_state_base.dart b/lib/src/generated/animation/advanceable_state_base.dart deleted file mode 100644 index 0070ce8..0000000 --- a/lib/src/generated/animation/advanceable_state_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/advanceable_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; - -abstract class AdvanceableStateBase extends LayerState { - static const int typeKey = 145; - @override - int get coreType => AdvanceableStateBase.typeKey; - @override - Set get coreTypes => { - AdvanceableStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Speed field with key 292. - static const int speedPropertyKey = 292; - static const double speedInitialValue = 1; - double _speed = speedInitialValue; - double get speed => _speed; - - /// Change the [_speed] field value. - /// [speedChanged] will be invoked only if the field's value has changed. - set speed(double value) { - if (_speed == value) { - return; - } - double from = _speed; - _speed = value; - if (hasValidated) { - speedChanged(from, value); - } - } - - void speedChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is AdvanceableStateBase) { - _speed = source._speed; - } - } -} diff --git a/lib/src/generated/animation/animation_base.dart b/lib/src/generated/animation/animation_base.dart deleted file mode 100644 index b4bfdb4..0000000 --- a/lib/src/generated/animation/animation_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class AnimationBase extends Core { - static const int typeKey = 27; - @override - int get coreType => AnimationBase.typeKey; - @override - Set get coreTypes => {AnimationBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 55. - static const int namePropertyKey = 55; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Name of the animation. - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is AnimationBase) { - _name = source._name; - } - } -} diff --git a/lib/src/generated/animation/animation_state_base.dart b/lib/src/generated/animation/animation_state_base.dart deleted file mode 100644 index 5832689..0000000 --- a/lib/src/generated/animation/animation_state_base.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/animation_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/layer_state_base.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/advanceable_state.dart'; - -abstract class AnimationStateBase extends AdvanceableState { - static const int typeKey = 61; - @override - int get coreType => AnimationStateBase.typeKey; - @override - Set get coreTypes => { - AnimationStateBase.typeKey, - AdvanceableStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AnimationId field with key 149. - static const int animationIdPropertyKey = 149; - static const int animationIdInitialValue = -1; - int _animationId = animationIdInitialValue; - - /// Id of the animation this layer state refers to. - int get animationId => _animationId; - - /// Change the [_animationId] field value. - /// [animationIdChanged] will be invoked only if the field's value has - /// changed. - set animationId(int value) { - if (_animationId == value) { - return; - } - int from = _animationId; - _animationId = value; - if (hasValidated) { - animationIdChanged(from, value); - } - } - - void animationIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is AnimationStateBase) { - _animationId = source._animationId; - } - } -} diff --git a/lib/src/generated/animation/any_state_base.dart b/lib/src/generated/animation/any_state_base.dart deleted file mode 100644 index 1c74964..0000000 --- a/lib/src/generated/animation/any_state_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/any_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; - -abstract class AnyStateBase extends LayerState { - static const int typeKey = 62; - @override - int get coreType => AnyStateBase.typeKey; - @override - Set get coreTypes => { - AnyStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/blend_animation_1d_base.dart b/lib/src/generated/animation/blend_animation_1d_base.dart deleted file mode 100644 index a17eeea..0000000 --- a/lib/src/generated/animation/blend_animation_1d_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_animation_1d_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; - -abstract class BlendAnimation1DBase extends BlendAnimation { - static const int typeKey = 75; - @override - int get coreType => BlendAnimation1DBase.typeKey; - @override - Set get coreTypes => - {BlendAnimation1DBase.typeKey, BlendAnimationBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Value field with key 166. - static const int valuePropertyKey = 166; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BlendAnimation1DBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/blend_animation_base.dart b/lib/src/generated/animation/blend_animation_base.dart deleted file mode 100644 index 5eaf997..0000000 --- a/lib/src/generated/animation/blend_animation_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class BlendAnimationBase extends Core { - static const int typeKey = 74; - @override - int get coreType => BlendAnimationBase.typeKey; - @override - Set get coreTypes => {BlendAnimationBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// AnimationId field with key 165. - static const int animationIdPropertyKey = 165; - static const int animationIdInitialValue = -1; - int _animationId = animationIdInitialValue; - - /// Id of the animation this BlendAnimation references. - int get animationId => _animationId; - - /// Change the [_animationId] field value. - /// [animationIdChanged] will be invoked only if the field's value has - /// changed. - set animationId(int value) { - if (_animationId == value) { - return; - } - int from = _animationId; - _animationId = value; - if (hasValidated) { - animationIdChanged(from, value); - } - } - - void animationIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BlendAnimationBase) { - _animationId = source._animationId; - } - } -} diff --git a/lib/src/generated/animation/blend_animation_direct_base.dart b/lib/src/generated/animation/blend_animation_direct_base.dart deleted file mode 100644 index 0168c58..0000000 --- a/lib/src/generated/animation/blend_animation_direct_base.dart +++ /dev/null @@ -1,99 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_animation_direct_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; - -abstract class BlendAnimationDirectBase extends BlendAnimation { - static const int typeKey = 77; - @override - int get coreType => BlendAnimationDirectBase.typeKey; - @override - Set get coreTypes => - {BlendAnimationDirectBase.typeKey, BlendAnimationBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InputId field with key 168. - static const int inputIdPropertyKey = 168; - static const int inputIdInitialValue = -1; - int _inputId = inputIdInitialValue; - - /// Id of the input that drives the direct mix value for this animation. - int get inputId => _inputId; - - /// Change the [_inputId] field value. - /// [inputIdChanged] will be invoked only if the field's value has changed. - set inputId(int value) { - if (_inputId == value) { - return; - } - int from = _inputId; - _inputId = value; - if (hasValidated) { - inputIdChanged(from, value); - } - } - - void inputIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MixValue field with key 297. - static const int mixValuePropertyKey = 297; - static const double mixValueInitialValue = 100; - double _mixValue = mixValueInitialValue; - - /// Direct mix value for this animation. - double get mixValue => _mixValue; - - /// Change the [_mixValue] field value. - /// [mixValueChanged] will be invoked only if the field's value has changed. - set mixValue(double value) { - if (_mixValue == value) { - return; - } - double from = _mixValue; - _mixValue = value; - if (hasValidated) { - mixValueChanged(from, value); - } - } - - void mixValueChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// BlendSource field with key 298. - static const int blendSourcePropertyKey = 298; - static const int blendSourceInitialValue = 0; - int _blendSource = blendSourceInitialValue; - - /// Source to use when establishing the mix value for the animation. 0 means - /// look at the input, 1 look at the mixValue. - int get blendSource => _blendSource; - - /// Change the [_blendSource] field value. - /// [blendSourceChanged] will be invoked only if the field's value has - /// changed. - set blendSource(int value) { - if (_blendSource == value) { - return; - } - int from = _blendSource; - _blendSource = value; - if (hasValidated) { - blendSourceChanged(from, value); - } - } - - void blendSourceChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BlendAnimationDirectBase) { - _inputId = source._inputId; - _mixValue = source._mixValue; - _blendSource = source._blendSource; - } - } -} diff --git a/lib/src/generated/animation/blend_state_1d_base.dart b/lib/src/generated/animation/blend_state_1d_base.dart deleted file mode 100644 index a8811dd..0000000 --- a/lib/src/generated/animation/blend_state_1d_base.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_state_1d_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/layer_state_base.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/blend_animation_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_state.dart'; - -abstract class BlendState1DBase extends BlendState { - static const int typeKey = 76; - @override - int get coreType => BlendState1DBase.typeKey; - @override - Set get coreTypes => { - BlendState1DBase.typeKey, - BlendStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// InputId field with key 167. - static const int inputIdPropertyKey = 167; - static const int inputIdInitialValue = -1; - int _inputId = inputIdInitialValue; - - /// Id of the input that drives the mix value for this blend state. - int get inputId => _inputId; - - /// Change the [_inputId] field value. - /// [inputIdChanged] will be invoked only if the field's value has changed. - set inputId(int value) { - if (_inputId == value) { - return; - } - int from = _inputId; - _inputId = value; - if (hasValidated) { - inputIdChanged(from, value); - } - } - - void inputIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BlendState1DBase) { - _inputId = source._inputId; - } - } -} diff --git a/lib/src/generated/animation/blend_state_base.dart b/lib/src/generated/animation/blend_state_base.dart deleted file mode 100644 index ba8926d..0000000 --- a/lib/src/generated/animation/blend_state_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; - -abstract class BlendStateBase extends LayerState { - static const int typeKey = 72; - @override - int get coreType => BlendStateBase.typeKey; - @override - Set get coreTypes => { - BlendStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/blend_state_direct_base.dart b/lib/src/generated/animation/blend_state_direct_base.dart deleted file mode 100644 index db5b2cd..0000000 --- a/lib/src/generated/animation/blend_state_direct_base.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_state_direct_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/layer_state_base.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/blend_animation_direct.dart'; -import 'package:rive/src/rive_core/animation/blend_state.dart'; - -abstract class BlendStateDirectBase extends BlendState { - static const int typeKey = 73; - @override - int get coreType => BlendStateDirectBase.typeKey; - @override - Set get coreTypes => { - BlendStateDirectBase.typeKey, - BlendStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/blend_state_transition_base.dart b/lib/src/generated/animation/blend_state_transition_base.dart deleted file mode 100644 index 1fbc2c4..0000000 --- a/lib/src/generated/animation/blend_state_transition_base.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/blend_state_transition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; - -abstract class BlendStateTransitionBase extends StateTransition { - static const int typeKey = 78; - @override - int get coreType => BlendStateTransitionBase.typeKey; - @override - Set get coreTypes => { - BlendStateTransitionBase.typeKey, - StateTransitionBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ExitBlendAnimationId field with key 171. - static const int exitBlendAnimationIdPropertyKey = 171; - static const int exitBlendAnimationIdInitialValue = -1; - int _exitBlendAnimationId = exitBlendAnimationIdInitialValue; - - /// Id of the state the blend state animation used for exit time calculation. - int get exitBlendAnimationId => _exitBlendAnimationId; - - /// Change the [_exitBlendAnimationId] field value. - /// [exitBlendAnimationIdChanged] will be invoked only if the field's value - /// has changed. - set exitBlendAnimationId(int value) { - if (_exitBlendAnimationId == value) { - return; - } - int from = _exitBlendAnimationId; - _exitBlendAnimationId = value; - if (hasValidated) { - exitBlendAnimationIdChanged(from, value); - } - } - - void exitBlendAnimationIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BlendStateTransitionBase) { - _exitBlendAnimationId = source._exitBlendAnimationId; - } - } -} diff --git a/lib/src/generated/animation/cubic_ease_interpolator_base.dart b/lib/src/generated/animation/cubic_ease_interpolator_base.dart deleted file mode 100644 index 006833c..0000000 --- a/lib/src/generated/animation/cubic_ease_interpolator_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/cubic_ease_interpolator_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; - -abstract class CubicEaseInterpolatorBase extends CubicInterpolator { - static const int typeKey = 28; - @override - int get coreType => CubicEaseInterpolatorBase.typeKey; - @override - Set get coreTypes => { - CubicEaseInterpolatorBase.typeKey, - CubicInterpolatorBase.typeKey, - KeyFrameInterpolatorBase.typeKey - }; -} diff --git a/lib/src/generated/animation/cubic_interpolator_base.dart b/lib/src/generated/animation/cubic_interpolator_base.dart deleted file mode 100644 index 4668fb6..0000000 --- a/lib/src/generated/animation/cubic_interpolator_base.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/cubic_interpolator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart'; - -abstract class CubicInterpolatorBase extends KeyFrameInterpolator { - static const int typeKey = 139; - @override - int get coreType => CubicInterpolatorBase.typeKey; - @override - Set get coreTypes => - {CubicInterpolatorBase.typeKey, KeyFrameInterpolatorBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// X1 field with key 63. - static const int x1PropertyKey = 63; - static const double x1InitialValue = 0.42; - double _x1 = x1InitialValue; - double get x1 => _x1; - - /// Change the [_x1] field value. - /// [x1Changed] will be invoked only if the field's value has changed. - set x1(double value) { - if (_x1 == value) { - return; - } - double from = _x1; - _x1 = value; - if (hasValidated) { - x1Changed(from, value); - } - } - - void x1Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y1 field with key 64. - static const int y1PropertyKey = 64; - static const double y1InitialValue = 0; - double _y1 = y1InitialValue; - double get y1 => _y1; - - /// Change the [_y1] field value. - /// [y1Changed] will be invoked only if the field's value has changed. - set y1(double value) { - if (_y1 == value) { - return; - } - double from = _y1; - _y1 = value; - if (hasValidated) { - y1Changed(from, value); - } - } - - void y1Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// X2 field with key 65. - static const int x2PropertyKey = 65; - static const double x2InitialValue = 0.58; - double _x2 = x2InitialValue; - double get x2 => _x2; - - /// Change the [_x2] field value. - /// [x2Changed] will be invoked only if the field's value has changed. - set x2(double value) { - if (_x2 == value) { - return; - } - double from = _x2; - _x2 = value; - if (hasValidated) { - x2Changed(from, value); - } - } - - void x2Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y2 field with key 66. - static const int y2PropertyKey = 66; - static const double y2InitialValue = 1; - double _y2 = y2InitialValue; - double get y2 => _y2; - - /// Change the [_y2] field value. - /// [y2Changed] will be invoked only if the field's value has changed. - set y2(double value) { - if (_y2 == value) { - return; - } - double from = _y2; - _y2 = value; - if (hasValidated) { - y2Changed(from, value); - } - } - - void y2Changed(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicInterpolatorBase) { - _x1 = source._x1; - _y1 = source._y1; - _x2 = source._x2; - _y2 = source._y2; - } - } -} diff --git a/lib/src/generated/animation/cubic_interpolator_component_base.dart b/lib/src/generated/animation/cubic_interpolator_component_base.dart deleted file mode 100644 index 6b7f52f..0000000 --- a/lib/src/generated/animation/cubic_interpolator_component_base.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/cubic_interpolator_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class CubicInterpolatorComponentBase extends Component { - static const int typeKey = 163; - @override - int get coreType => CubicInterpolatorComponentBase.typeKey; - @override - Set get coreTypes => - {CubicInterpolatorComponentBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// X1 field with key 337. - static const int x1PropertyKey = 337; - static const double x1InitialValue = 0.42; - double _x1 = x1InitialValue; - double get x1 => _x1; - - /// Change the [_x1] field value. - /// [x1Changed] will be invoked only if the field's value has changed. - set x1(double value) { - if (_x1 == value) { - return; - } - double from = _x1; - _x1 = value; - if (hasValidated) { - x1Changed(from, value); - } - } - - void x1Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y1 field with key 338. - static const int y1PropertyKey = 338; - static const double y1InitialValue = 0; - double _y1 = y1InitialValue; - double get y1 => _y1; - - /// Change the [_y1] field value. - /// [y1Changed] will be invoked only if the field's value has changed. - set y1(double value) { - if (_y1 == value) { - return; - } - double from = _y1; - _y1 = value; - if (hasValidated) { - y1Changed(from, value); - } - } - - void y1Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// X2 field with key 339. - static const int x2PropertyKey = 339; - static const double x2InitialValue = 0.58; - double _x2 = x2InitialValue; - double get x2 => _x2; - - /// Change the [_x2] field value. - /// [x2Changed] will be invoked only if the field's value has changed. - set x2(double value) { - if (_x2 == value) { - return; - } - double from = _x2; - _x2 = value; - if (hasValidated) { - x2Changed(from, value); - } - } - - void x2Changed(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y2 field with key 340. - static const int y2PropertyKey = 340; - static const double y2InitialValue = 1; - double _y2 = y2InitialValue; - double get y2 => _y2; - - /// Change the [_y2] field value. - /// [y2Changed] will be invoked only if the field's value has changed. - set y2(double value) { - if (_y2 == value) { - return; - } - double from = _y2; - _y2 = value; - if (hasValidated) { - y2Changed(from, value); - } - } - - void y2Changed(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicInterpolatorComponentBase) { - _x1 = source._x1; - _y1 = source._y1; - _x2 = source._x2; - _y2 = source._y2; - } - } -} diff --git a/lib/src/generated/animation/cubic_value_interpolator_base.dart b/lib/src/generated/animation/cubic_value_interpolator_base.dart deleted file mode 100644 index 21595ea..0000000 --- a/lib/src/generated/animation/cubic_value_interpolator_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/cubic_value_interpolator_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; - -abstract class CubicValueInterpolatorBase extends CubicInterpolator { - static const int typeKey = 138; - @override - int get coreType => CubicValueInterpolatorBase.typeKey; - @override - Set get coreTypes => { - CubicValueInterpolatorBase.typeKey, - CubicInterpolatorBase.typeKey, - KeyFrameInterpolatorBase.typeKey - }; -} diff --git a/lib/src/generated/animation/elastic_interpolator_base.dart b/lib/src/generated/animation/elastic_interpolator_base.dart deleted file mode 100644 index 2848c6a..0000000 --- a/lib/src/generated/animation/elastic_interpolator_base.dart +++ /dev/null @@ -1,97 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/elastic_interpolator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart'; - -abstract class ElasticInterpolatorBase extends KeyFrameInterpolator { - static const int typeKey = 174; - @override - int get coreType => ElasticInterpolatorBase.typeKey; - @override - Set get coreTypes => - {ElasticInterpolatorBase.typeKey, KeyFrameInterpolatorBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// EasingValue field with key 405. - static const int easingValuePropertyKey = 405; - static const int easingValueInitialValue = 1; - int _easingValue = easingValueInitialValue; - int get easingValue => _easingValue; - - /// Change the [_easingValue] field value. - /// [easingValueChanged] will be invoked only if the field's value has - /// changed. - set easingValue(int value) { - if (_easingValue == value) { - return; - } - int from = _easingValue; - _easingValue = value; - if (hasValidated) { - easingValueChanged(from, value); - } - } - - void easingValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Amplitude field with key 406. - static const int amplitudePropertyKey = 406; - static const double amplitudeInitialValue = 1; - double _amplitude = amplitudeInitialValue; - - /// The amplitude for the easing expressed as a percentage of the change. - double get amplitude => _amplitude; - - /// Change the [_amplitude] field value. - /// [amplitudeChanged] will be invoked only if the field's value has changed. - set amplitude(double value) { - if (_amplitude == value) { - return; - } - double from = _amplitude; - _amplitude = value; - if (hasValidated) { - amplitudeChanged(from, value); - } - } - - void amplitudeChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Period field with key 407. - static const int periodPropertyKey = 407; - static const double periodInitialValue = 1; - double _period = periodInitialValue; - - /// The period of the elastic expressed as a percentage of the time - /// difference. - double get period => _period; - - /// Change the [_period] field value. - /// [periodChanged] will be invoked only if the field's value has changed. - set period(double value) { - if (_period == value) { - return; - } - double from = _period; - _period = value; - if (hasValidated) { - periodChanged(from, value); - } - } - - void periodChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ElasticInterpolatorBase) { - _easingValue = source._easingValue; - _amplitude = source._amplitude; - _period = source._period; - } - } -} diff --git a/lib/src/generated/animation/entry_state_base.dart b/lib/src/generated/animation/entry_state_base.dart deleted file mode 100644 index d76c781..0000000 --- a/lib/src/generated/animation/entry_state_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/entry_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; - -abstract class EntryStateBase extends LayerState { - static const int typeKey = 63; - @override - int get coreType => EntryStateBase.typeKey; - @override - Set get coreTypes => { - EntryStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/exit_state_base.dart b/lib/src/generated/animation/exit_state_base.dart deleted file mode 100644 index 2cb7148..0000000 --- a/lib/src/generated/animation/exit_state_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/exit_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; - -abstract class ExitStateBase extends LayerState { - static const int typeKey = 64; - @override - int get coreType => ExitStateBase.typeKey; - @override - Set get coreTypes => { - ExitStateBase.typeKey, - LayerStateBase.typeKey, - StateMachineLayerComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/interpolating_keyframe_base.dart b/lib/src/generated/animation/interpolating_keyframe_base.dart deleted file mode 100644 index 59f761e..0000000 --- a/lib/src/generated/animation/interpolating_keyframe_base.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/interpolating_keyframe_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/keyframe.dart'; - -abstract class InterpolatingKeyFrameBase extends KeyFrame { - static const int typeKey = 170; - @override - int get coreType => InterpolatingKeyFrameBase.typeKey; - @override - Set get coreTypes => - {InterpolatingKeyFrameBase.typeKey, KeyFrameBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InterpolationType field with key 68. - static const int interpolationTypePropertyKey = 68; - static const int interpolationTypeInitialValue = 0; - int _interpolationType = interpolationTypeInitialValue; - - /// The type of interpolation index in KeyframeInterpolation applied to this - /// keyframe. - int get interpolationType => _interpolationType; - - /// Change the [_interpolationType] field value. - /// [interpolationTypeChanged] will be invoked only if the field's value has - /// changed. - set interpolationType(int value) { - if (_interpolationType == value) { - return; - } - int from = _interpolationType; - _interpolationType = value; - if (hasValidated) { - interpolationTypeChanged(from, value); - } - } - - void interpolationTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolatorId field with key 69. - static const int interpolatorIdPropertyKey = 69; - static const int interpolatorIdInitialValue = -1; - int _interpolatorId = interpolatorIdInitialValue; - - /// The id of the custom interpolator used when interpolation is Cubic. - int get interpolatorId => _interpolatorId; - - /// Change the [_interpolatorId] field value. - /// [interpolatorIdChanged] will be invoked only if the field's value has - /// changed. - set interpolatorId(int value) { - if (_interpolatorId == value) { - return; - } - int from = _interpolatorId; - _interpolatorId = value; - if (hasValidated) { - interpolatorIdChanged(from, value); - } - } - - void interpolatorIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is InterpolatingKeyFrameBase) { - _interpolationType = source._interpolationType; - _interpolatorId = source._interpolatorId; - } - } -} diff --git a/lib/src/generated/animation/keyed_object_base.dart b/lib/src/generated/animation/keyed_object_base.dart deleted file mode 100644 index 5c1e649..0000000 --- a/lib/src/generated/animation/keyed_object_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyed_object_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class KeyedObjectBase extends Core { - static const int typeKey = 25; - @override - int get coreType => KeyedObjectBase.typeKey; - @override - Set get coreTypes => {KeyedObjectBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// ObjectId field with key 51. - static const int objectIdPropertyKey = 51; - static const int objectIdInitialValue = 0; - int _objectId = objectIdInitialValue; - - /// Identifier used to track the object that is keyed. - int get objectId => _objectId; - - /// Change the [_objectId] field value. - /// [objectIdChanged] will be invoked only if the field's value has changed. - set objectId(int value) { - if (_objectId == value) { - return; - } - int from = _objectId; - _objectId = value; - if (hasValidated) { - objectIdChanged(from, value); - } - } - - void objectIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyedObjectBase) { - _objectId = source._objectId; - } - } -} diff --git a/lib/src/generated/animation/keyed_property_base.dart b/lib/src/generated/animation/keyed_property_base.dart deleted file mode 100644 index 515dcf9..0000000 --- a/lib/src/generated/animation/keyed_property_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyed_property_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class KeyedPropertyBase extends Core { - static const int typeKey = 26; - @override - int get coreType => KeyedPropertyBase.typeKey; - @override - Set get coreTypes => {KeyedPropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyKey field with key 53. - static const int propertyKeyPropertyKey = 53; - static const int propertyKeyInitialValue = CoreContext.invalidPropertyKey; - int _propertyKey = propertyKeyInitialValue; - - /// The property type that is keyed. - int get propertyKey => _propertyKey; - - /// Change the [_propertyKey] field value. - /// [propertyKeyChanged] will be invoked only if the field's value has - /// changed. - set propertyKey(int value) { - if (_propertyKey == value) { - return; - } - int from = _propertyKey; - _propertyKey = value; - if (hasValidated) { - propertyKeyChanged(from, value); - } - } - - void propertyKeyChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyedPropertyBase) { - _propertyKey = source._propertyKey; - } - } -} diff --git a/lib/src/generated/animation/keyframe_base.dart b/lib/src/generated/animation/keyframe_base.dart deleted file mode 100644 index 295a1e6..0000000 --- a/lib/src/generated/animation/keyframe_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated lib/src/generated/animation/keyframe_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class KeyFrameBase extends Core { - static const int typeKey = 29; - @override - int get coreType => KeyFrameBase.typeKey; - @override - Set get coreTypes => {KeyFrameBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Frame field with key 67. - static const int framePropertyKey = 67; - static const int frameInitialValue = 0; - int _frame = frameInitialValue; - - /// Timecode as frame number can be converted to time by dividing by animation - /// fps. - int get frame => _frame; - - /// Change the [_frame] field value. - /// [frameChanged] will be invoked only if the field's value has changed. - set frame(int value) { - if (_frame == value) { - return; - } - int from = _frame; - _frame = value; - if (hasValidated) { - frameChanged(from, value); - } - } - - void frameChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameBase) { - _frame = source._frame; - } - } -} diff --git a/lib/src/generated/animation/keyframe_bool_base.dart b/lib/src/generated/animation/keyframe_bool_base.dart deleted file mode 100644 index 9121e98..0000000 --- a/lib/src/generated/animation/keyframe_bool_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_bool_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameBoolBase extends InterpolatingKeyFrame { - static const int typeKey = 84; - @override - int get coreType => KeyFrameBoolBase.typeKey; - @override - Set get coreTypes => { - KeyFrameBoolBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 181. - static const int valuePropertyKey = 181; - static const bool valueInitialValue = false; - bool _value = valueInitialValue; - bool get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(bool value) { - if (_value == value) { - return; - } - bool from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameBoolBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/keyframe_callback_base.dart b/lib/src/generated/animation/keyframe_callback_base.dart deleted file mode 100644 index e195153..0000000 --- a/lib/src/generated/animation/keyframe_callback_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_callback_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/keyframe.dart'; - -abstract class KeyFrameCallbackBase extends KeyFrame { - static const int typeKey = 171; - @override - int get coreType => KeyFrameCallbackBase.typeKey; - @override - Set get coreTypes => - {KeyFrameCallbackBase.typeKey, KeyFrameBase.typeKey}; -} diff --git a/lib/src/generated/animation/keyframe_color_base.dart b/lib/src/generated/animation/keyframe_color_base.dart deleted file mode 100644 index 0126be5..0000000 --- a/lib/src/generated/animation/keyframe_color_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_color_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameColorBase extends InterpolatingKeyFrame { - static const int typeKey = 37; - @override - int get coreType => KeyFrameColorBase.typeKey; - @override - Set get coreTypes => { - KeyFrameColorBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 88. - static const int valuePropertyKey = 88; - static const int valueInitialValue = 0; - int _value = valueInitialValue; - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameColorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/keyframe_double_base.dart b/lib/src/generated/animation/keyframe_double_base.dart deleted file mode 100644 index 6f2eb19..0000000 --- a/lib/src/generated/animation/keyframe_double_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_double_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameDoubleBase extends InterpolatingKeyFrame { - static const int typeKey = 30; - @override - int get coreType => KeyFrameDoubleBase.typeKey; - @override - Set get coreTypes => { - KeyFrameDoubleBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 70. - static const int valuePropertyKey = 70; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameDoubleBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/keyframe_id_base.dart b/lib/src/generated/animation/keyframe_id_base.dart deleted file mode 100644 index 07377b7..0000000 --- a/lib/src/generated/animation/keyframe_id_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_id_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameIdBase extends InterpolatingKeyFrame { - static const int typeKey = 50; - @override - int get coreType => KeyFrameIdBase.typeKey; - @override - Set get coreTypes => { - KeyFrameIdBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 122. - static const int valuePropertyKey = 122; - static const int valueInitialValue = -1; - int _value = valueInitialValue; - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameIdBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/keyframe_interpolator_base.dart b/lib/src/generated/animation/keyframe_interpolator_base.dart deleted file mode 100644 index adffa58..0000000 --- a/lib/src/generated/animation/keyframe_interpolator_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_interpolator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class KeyFrameInterpolatorBase extends Core { - static const int typeKey = 175; - @override - int get coreType => KeyFrameInterpolatorBase.typeKey; - @override - Set get coreTypes => {KeyFrameInterpolatorBase.typeKey}; -} diff --git a/lib/src/generated/animation/keyframe_string_base.dart b/lib/src/generated/animation/keyframe_string_base.dart deleted file mode 100644 index e2ae9f3..0000000 --- a/lib/src/generated/animation/keyframe_string_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_string_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameStringBase extends InterpolatingKeyFrame { - static const int typeKey = 142; - @override - int get coreType => KeyFrameStringBase.typeKey; - @override - Set get coreTypes => { - KeyFrameStringBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 280. - static const int valuePropertyKey = 280; - static const String valueInitialValue = ''; - String _value = valueInitialValue; - String get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(String value) { - if (_value == value) { - return; - } - String from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameStringBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/keyframe_uint_base.dart b/lib/src/generated/animation/keyframe_uint_base.dart deleted file mode 100644 index 2a29c31..0000000 --- a/lib/src/generated/animation/keyframe_uint_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/keyframe_uint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; - -abstract class KeyFrameUintBase extends InterpolatingKeyFrame { - static const int typeKey = 450; - @override - int get coreType => KeyFrameUintBase.typeKey; - @override - Set get coreTypes => { - KeyFrameUintBase.typeKey, - InterpolatingKeyFrameBase.typeKey, - KeyFrameBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 631. - static const int valuePropertyKey = 631; - static const int valueInitialValue = 0; - int _value = valueInitialValue; - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is KeyFrameUintBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/layer_state_base.dart b/lib/src/generated/animation/layer_state_base.dart deleted file mode 100644 index 89b109b..0000000 --- a/lib/src/generated/animation/layer_state_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/layer_state_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart'; - -abstract class LayerStateBase extends StateMachineLayerComponent { - static const int typeKey = 60; - @override - int get coreType => LayerStateBase.typeKey; - @override - Set get coreTypes => - {LayerStateBase.typeKey, StateMachineLayerComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Flags field with key 536. - static const int flagsPropertyKey = 536; - static const int flagsInitialValue = 0; - int _flags = flagsInitialValue; - int get flags => _flags; - - /// Change the [_flags] field value. - /// [flagsChanged] will be invoked only if the field's value has changed. - set flags(int value) { - if (_flags == value) { - return; - } - int from = _flags; - _flags = value; - if (hasValidated) { - flagsChanged(from, value); - } - } - - void flagsChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is LayerStateBase) { - _flags = source._flags; - } - } -} diff --git a/lib/src/generated/animation/linear_animation_base.dart b/lib/src/generated/animation/linear_animation_base.dart deleted file mode 100644 index b4bde74..0000000 --- a/lib/src/generated/animation/linear_animation_base.dart +++ /dev/null @@ -1,225 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/linear_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/animation.dart'; - -abstract class LinearAnimationBase extends Animation { - static const int typeKey = 31; - @override - int get coreType => LinearAnimationBase.typeKey; - @override - Set get coreTypes => - {LinearAnimationBase.typeKey, AnimationBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Fps field with key 56. - static const int fpsPropertyKey = 56; - static const int fpsInitialValue = 60; - int _fps = fpsInitialValue; - - /// Frames per second used to quantize keyframe times to discrete values that - /// match this rate. - int get fps => _fps; - - /// Change the [_fps] field value. - /// [fpsChanged] will be invoked only if the field's value has changed. - set fps(int value) { - if (_fps == value) { - return; - } - int from = _fps; - _fps = value; - if (hasValidated) { - fpsChanged(from, value); - } - } - - void fpsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Duration field with key 57. - static const int durationPropertyKey = 57; - static const int durationInitialValue = 60; - int _duration = durationInitialValue; - - /// Duration expressed in number of frames. - int get duration => _duration; - - /// Change the [_duration] field value. - /// [durationChanged] will be invoked only if the field's value has changed. - set duration(int value) { - if (_duration == value) { - return; - } - int from = _duration; - _duration = value; - if (hasValidated) { - durationChanged(from, value); - } - } - - void durationChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Speed field with key 58. - static const int speedPropertyKey = 58; - static const double speedInitialValue = 1; - double _speed = speedInitialValue; - - /// Playback speed multiplier. - double get speed => _speed; - - /// Change the [_speed] field value. - /// [speedChanged] will be invoked only if the field's value has changed. - set speed(double value) { - if (_speed == value) { - return; - } - double from = _speed; - _speed = value; - if (hasValidated) { - speedChanged(from, value); - } - } - - void speedChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// LoopValue field with key 59. - static const int loopValuePropertyKey = 59; - static const int loopValueInitialValue = 0; - int _loopValue = loopValueInitialValue; - - /// Loop value option matches Loop enumeration. - int get loopValue => _loopValue; - - /// Change the [_loopValue] field value. - /// [loopValueChanged] will be invoked only if the field's value has changed. - set loopValue(int value) { - if (_loopValue == value) { - return; - } - int from = _loopValue; - _loopValue = value; - if (hasValidated) { - loopValueChanged(from, value); - } - } - - void loopValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// WorkStart field with key 60. - static const int workStartPropertyKey = 60; - static const int workStartInitialValue = -1; - int _workStart = workStartInitialValue; - - /// Start of the work area in frames. - int get workStart => _workStart; - - /// Change the [_workStart] field value. - /// [workStartChanged] will be invoked only if the field's value has changed. - set workStart(int value) { - if (_workStart == value) { - return; - } - int from = _workStart; - _workStart = value; - if (hasValidated) { - workStartChanged(from, value); - } - } - - void workStartChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// WorkEnd field with key 61. - static const int workEndPropertyKey = 61; - static const int workEndInitialValue = -1; - int _workEnd = workEndInitialValue; - - /// End of the work area in frames. - int get workEnd => _workEnd; - - /// Change the [_workEnd] field value. - /// [workEndChanged] will be invoked only if the field's value has changed. - set workEnd(int value) { - if (_workEnd == value) { - return; - } - int from = _workEnd; - _workEnd = value; - if (hasValidated) { - workEndChanged(from, value); - } - } - - void workEndChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// EnableWorkArea field with key 62. - static const int enableWorkAreaPropertyKey = 62; - static const bool enableWorkAreaInitialValue = false; - bool _enableWorkArea = enableWorkAreaInitialValue; - - /// Whether or not the work area is enabled. - bool get enableWorkArea => _enableWorkArea; - - /// Change the [_enableWorkArea] field value. - /// [enableWorkAreaChanged] will be invoked only if the field's value has - /// changed. - set enableWorkArea(bool value) { - if (_enableWorkArea == value) { - return; - } - bool from = _enableWorkArea; - _enableWorkArea = value; - if (hasValidated) { - enableWorkAreaChanged(from, value); - } - } - - void enableWorkAreaChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// Quantize field with key 376. - static const int quantizePropertyKey = 376; - static const bool quantizeInitialValue = false; - bool _quantize = quantizeInitialValue; - - /// Whether frames are quantized to desired frame rate or floating based on - /// runtime speed. - bool get quantize => _quantize; - - /// Change the [_quantize] field value. - /// [quantizeChanged] will be invoked only if the field's value has changed. - set quantize(bool value) { - if (_quantize == value) { - return; - } - bool from = _quantize; - _quantize = value; - if (hasValidated) { - quantizeChanged(from, value); - } - } - - void quantizeChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is LinearAnimationBase) { - _fps = source._fps; - _duration = source._duration; - _speed = source._speed; - _loopValue = source._loopValue; - _workStart = source._workStart; - _workEnd = source._workEnd; - _enableWorkArea = source._enableWorkArea; - _quantize = source._quantize; - } - } -} diff --git a/lib/src/generated/animation/listener_action_base.dart b/lib/src/generated/animation/listener_action_base.dart deleted file mode 100644 index aee2785..0000000 --- a/lib/src/generated/animation/listener_action_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_action_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class ListenerActionBase extends Core { - static const int typeKey = 125; - @override - int get coreType => ListenerActionBase.typeKey; - @override - Set get coreTypes => {ListenerActionBase.typeKey}; -} diff --git a/lib/src/generated/animation/listener_align_target_base.dart b/lib/src/generated/animation/listener_align_target_base.dart deleted file mode 100644 index f0dbb62..0000000 --- a/lib/src/generated/animation/listener_align_target_base.dart +++ /dev/null @@ -1,74 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_align_target_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/listener_action.dart'; - -abstract class ListenerAlignTargetBase extends ListenerAction { - static const int typeKey = 126; - @override - int get coreType => ListenerAlignTargetBase.typeKey; - @override - Set get coreTypes => - {ListenerAlignTargetBase.typeKey, ListenerActionBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// TargetId field with key 240. - static const int targetIdPropertyKey = 240; - static const int targetIdInitialValue = 0; - int _targetId = targetIdInitialValue; - - /// Identifier used to track the object use as a target fo this listener - /// action. - int get targetId => _targetId; - - /// Change the [_targetId] field value. - /// [targetIdChanged] will be invoked only if the field's value has changed. - set targetId(int value) { - if (_targetId == value) { - return; - } - int from = _targetId; - _targetId = value; - if (hasValidated) { - targetIdChanged(from, value); - } - } - - void targetIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PreserveOffset field with key 541. - static const int preserveOffsetPropertyKey = 541; - static const bool preserveOffsetInitialValue = false; - bool _preserveOffset = preserveOffsetInitialValue; - - /// Whether to preserve offset between mouse position and target position. - bool get preserveOffset => _preserveOffset; - - /// Change the [_preserveOffset] field value. - /// [preserveOffsetChanged] will be invoked only if the field's value has - /// changed. - set preserveOffset(bool value) { - if (_preserveOffset == value) { - return; - } - bool from = _preserveOffset; - _preserveOffset = value; - if (hasValidated) { - preserveOffsetChanged(from, value); - } - } - - void preserveOffsetChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ListenerAlignTargetBase) { - _targetId = source._targetId; - _preserveOffset = source._preserveOffset; - } - } -} diff --git a/lib/src/generated/animation/listener_bool_change_base.dart b/lib/src/generated/animation/listener_bool_change_base.dart deleted file mode 100644 index 33b476e..0000000 --- a/lib/src/generated/animation/listener_bool_change_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_bool_change_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/listener_action_base.dart'; -import 'package:rive/src/rive_core/animation/listener_input_change.dart'; - -abstract class ListenerBoolChangeBase extends ListenerInputChange { - static const int typeKey = 117; - @override - int get coreType => ListenerBoolChangeBase.typeKey; - @override - Set get coreTypes => { - ListenerBoolChangeBase.typeKey, - ListenerInputChangeBase.typeKey, - ListenerActionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 228. - static const int valuePropertyKey = 228; - static const int valueInitialValue = 1; - int _value = valueInitialValue; - - /// Value to set the input to when the listener occurs. - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ListenerBoolChangeBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/listener_fire_event_base.dart b/lib/src/generated/animation/listener_fire_event_base.dart deleted file mode 100644 index 478e07b..0000000 --- a/lib/src/generated/animation/listener_fire_event_base.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_fire_event_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/listener_action.dart'; - -abstract class ListenerFireEventBase extends ListenerAction { - static const int typeKey = 168; - @override - int get coreType => ListenerFireEventBase.typeKey; - @override - Set get coreTypes => - {ListenerFireEventBase.typeKey, ListenerActionBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// EventId field with key 389. - static const int eventIdPropertyKey = 389; - static const int eventIdInitialValue = -1; - int _eventId = eventIdInitialValue; - - /// Id of the Event referenced. - int get eventId => _eventId; - - /// Change the [_eventId] field value. - /// [eventIdChanged] will be invoked only if the field's value has changed. - set eventId(int value) { - if (_eventId == value) { - return; - } - int from = _eventId; - _eventId = value; - if (hasValidated) { - eventIdChanged(from, value); - } - } - - void eventIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ListenerFireEventBase) { - _eventId = source._eventId; - } - } -} diff --git a/lib/src/generated/animation/listener_input_change_base.dart b/lib/src/generated/animation/listener_input_change_base.dart deleted file mode 100644 index 90b8305..0000000 --- a/lib/src/generated/animation/listener_input_change_base.dart +++ /dev/null @@ -1,73 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_input_change_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/listener_action.dart'; - -abstract class ListenerInputChangeBase extends ListenerAction { - static const int typeKey = 116; - @override - int get coreType => ListenerInputChangeBase.typeKey; - @override - Set get coreTypes => - {ListenerInputChangeBase.typeKey, ListenerActionBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InputId field with key 227. - static const int inputIdPropertyKey = 227; - static const int inputIdInitialValue = -1; - int _inputId = inputIdInitialValue; - - /// Id of the StateMachineInput referenced. - int get inputId => _inputId; - - /// Change the [_inputId] field value. - /// [inputIdChanged] will be invoked only if the field's value has changed. - set inputId(int value) { - if (_inputId == value) { - return; - } - int from = _inputId; - _inputId = value; - if (hasValidated) { - inputIdChanged(from, value); - } - } - - void inputIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// NestedInputId field with key 400. - static const int nestedInputIdPropertyKey = 400; - static const int nestedInputIdInitialValue = -1; - int _nestedInputId = nestedInputIdInitialValue; - - /// Id of the NestedInput referenced if this is listening to a nested input. - int get nestedInputId => _nestedInputId; - - /// Change the [_nestedInputId] field value. - /// [nestedInputIdChanged] will be invoked only if the field's value has - /// changed. - set nestedInputId(int value) { - if (_nestedInputId == value) { - return; - } - int from = _nestedInputId; - _nestedInputId = value; - if (hasValidated) { - nestedInputIdChanged(from, value); - } - } - - void nestedInputIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ListenerInputChangeBase) { - _inputId = source._inputId; - _nestedInputId = source._nestedInputId; - } - } -} diff --git a/lib/src/generated/animation/listener_number_change_base.dart b/lib/src/generated/animation/listener_number_change_base.dart deleted file mode 100644 index 63f78c9..0000000 --- a/lib/src/generated/animation/listener_number_change_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_number_change_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/listener_action_base.dart'; -import 'package:rive/src/rive_core/animation/listener_input_change.dart'; - -abstract class ListenerNumberChangeBase extends ListenerInputChange { - static const int typeKey = 118; - @override - int get coreType => ListenerNumberChangeBase.typeKey; - @override - Set get coreTypes => { - ListenerNumberChangeBase.typeKey, - ListenerInputChangeBase.typeKey, - ListenerActionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 229. - static const int valuePropertyKey = 229; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - - /// Value to set the input to when the listener occurs. - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ListenerNumberChangeBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/listener_trigger_change_base.dart b/lib/src/generated/animation/listener_trigger_change_base.dart deleted file mode 100644 index 480c64d..0000000 --- a/lib/src/generated/animation/listener_trigger_change_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_trigger_change_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/listener_action_base.dart'; -import 'package:rive/src/rive_core/animation/listener_input_change.dart'; - -abstract class ListenerTriggerChangeBase extends ListenerInputChange { - static const int typeKey = 115; - @override - int get coreType => ListenerTriggerChangeBase.typeKey; - @override - Set get coreTypes => { - ListenerTriggerChangeBase.typeKey, - ListenerInputChangeBase.typeKey, - ListenerActionBase.typeKey - }; -} diff --git a/lib/src/generated/animation/listener_viewmodel_change_base.dart b/lib/src/generated/animation/listener_viewmodel_change_base.dart deleted file mode 100644 index 79cc025..0000000 --- a/lib/src/generated/animation/listener_viewmodel_change_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/listener_viewmodel_change_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/listener_action.dart'; - -abstract class ListenerViewModelChangeBase extends ListenerAction { - static const int typeKey = 487; - @override - int get coreType => ListenerViewModelChangeBase.typeKey; - @override - Set get coreTypes => - {ListenerViewModelChangeBase.typeKey, ListenerActionBase.typeKey}; -} diff --git a/lib/src/generated/animation/nested_bool_base.dart b/lib/src/generated/animation/nested_bool_base.dart deleted file mode 100644 index df58a6a..0000000 --- a/lib/src/generated/animation/nested_bool_base.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_bool_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; - -abstract class NestedBoolBase extends NestedInput { - static const int typeKey = 123; - @override - int get coreType => NestedBoolBase.typeKey; - @override - Set get coreTypes => - {NestedBoolBase.typeKey, NestedInputBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// NestedValue field with key 238. - static const int nestedValuePropertyKey = 238; - static const bool nestedValueInitialValue = false; - bool _nestedValue = nestedValueInitialValue; - bool get nestedValue => _nestedValue; - - /// Change the [_nestedValue] field value. - /// [nestedValueChanged] will be invoked only if the field's value has - /// changed. - set nestedValue(bool value) { - if (_nestedValue == value) { - return; - } - bool from = _nestedValue; - _nestedValue = value; - if (hasValidated) { - nestedValueChanged(from, value); - } - } - - void nestedValueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedBoolBase) { - _nestedValue = source._nestedValue; - } - } -} diff --git a/lib/src/generated/animation/nested_input_base.dart b/lib/src/generated/animation/nested_input_base.dart deleted file mode 100644 index 457b252..0000000 --- a/lib/src/generated/animation/nested_input_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_input_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class NestedInputBase extends Component { - static const int typeKey = 121; - @override - int get coreType => NestedInputBase.typeKey; - @override - Set get coreTypes => {NestedInputBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InputId field with key 237. - static const int inputIdPropertyKey = 237; - static const int inputIdInitialValue = -1; - int _inputId = inputIdInitialValue; - - /// Identifier used to track the actual backing state machine input. - int get inputId => _inputId; - - /// Change the [_inputId] field value. - /// [inputIdChanged] will be invoked only if the field's value has changed. - set inputId(int value) { - if (_inputId == value) { - return; - } - int from = _inputId; - _inputId = value; - if (hasValidated) { - inputIdChanged(from, value); - } - } - - void inputIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedInputBase) { - _inputId = source._inputId; - } - } -} diff --git a/lib/src/generated/animation/nested_linear_animation_base.dart b/lib/src/generated/animation/nested_linear_animation_base.dart deleted file mode 100644 index ba8e743..0000000 --- a/lib/src/generated/animation/nested_linear_animation_base.dart +++ /dev/null @@ -1,55 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_linear_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/nested_animation.dart'; - -abstract class NestedLinearAnimationBase - extends NestedAnimation { - static const int typeKey = 97; - @override - int get coreType => NestedLinearAnimationBase.typeKey; - @override - Set get coreTypes => { - NestedLinearAnimationBase.typeKey, - NestedAnimationBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Mix field with key 200. - static const int mixPropertyKey = 200; - static const double mixInitialValue = 1; - double _mix = mixInitialValue; - - /// Value to mix the animation in. - double get mix => _mix; - - /// Change the [_mix] field value. - /// [mixChanged] will be invoked only if the field's value has changed. - set mix(double value) { - if (_mix == value) { - return; - } - double from = _mix; - _mix = value; - if (hasValidated) { - mixChanged(from, value); - } - } - - void mixChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedLinearAnimationBase) { - _mix = source._mix; - } - } -} diff --git a/lib/src/generated/animation/nested_number_base.dart b/lib/src/generated/animation/nested_number_base.dart deleted file mode 100644 index 6164487..0000000 --- a/lib/src/generated/animation/nested_number_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; - -abstract class NestedNumberBase extends NestedInput { - static const int typeKey = 124; - @override - int get coreType => NestedNumberBase.typeKey; - @override - Set get coreTypes => { - NestedNumberBase.typeKey, - NestedInputBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// NestedValue field with key 239. - static const int nestedValuePropertyKey = 239; - static const double nestedValueInitialValue = 0; - double _nestedValue = nestedValueInitialValue; - double get nestedValue => _nestedValue; - - /// Change the [_nestedValue] field value. - /// [nestedValueChanged] will be invoked only if the field's value has - /// changed. - set nestedValue(double value) { - if (_nestedValue == value) { - return; - } - double from = _nestedValue; - _nestedValue = value; - if (hasValidated) { - nestedValueChanged(from, value); - } - } - - void nestedValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedNumberBase) { - _nestedValue = source._nestedValue; - } - } -} diff --git a/lib/src/generated/animation/nested_remap_animation_base.dart b/lib/src/generated/animation/nested_remap_animation_base.dart deleted file mode 100644 index a6001fe..0000000 --- a/lib/src/generated/animation/nested_remap_animation_base.dart +++ /dev/null @@ -1,55 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_remap_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/nested_animation_base.dart'; -import 'package:rive/src/rive_core/animation/nested_linear_animation.dart'; - -abstract class NestedRemapAnimationBase extends NestedLinearAnimation { - static const int typeKey = 98; - @override - int get coreType => NestedRemapAnimationBase.typeKey; - @override - Set get coreTypes => { - NestedRemapAnimationBase.typeKey, - NestedLinearAnimationBase.typeKey, - NestedAnimationBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Time field with key 202. - static const int timePropertyKey = 202; - static const double timeInitialValue = 0.0; - double _time = timeInitialValue; - - /// Time value in seconds for the nested linear animation. - double get time => _time; - - /// Change the [_time] field value. - /// [timeChanged] will be invoked only if the field's value has changed. - set time(double value) { - if (_time == value) { - return; - } - double from = _time; - _time = value; - if (hasValidated) { - timeChanged(from, value); - } - } - - void timeChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedRemapAnimationBase) { - _time = source._time; - } - } -} diff --git a/lib/src/generated/animation/nested_simple_animation_base.dart b/lib/src/generated/animation/nested_simple_animation_base.dart deleted file mode 100644 index 3efd76d..0000000 --- a/lib/src/generated/animation/nested_simple_animation_base.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_simple_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/nested_animation_base.dart'; -import 'package:rive/src/rive_core/animation/nested_linear_animation.dart'; - -abstract class NestedSimpleAnimationBase extends NestedLinearAnimation { - static const int typeKey = 96; - @override - int get coreType => NestedSimpleAnimationBase.typeKey; - @override - Set get coreTypes => { - NestedSimpleAnimationBase.typeKey, - NestedLinearAnimationBase.typeKey, - NestedAnimationBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Speed field with key 199. - static const int speedPropertyKey = 199; - static const double speedInitialValue = 1; - double _speed = speedInitialValue; - - /// Speed to play the nested animation at. - double get speed => _speed; - - /// Change the [_speed] field value. - /// [speedChanged] will be invoked only if the field's value has changed. - set speed(double value) { - if (_speed == value) { - return; - } - double from = _speed; - _speed = value; - if (hasValidated) { - speedChanged(from, value); - } - } - - void speedChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// IsPlaying field with key 201. - static const int isPlayingPropertyKey = 201; - static const bool isPlayingInitialValue = false; - bool _isPlaying = isPlayingInitialValue; - - /// Enumerated backing value for playback state. - bool get isPlaying => _isPlaying; - - /// Change the [_isPlaying] field value. - /// [isPlayingChanged] will be invoked only if the field's value has changed. - set isPlaying(bool value) { - if (_isPlaying == value) { - return; - } - bool from = _isPlaying; - _isPlaying = value; - if (hasValidated) { - isPlayingChanged(from, value); - } - } - - void isPlayingChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedSimpleAnimationBase) { - _speed = source._speed; - _isPlaying = source._isPlaying; - } - } -} diff --git a/lib/src/generated/animation/nested_state_machine_base.dart b/lib/src/generated/animation/nested_state_machine_base.dart deleted file mode 100644 index 25d744f..0000000 --- a/lib/src/generated/animation/nested_state_machine_base.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_state_machine_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/nested_animation.dart'; - -abstract class NestedStateMachineBase extends NestedAnimation { - static const int typeKey = 95; - @override - int get coreType => NestedStateMachineBase.typeKey; - @override - Set get coreTypes => { - NestedStateMachineBase.typeKey, - NestedAnimationBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/nested_trigger_base.dart b/lib/src/generated/animation/nested_trigger_base.dart deleted file mode 100644 index 7be67f3..0000000 --- a/lib/src/generated/animation/nested_trigger_base.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/nested_trigger_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; - -abstract class NestedTriggerBase extends NestedInput { - static const int typeKey = 122; - @override - int get coreType => NestedTriggerBase.typeKey; - @override - Set get coreTypes => { - NestedTriggerBase.typeKey, - NestedInputBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Fire field with key 401. - static const int firePropertyKey = 401; - void fire(CallbackData value); -} diff --git a/lib/src/generated/animation/state_machine_base.dart b/lib/src/generated/animation/state_machine_base.dart deleted file mode 100644 index 8ec3b17..0000000 --- a/lib/src/generated/animation/state_machine_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/animation.dart'; - -abstract class StateMachineBase extends Animation { - static const int typeKey = 53; - @override - int get coreType => StateMachineBase.typeKey; - @override - Set get coreTypes => {StateMachineBase.typeKey, AnimationBase.typeKey}; -} diff --git a/lib/src/generated/animation/state_machine_bool_base.dart b/lib/src/generated/animation/state_machine_bool_base.dart deleted file mode 100644 index 4552456..0000000 --- a/lib/src/generated/animation/state_machine_bool_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_bool_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; - -abstract class StateMachineBoolBase extends StateMachineInput { - static const int typeKey = 59; - @override - int get coreType => StateMachineBoolBase.typeKey; - @override - Set get coreTypes => { - StateMachineBoolBase.typeKey, - StateMachineInputBase.typeKey, - StateMachineComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 141. - static const int valuePropertyKey = 141; - static const bool valueInitialValue = false; - bool _value = valueInitialValue; - bool get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(bool value) { - if (_value == value) { - return; - } - bool from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateMachineBoolBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/state_machine_component_base.dart b/lib/src/generated/animation/state_machine_component_base.dart deleted file mode 100644 index 26f4fdb..0000000 --- a/lib/src/generated/animation/state_machine_component_base.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class StateMachineComponentBase - extends Core { - static const int typeKey = 54; - @override - int get coreType => StateMachineComponentBase.typeKey; - @override - Set get coreTypes => {StateMachineComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 138. - static const int namePropertyKey = 138; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Non-unique identifier, used to give friendly names to state machine - /// components (like layers or inputs). - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateMachineComponentBase) { - _name = source._name; - } - } -} diff --git a/lib/src/generated/animation/state_machine_double_base.dart b/lib/src/generated/animation/state_machine_double_base.dart deleted file mode 100644 index 436168e..0000000 --- a/lib/src/generated/animation/state_machine_double_base.dart +++ /dev/null @@ -1,40 +0,0 @@ -/// Core automatically generated -/// lib/src/generated/animation/state_machine_double_base.dart. -/// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; - -abstract class StateMachineDoubleBase extends StateMachineInput { - static const int typeKey = 56; - @override - int get coreType => StateMachineDoubleBase.typeKey; - @override - Set get coreTypes => { - StateMachineDoubleBase.typeKey, - StateMachineInputBase.typeKey, - StateMachineComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 140. - static const double valueInitialValue = 0; - double _value = valueInitialValue; - static const int valuePropertyKey = 140; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); -} diff --git a/lib/src/generated/animation/state_machine_event_base.dart b/lib/src/generated/animation/state_machine_event_base.dart deleted file mode 100644 index 8acdd29..0000000 --- a/lib/src/generated/animation/state_machine_event_base.dart +++ /dev/null @@ -1,70 +0,0 @@ -/// Core automatically generated -/// lib/src/generated/animation/state_machine_event_base.dart. -/// Do not modify manually. - -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -abstract class StateMachineEventBase extends StateMachineComponent { - static const int typeKey = 114; - @override - int get coreType => StateMachineEventBase.typeKey; - @override - Set get coreTypes => - {StateMachineEventBase.typeKey, StateMachineComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// TargetId field with key 224. - static const int targetIdInitialValue = 0; - int _targetId = targetIdInitialValue; - static const int targetIdPropertyKey = 224; - - /// Identifier used to track the object use as a target fo this event. - int get targetId => _targetId; - - /// Change the [_targetId] field value. - /// [targetIdChanged] will be invoked only if the field's value has changed. - set targetId(int value) { - if (_targetId == value) { - return; - } - int from = _targetId; - _targetId = value; - if (hasValidated) { - targetIdChanged(from, value); - } - } - - void targetIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// EventTypeValue field with key 225. - static const int eventTypeValueInitialValue = 0; - int _eventTypeValue = eventTypeValueInitialValue; - static const int eventTypeValuePropertyKey = 225; - - /// Event type (hover, click, etc). - int get eventTypeValue => _eventTypeValue; - - /// Change the [_eventTypeValue] field value. - /// [eventTypeValueChanged] will be invoked only if the field's value has - /// changed. - set eventTypeValue(int value) { - if (_eventTypeValue == value) { - return; - } - int from = _eventTypeValue; - _eventTypeValue = value; - if (hasValidated) { - eventTypeValueChanged(from, value); - } - } - - void eventTypeValueChanged(int from, int to); - - @override - void copy(covariant StateMachineEventBase source) { - super.copy(source); - _targetId = source._targetId; - _eventTypeValue = source._eventTypeValue; - } -} diff --git a/lib/src/generated/animation/state_machine_fire_event_base.dart b/lib/src/generated/animation/state_machine_fire_event_base.dart deleted file mode 100644 index 042c42a..0000000 --- a/lib/src/generated/animation/state_machine_fire_event_base.dart +++ /dev/null @@ -1,72 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_fire_event_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class StateMachineFireEventBase - extends Core { - static const int typeKey = 169; - @override - int get coreType => StateMachineFireEventBase.typeKey; - @override - Set get coreTypes => {StateMachineFireEventBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// EventId field with key 392. - static const int eventIdPropertyKey = 392; - static const int eventIdInitialValue = -1; - int _eventId = eventIdInitialValue; - - /// Id of the Event referenced. - int get eventId => _eventId; - - /// Change the [_eventId] field value. - /// [eventIdChanged] will be invoked only if the field's value has changed. - set eventId(int value) { - if (_eventId == value) { - return; - } - int from = _eventId; - _eventId = value; - if (hasValidated) { - eventIdChanged(from, value); - } - } - - void eventIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OccursValue field with key 393. - static const int occursValuePropertyKey = 393; - static const int occursValueInitialValue = 0; - int _occursValue = occursValueInitialValue; - - /// When the event fires. - int get occursValue => _occursValue; - - /// Change the [_occursValue] field value. - /// [occursValueChanged] will be invoked only if the field's value has - /// changed. - set occursValue(int value) { - if (_occursValue == value) { - return; - } - int from = _occursValue; - _occursValue = value; - if (hasValidated) { - occursValueChanged(from, value); - } - } - - void occursValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateMachineFireEventBase) { - _eventId = source._eventId; - _occursValue = source._occursValue; - } - } -} diff --git a/lib/src/generated/animation/state_machine_input_base.dart b/lib/src/generated/animation/state_machine_input_base.dart deleted file mode 100644 index b4e32ac..0000000 --- a/lib/src/generated/animation/state_machine_input_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_input_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -abstract class StateMachineInputBase extends StateMachineComponent { - static const int typeKey = 55; - @override - int get coreType => StateMachineInputBase.typeKey; - @override - Set get coreTypes => - {StateMachineInputBase.typeKey, StateMachineComponentBase.typeKey}; -} diff --git a/lib/src/generated/animation/state_machine_layer_base.dart b/lib/src/generated/animation/state_machine_layer_base.dart deleted file mode 100644 index 87ae9f3..0000000 --- a/lib/src/generated/animation/state_machine_layer_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_layer_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -abstract class StateMachineLayerBase extends StateMachineComponent { - static const int typeKey = 57; - @override - int get coreType => StateMachineLayerBase.typeKey; - @override - Set get coreTypes => - {StateMachineLayerBase.typeKey, StateMachineComponentBase.typeKey}; -} diff --git a/lib/src/generated/animation/state_machine_layer_component_base.dart b/lib/src/generated/animation/state_machine_layer_component_base.dart deleted file mode 100644 index 6bcfe32..0000000 --- a/lib/src/generated/animation/state_machine_layer_component_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_layer_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class StateMachineLayerComponentBase - extends Core { - static const int typeKey = 66; - @override - int get coreType => StateMachineLayerComponentBase.typeKey; - @override - Set get coreTypes => {StateMachineLayerComponentBase.typeKey}; -} diff --git a/lib/src/generated/animation/state_machine_listener_base.dart b/lib/src/generated/animation/state_machine_listener_base.dart deleted file mode 100644 index a36b624..0000000 --- a/lib/src/generated/animation/state_machine_listener_base.dart +++ /dev/null @@ -1,98 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_listener_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -abstract class StateMachineListenerBase extends StateMachineComponent { - static const int typeKey = 114; - @override - int get coreType => StateMachineListenerBase.typeKey; - @override - Set get coreTypes => - {StateMachineListenerBase.typeKey, StateMachineComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// TargetId field with key 224. - static const int targetIdPropertyKey = 224; - static const int targetIdInitialValue = 0; - int _targetId = targetIdInitialValue; - - /// Identifier used to track the object use as a target for this listener. - int get targetId => _targetId; - - /// Change the [_targetId] field value. - /// [targetIdChanged] will be invoked only if the field's value has changed. - set targetId(int value) { - if (_targetId == value) { - return; - } - int from = _targetId; - _targetId = value; - if (hasValidated) { - targetIdChanged(from, value); - } - } - - void targetIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ListenerTypeValue field with key 225. - static const int listenerTypeValuePropertyKey = 225; - static const int listenerTypeValueInitialValue = 0; - int _listenerTypeValue = listenerTypeValueInitialValue; - - /// Listener type (hover, click, etc). - int get listenerTypeValue => _listenerTypeValue; - - /// Change the [_listenerTypeValue] field value. - /// [listenerTypeValueChanged] will be invoked only if the field's value has - /// changed. - set listenerTypeValue(int value) { - if (_listenerTypeValue == value) { - return; - } - int from = _listenerTypeValue; - _listenerTypeValue = value; - if (hasValidated) { - listenerTypeValueChanged(from, value); - } - } - - void listenerTypeValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// EventId field with key 399. - static const int eventIdPropertyKey = 399; - static const int eventIdInitialValue = -1; - int _eventId = eventIdInitialValue; - - /// Event id for the associated event, if listenerType is event - int get eventId => _eventId; - - /// Change the [_eventId] field value. - /// [eventIdChanged] will be invoked only if the field's value has changed. - set eventId(int value) { - if (_eventId == value) { - return; - } - int from = _eventId; - _eventId = value; - if (hasValidated) { - eventIdChanged(from, value); - } - } - - void eventIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateMachineListenerBase) { - _targetId = source._targetId; - _listenerTypeValue = source._listenerTypeValue; - _eventId = source._eventId; - } - } -} diff --git a/lib/src/generated/animation/state_machine_number_base.dart b/lib/src/generated/animation/state_machine_number_base.dart deleted file mode 100644 index 0abdfdd..0000000 --- a/lib/src/generated/animation/state_machine_number_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; - -abstract class StateMachineNumberBase extends StateMachineInput { - static const int typeKey = 56; - @override - int get coreType => StateMachineNumberBase.typeKey; - @override - Set get coreTypes => { - StateMachineNumberBase.typeKey, - StateMachineInputBase.typeKey, - StateMachineComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 140. - static const int valuePropertyKey = 140; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateMachineNumberBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/state_machine_trigger_base.dart b/lib/src/generated/animation/state_machine_trigger_base.dart deleted file mode 100644 index 4728036..0000000 --- a/lib/src/generated/animation/state_machine_trigger_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_machine_trigger_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; - -abstract class StateMachineTriggerBase extends StateMachineInput { - static const int typeKey = 58; - @override - int get coreType => StateMachineTriggerBase.typeKey; - @override - Set get coreTypes => { - StateMachineTriggerBase.typeKey, - StateMachineInputBase.typeKey, - StateMachineComponentBase.typeKey - }; -} diff --git a/lib/src/generated/animation/state_transition_base.dart b/lib/src/generated/animation/state_transition_base.dart deleted file mode 100644 index c34d936..0000000 --- a/lib/src/generated/animation/state_transition_base.dart +++ /dev/null @@ -1,202 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/state_transition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart'; - -abstract class StateTransitionBase extends StateMachineLayerComponent { - static const int typeKey = 65; - @override - int get coreType => StateTransitionBase.typeKey; - @override - Set get coreTypes => - {StateTransitionBase.typeKey, StateMachineLayerComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// StateToId field with key 151. - static const int stateToIdPropertyKey = 151; - static const int stateToIdInitialValue = -1; - int _stateToId = stateToIdInitialValue; - - /// Id of the state this transition originates from. - int get stateToId => _stateToId; - - /// Change the [_stateToId] field value. - /// [stateToIdChanged] will be invoked only if the field's value has changed. - set stateToId(int value) { - if (_stateToId == value) { - return; - } - int from = _stateToId; - _stateToId = value; - if (hasValidated) { - stateToIdChanged(from, value); - } - } - - void stateToIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Flags field with key 152. - static const int flagsPropertyKey = 152; - static const int flagsInitialValue = 0; - int _flags = flagsInitialValue; - int get flags => _flags; - - /// Change the [_flags] field value. - /// [flagsChanged] will be invoked only if the field's value has changed. - set flags(int value) { - if (_flags == value) { - return; - } - int from = _flags; - _flags = value; - if (hasValidated) { - flagsChanged(from, value); - } - } - - void flagsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Duration field with key 158. - static const int durationPropertyKey = 158; - static const int durationInitialValue = 0; - int _duration = durationInitialValue; - - /// Duration of the trasition (mix time) in milliseconds or percentage (0-100) - /// based on flags. - int get duration => _duration; - - /// Change the [_duration] field value. - /// [durationChanged] will be invoked only if the field's value has changed. - set duration(int value) { - if (_duration == value) { - return; - } - int from = _duration; - _duration = value; - if (hasValidated) { - durationChanged(from, value); - } - } - - void durationChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ExitTime field with key 160. - static const int exitTimePropertyKey = 160; - static const int exitTimeInitialValue = 0; - int _exitTime = exitTimeInitialValue; - - /// Duration in milliseconds that must elapse before allowing the state to - /// change. If the flags mark this property as being percentage based, the - /// value is in 0-100% of the outgoing animation's duration - int get exitTime => _exitTime; - - /// Change the [_exitTime] field value. - /// [exitTimeChanged] will be invoked only if the field's value has changed. - set exitTime(int value) { - if (_exitTime == value) { - return; - } - int from = _exitTime; - _exitTime = value; - if (hasValidated) { - exitTimeChanged(from, value); - } - } - - void exitTimeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolationType field with key 349. - static const int interpolationTypePropertyKey = 349; - static const int interpolationTypeInitialValue = 1; - int _interpolationType = interpolationTypeInitialValue; - - /// The type of interpolation index in Interpolation applied to this state - /// transition ('linear' by default). - int get interpolationType => _interpolationType; - - /// Change the [_interpolationType] field value. - /// [interpolationTypeChanged] will be invoked only if the field's value has - /// changed. - set interpolationType(int value) { - if (_interpolationType == value) { - return; - } - int from = _interpolationType; - _interpolationType = value; - if (hasValidated) { - interpolationTypeChanged(from, value); - } - } - - void interpolationTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolatorId field with key 350. - static const int interpolatorIdPropertyKey = 350; - static const int interpolatorIdInitialValue = -1; - int _interpolatorId = interpolatorIdInitialValue; - - /// The id of the custom interpolator used when interpolation is Cubic. - int get interpolatorId => _interpolatorId; - - /// Change the [_interpolatorId] field value. - /// [interpolatorIdChanged] will be invoked only if the field's value has - /// changed. - set interpolatorId(int value) { - if (_interpolatorId == value) { - return; - } - int from = _interpolatorId; - _interpolatorId = value; - if (hasValidated) { - interpolatorIdChanged(from, value); - } - } - - void interpolatorIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// RandomWeight field with key 537. - static const int randomWeightPropertyKey = 537; - static const int randomWeightInitialValue = 1; - int _randomWeight = randomWeightInitialValue; - - /// Weight of the transition in the overall random options - int get randomWeight => _randomWeight; - - /// Change the [_randomWeight] field value. - /// [randomWeightChanged] will be invoked only if the field's value has - /// changed. - set randomWeight(int value) { - if (_randomWeight == value) { - return; - } - int from = _randomWeight; - _randomWeight = value; - if (hasValidated) { - randomWeightChanged(from, value); - } - } - - void randomWeightChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StateTransitionBase) { - _stateToId = source._stateToId; - _flags = source._flags; - _duration = source._duration; - _exitTime = source._exitTime; - _interpolationType = source._interpolationType; - _interpolatorId = source._interpolatorId; - _randomWeight = source._randomWeight; - } - } -} diff --git a/lib/src/generated/animation/transition_artboard_condition_base.dart b/lib/src/generated/animation/transition_artboard_condition_base.dart deleted file mode 100644 index 0a7b2d4..0000000 --- a/lib/src/generated/animation/transition_artboard_condition_base.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_artboard_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_viewmodel_condition.dart'; - -abstract class TransitionArtboardConditionBase - extends TransitionViewModelCondition { - static const int typeKey = 497; - @override - int get coreType => TransitionArtboardConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionArtboardConditionBase.typeKey, - TransitionViewModelConditionBase.typeKey, - TransitionConditionBase.typeKey - }; -} diff --git a/lib/src/generated/animation/transition_bool_condition_base.dart b/lib/src/generated/animation/transition_bool_condition_base.dart deleted file mode 100644 index e9bcc13..0000000 --- a/lib/src/generated/animation/transition_bool_condition_base.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_bool_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/generated/animation/transition_input_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_condition.dart'; - -abstract class TransitionBoolConditionBase extends TransitionValueCondition { - static const int typeKey = 71; - @override - int get coreType => TransitionBoolConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionBoolConditionBase.typeKey, - TransitionValueConditionBase.typeKey, - TransitionInputConditionBase.typeKey, - TransitionConditionBase.typeKey - }; -} diff --git a/lib/src/generated/animation/transition_comparator_base.dart b/lib/src/generated/animation/transition_comparator_base.dart deleted file mode 100644 index 9c6894f..0000000 --- a/lib/src/generated/animation/transition_comparator_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class TransitionComparatorBase extends Core { - static const int typeKey = 477; - @override - int get coreType => TransitionComparatorBase.typeKey; - @override - Set get coreTypes => {TransitionComparatorBase.typeKey}; -} diff --git a/lib/src/generated/animation/transition_condition_base.dart b/lib/src/generated/animation/transition_condition_base.dart deleted file mode 100644 index a6ffede..0000000 --- a/lib/src/generated/animation/transition_condition_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class TransitionConditionBase extends Core { - static const int typeKey = 476; - @override - int get coreType => TransitionConditionBase.typeKey; - @override - Set get coreTypes => {TransitionConditionBase.typeKey}; -} diff --git a/lib/src/generated/animation/transition_double_condition_base.dart b/lib/src/generated/animation/transition_double_condition_base.dart deleted file mode 100644 index 6a483f2..0000000 --- a/lib/src/generated/animation/transition_double_condition_base.dart +++ /dev/null @@ -1,40 +0,0 @@ -/// Core automatically generated -/// lib/src/generated/animation/transition_double_condition_base.dart. -/// Do not modify manually. - -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_condition.dart'; - -abstract class TransitionDoubleConditionBase extends TransitionValueCondition { - static const int typeKey = 70; - @override - int get coreType => TransitionDoubleConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionDoubleConditionBase.typeKey, - TransitionValueConditionBase.typeKey, - TransitionConditionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 157. - static const double valueInitialValue = 0; - double _value = valueInitialValue; - static const int valuePropertyKey = 157; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); -} diff --git a/lib/src/generated/animation/transition_input_condition_base.dart b/lib/src/generated/animation/transition_input_condition_base.dart deleted file mode 100644 index 9026c40..0000000 --- a/lib/src/generated/animation/transition_input_condition_base.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_input_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -abstract class TransitionInputConditionBase extends TransitionCondition { - static const int typeKey = 67; - @override - int get coreType => TransitionInputConditionBase.typeKey; - @override - Set get coreTypes => - {TransitionInputConditionBase.typeKey, TransitionConditionBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InputId field with key 155. - static const int inputIdPropertyKey = 155; - static const int inputIdInitialValue = -1; - int _inputId = inputIdInitialValue; - - /// Id of the StateMachineInput referenced. - int get inputId => _inputId; - - /// Change the [_inputId] field value. - /// [inputIdChanged] will be invoked only if the field's value has changed. - set inputId(int value) { - if (_inputId == value) { - return; - } - int from = _inputId; - _inputId = value; - if (hasValidated) { - inputIdChanged(from, value); - } - } - - void inputIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionInputConditionBase) { - _inputId = source._inputId; - } - } -} diff --git a/lib/src/generated/animation/transition_number_condition_base.dart b/lib/src/generated/animation/transition_number_condition_base.dart deleted file mode 100644 index 7699a91..0000000 --- a/lib/src/generated/animation/transition_number_condition_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_number_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/generated/animation/transition_input_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_condition.dart'; - -abstract class TransitionNumberConditionBase extends TransitionValueCondition { - static const int typeKey = 70; - @override - int get coreType => TransitionNumberConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionNumberConditionBase.typeKey, - TransitionValueConditionBase.typeKey, - TransitionInputConditionBase.typeKey, - TransitionConditionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 157. - static const int valuePropertyKey = 157; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionNumberConditionBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_property_artboard_comparator_base.dart b/lib/src/generated/animation/transition_property_artboard_comparator_base.dart deleted file mode 100644 index fa45621..0000000 --- a/lib/src/generated/animation/transition_property_artboard_comparator_base.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Core automatically generated -// nullnull -// t. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_property_comparator.dart'; - -abstract class TransitionPropertyArtboardComparatorBase - extends TransitionPropertyComparator { - static const int typeKey = 496; - @override - int get coreType => TransitionPropertyArtboardComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionPropertyArtboardComparatorBase.typeKey, - TransitionPropertyComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyType field with key 677. - static const int propertyTypePropertyKey = 677; - static const int propertyTypeInitialValue = 0; - int _propertyType = propertyTypeInitialValue; - - /// Integer representation of the artboard's property used for condition - int get propertyType => _propertyType; - - /// Change the [_propertyType] field value. - /// [propertyTypeChanged] will be invoked only if the field's value has - /// changed. - set propertyType(int value) { - if (_propertyType == value) { - return; - } - int from = _propertyType; - _propertyType = value; - if (hasValidated) { - propertyTypeChanged(from, value); - } - } - - void propertyTypeChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionPropertyArtboardComparatorBase) { - _propertyType = source._propertyType; - } - } -} diff --git a/lib/src/generated/animation/transition_property_comparator_base.dart b/lib/src/generated/animation/transition_property_comparator_base.dart deleted file mode 100644 index 9d0567a..0000000 --- a/lib/src/generated/animation/transition_property_comparator_base.dart +++ /dev/null @@ -1,16 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_property_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; - -abstract class TransitionPropertyComparatorBase extends TransitionComparator { - static const int typeKey = 478; - @override - int get coreType => TransitionPropertyComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionPropertyComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; -} diff --git a/lib/src/generated/animation/transition_property_viewmodel_comparator_base.dart b/lib/src/generated/animation/transition_property_viewmodel_comparator_base.dart deleted file mode 100644 index 4e3316d..0000000 --- a/lib/src/generated/animation/transition_property_viewmodel_comparator_base.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Core automatically generated -// nullnull -// rt. -// Do not modify manually. - -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_property_comparator.dart'; - -abstract class TransitionPropertyViewModelComparatorBase - extends TransitionPropertyComparator { - static const int typeKey = 479; - @override - int get coreType => TransitionPropertyViewModelComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionPropertyViewModelComparatorBase.typeKey, - TransitionPropertyComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; -} diff --git a/lib/src/generated/animation/transition_trigger_condition_base.dart b/lib/src/generated/animation/transition_trigger_condition_base.dart deleted file mode 100644 index d8a3eea..0000000 --- a/lib/src/generated/animation/transition_trigger_condition_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_trigger_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_input_condition.dart'; - -abstract class TransitionTriggerConditionBase extends TransitionInputCondition { - static const int typeKey = 68; - @override - int get coreType => TransitionTriggerConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionTriggerConditionBase.typeKey, - TransitionInputConditionBase.typeKey, - TransitionConditionBase.typeKey - }; -} diff --git a/lib/src/generated/animation/transition_value_boolean_comparator_base.dart b/lib/src/generated/animation/transition_value_boolean_comparator_base.dart deleted file mode 100644 index cdf36ad..0000000 --- a/lib/src/generated/animation/transition_value_boolean_comparator_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_boolean_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_comparator.dart'; - -abstract class TransitionValueBooleanComparatorBase - extends TransitionValueComparator { - static const int typeKey = 481; - @override - int get coreType => TransitionValueBooleanComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionValueBooleanComparatorBase.typeKey, - TransitionValueComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 647. - static const int valuePropertyKey = 647; - static const bool valueInitialValue = false; - bool _value = valueInitialValue; - bool get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(bool value) { - if (_value == value) { - return; - } - bool from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueBooleanComparatorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_value_color_comparator_base.dart b/lib/src/generated/animation/transition_value_color_comparator_base.dart deleted file mode 100644 index 57da2e7..0000000 --- a/lib/src/generated/animation/transition_value_color_comparator_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_color_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_comparator.dart'; - -abstract class TransitionValueColorComparatorBase - extends TransitionValueComparator { - static const int typeKey = 483; - @override - int get coreType => TransitionValueColorComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionValueColorComparatorBase.typeKey, - TransitionValueComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 651. - static const int valuePropertyKey = 651; - static const int valueInitialValue = 0xFF1D1D1D; - int _value = valueInitialValue; - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueColorComparatorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_value_comparator_base.dart b/lib/src/generated/animation/transition_value_comparator_base.dart deleted file mode 100644 index ab64ed7..0000000 --- a/lib/src/generated/animation/transition_value_comparator_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; - -abstract class TransitionValueComparatorBase extends TransitionComparator { - static const int typeKey = 480; - @override - int get coreType => TransitionValueComparatorBase.typeKey; - @override - Set get coreTypes => - {TransitionValueComparatorBase.typeKey, TransitionComparatorBase.typeKey}; -} diff --git a/lib/src/generated/animation/transition_value_condition_base.dart b/lib/src/generated/animation/transition_value_condition_base.dart deleted file mode 100644 index 23c0288..0000000 --- a/lib/src/generated/animation/transition_value_condition_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_input_condition.dart'; - -abstract class TransitionValueConditionBase extends TransitionInputCondition { - static const int typeKey = 69; - @override - int get coreType => TransitionValueConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionValueConditionBase.typeKey, - TransitionInputConditionBase.typeKey, - TransitionConditionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// OpValue field with key 156. - static const int opValuePropertyKey = 156; - static const int opValueInitialValue = 0; - int _opValue = opValueInitialValue; - - /// Integer representation of the StateMachineOp enum. - int get opValue => _opValue; - - /// Change the [_opValue] field value. - /// [opValueChanged] will be invoked only if the field's value has changed. - set opValue(int value) { - if (_opValue == value) { - return; - } - int from = _opValue; - _opValue = value; - if (hasValidated) { - opValueChanged(from, value); - } - } - - void opValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueConditionBase) { - _opValue = source._opValue; - } - } -} diff --git a/lib/src/generated/animation/transition_value_enum_comparator_base.dart b/lib/src/generated/animation/transition_value_enum_comparator_base.dart deleted file mode 100644 index 75a1c2b..0000000 --- a/lib/src/generated/animation/transition_value_enum_comparator_base.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_enum_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_comparator.dart'; - -abstract class TransitionValueEnumComparatorBase - extends TransitionValueComparator { - static const int typeKey = 485; - @override - int get coreType => TransitionValueEnumComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionValueEnumComparatorBase.typeKey, - TransitionValueComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 653. - static const int valuePropertyKey = 653; - static const int valueInitialValue = -1; - int _value = valueInitialValue; - - /// The id of the enum to compare the condition to - int get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(int value) { - if (_value == value) { - return; - } - int from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueEnumComparatorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_value_number_comparator_base.dart b/lib/src/generated/animation/transition_value_number_comparator_base.dart deleted file mode 100644 index 12ef97d..0000000 --- a/lib/src/generated/animation/transition_value_number_comparator_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_number_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_comparator.dart'; - -abstract class TransitionValueNumberComparatorBase - extends TransitionValueComparator { - static const int typeKey = 484; - @override - int get coreType => TransitionValueNumberComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionValueNumberComparatorBase.typeKey, - TransitionValueComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 652. - static const int valuePropertyKey = 652; - static const double valueInitialValue = 0; - double _value = valueInitialValue; - double get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(double value) { - if (_value == value) { - return; - } - double from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueNumberComparatorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_value_string_comparator_base.dart b/lib/src/generated/animation/transition_value_string_comparator_base.dart deleted file mode 100644 index e035d49..0000000 --- a/lib/src/generated/animation/transition_value_string_comparator_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_value_string_comparator_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_value_comparator.dart'; - -abstract class TransitionValueStringComparatorBase - extends TransitionValueComparator { - static const int typeKey = 486; - @override - int get coreType => TransitionValueStringComparatorBase.typeKey; - @override - Set get coreTypes => { - TransitionValueStringComparatorBase.typeKey, - TransitionValueComparatorBase.typeKey, - TransitionComparatorBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Value field with key 654. - static const int valuePropertyKey = 654; - static const String valueInitialValue = ''; - String _value = valueInitialValue; - String get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(String value) { - if (_value == value) { - return; - } - String from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionValueStringComparatorBase) { - _value = source._value; - } - } -} diff --git a/lib/src/generated/animation/transition_viewmodel_condition_base.dart b/lib/src/generated/animation/transition_viewmodel_condition_base.dart deleted file mode 100644 index f001748..0000000 --- a/lib/src/generated/animation/transition_viewmodel_condition_base.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Core automatically generated -// lib/src/generated/animation/transition_viewmodel_condition_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -abstract class TransitionViewModelConditionBase extends TransitionCondition { - static const int typeKey = 482; - @override - int get coreType => TransitionViewModelConditionBase.typeKey; - @override - Set get coreTypes => { - TransitionViewModelConditionBase.typeKey, - TransitionConditionBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// LeftComparatorId field with key 648. - static const int leftComparatorIdPropertyKey = 648; - static const int leftComparatorIdInitialValue = -1; - int _leftComparatorId = leftComparatorIdInitialValue; - - /// The id of the left comaprand to use for this condition - int get leftComparatorId => _leftComparatorId; - - /// Change the [_leftComparatorId] field value. - /// [leftComparatorIdChanged] will be invoked only if the field's value has - /// changed. - set leftComparatorId(int value) { - if (_leftComparatorId == value) { - return; - } - int from = _leftComparatorId; - _leftComparatorId = value; - if (hasValidated) { - leftComparatorIdChanged(from, value); - } - } - - void leftComparatorIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// RightComparatorId field with key 649. - static const int rightComparatorIdPropertyKey = 649; - static const int rightComparatorIdInitialValue = -1; - int _rightComparatorId = rightComparatorIdInitialValue; - - /// The id of the right comaprand to use for this condition - int get rightComparatorId => _rightComparatorId; - - /// Change the [_rightComparatorId] field value. - /// [rightComparatorIdChanged] will be invoked only if the field's value has - /// changed. - set rightComparatorId(int value) { - if (_rightComparatorId == value) { - return; - } - int from = _rightComparatorId; - _rightComparatorId = value; - if (hasValidated) { - rightComparatorIdChanged(from, value); - } - } - - void rightComparatorIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OpValue field with key 650. - static const int opValuePropertyKey = 650; - static const int opValueInitialValue = 0; - int _opValue = opValueInitialValue; - - /// Integer representation of the StateMachineOp enum. - int get opValue => _opValue; - - /// Change the [_opValue] field value. - /// [opValueChanged] will be invoked only if the field's value has changed. - set opValue(int value) { - if (_opValue == value) { - return; - } - int from = _opValue; - _opValue = value; - if (hasValidated) { - opValueChanged(from, value); - } - } - - void opValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransitionViewModelConditionBase) { - _leftComparatorId = source._leftComparatorId; - _rightComparatorId = source._rightComparatorId; - _opValue = source._opValue; - } - } -} diff --git a/lib/src/generated/artboard_base.dart b/lib/src/generated/artboard_base.dart deleted file mode 100644 index fddd43a..0000000 --- a/lib/src/generated/artboard_base.dart +++ /dev/null @@ -1,182 +0,0 @@ -// Core automatically generated lib/src/generated/artboard_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/layout_component.dart'; - -abstract class ArtboardBase extends LayoutComponent { - static const int typeKey = 1; - @override - int get coreType => ArtboardBase.typeKey; - @override - Set get coreTypes => { - ArtboardBase.typeKey, - LayoutComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// X field with key 9. - static const int xPropertyKey = 9; - static const double xInitialValue = 0; - double _x = xInitialValue; - - /// X coordinate in editor world space. - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 10. - static const int yPropertyKey = 10; - static const double yInitialValue = 0; - double _y = yInitialValue; - - /// Y coordinate in editor world space. - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 11. - static const int originXPropertyKey = 11; - static const double originXInitialValue = 0; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 12. - static const int originYPropertyKey = 12; - static const double originYInitialValue = 0; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// DefaultStateMachineId field with key 236. - static const int defaultStateMachineIdPropertyKey = 236; - static const int defaultStateMachineIdInitialValue = -1; - int _defaultStateMachineId = defaultStateMachineIdInitialValue; - - /// The default StateMachine attached to this artboard automatically when it - /// is initialized. - int get defaultStateMachineId => _defaultStateMachineId; - - /// Change the [_defaultStateMachineId] field value. - /// [defaultStateMachineIdChanged] will be invoked only if the field's value - /// has changed. - set defaultStateMachineId(int value) { - if (_defaultStateMachineId == value) { - return; - } - int from = _defaultStateMachineId; - _defaultStateMachineId = value; - if (hasValidated) { - defaultStateMachineIdChanged(from, value); - } - } - - void defaultStateMachineIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ViewModelId field with key 583. - static const int viewModelIdPropertyKey = 583; - static const int viewModelIdInitialValue = -1; - int _viewModelId = viewModelIdInitialValue; - - /// The view model attached to this artboard data context. - int get viewModelId => _viewModelId; - - /// Change the [_viewModelId] field value. - /// [viewModelIdChanged] will be invoked only if the field's value has - /// changed. - set viewModelId(int value) { - if (_viewModelId == value) { - return; - } - int from = _viewModelId; - _viewModelId = value; - if (hasValidated) { - viewModelIdChanged(from, value); - } - } - - void viewModelIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ArtboardBase) { - _x = source._x; - _y = source._y; - _originX = source._originX; - _originY = source._originY; - _defaultStateMachineId = source._defaultStateMachineId; - _viewModelId = source._viewModelId; - } - } -} diff --git a/lib/src/generated/asset_base.dart b/lib/src/generated/asset_base.dart deleted file mode 100644 index b8e34d5..0000000 --- a/lib/src/generated/asset_base.dart +++ /dev/null @@ -1,12 +0,0 @@ -/// Core automatically generated lib/src/generated/asset_base.dart. -/// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class AssetBase extends Core { - static const int typeKey = 99; - @override - int get coreType => AssetBase.typeKey; - @override - Set get coreTypes => {AssetBase.typeKey}; -} diff --git a/lib/src/generated/assets/asset_base.dart b/lib/src/generated/assets/asset_base.dart deleted file mode 100644 index bd9ca0a..0000000 --- a/lib/src/generated/assets/asset_base.dart +++ /dev/null @@ -1,44 +0,0 @@ -// Core automatically generated lib/src/generated/assets/asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class AssetBase extends Core { - static const int typeKey = 99; - @override - int get coreType => AssetBase.typeKey; - @override - Set get coreTypes => {AssetBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 203. - static const int namePropertyKey = 203; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Name of the asset - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is AssetBase) { - _name = source._name; - } - } -} diff --git a/lib/src/generated/assets/audio_asset_base.dart b/lib/src/generated/assets/audio_asset_base.dart deleted file mode 100644 index bddd843..0000000 --- a/lib/src/generated/assets/audio_asset_base.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Core automatically generated lib/src/generated/assets/audio_asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/generated/assets/file_asset_base.dart'; -import 'package:rive/src/rive_core/assets/export_audio.dart'; - -abstract class AudioAssetBase extends ExportAudio { - static const int typeKey = 406; - @override - int get coreType => AudioAssetBase.typeKey; - @override - Set get coreTypes => { - AudioAssetBase.typeKey, - ExportAudioBase.typeKey, - FileAssetBase.typeKey, - AssetBase.typeKey - }; -} diff --git a/lib/src/generated/assets/drawable_asset_base.dart b/lib/src/generated/assets/drawable_asset_base.dart deleted file mode 100644 index 096a37d..0000000 --- a/lib/src/generated/assets/drawable_asset_base.dart +++ /dev/null @@ -1,73 +0,0 @@ -// Core automatically generated -// lib/src/generated/assets/drawable_asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; - -abstract class DrawableAssetBase extends FileAsset { - static const int typeKey = 104; - @override - int get coreType => DrawableAssetBase.typeKey; - @override - Set get coreTypes => - {DrawableAssetBase.typeKey, FileAssetBase.typeKey, AssetBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Height field with key 207. - static const int heightPropertyKey = 207; - static const double heightInitialValue = 0; - double _height = heightInitialValue; - - /// Height of the original asset uploaded - double get height => _height; - - /// Change the [_height] field value. - /// [heightChanged] will be invoked only if the field's value has changed. - set height(double value) { - if (_height == value) { - return; - } - double from = _height; - _height = value; - if (hasValidated) { - heightChanged(from, value); - } - } - - void heightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Width field with key 208. - static const int widthPropertyKey = 208; - static const double widthInitialValue = 0; - double _width = widthInitialValue; - - /// Width of the original asset uploaded - double get width => _width; - - /// Change the [_width] field value. - /// [widthChanged] will be invoked only if the field's value has changed. - set width(double value) { - if (_width == value) { - return; - } - double from = _width; - _width = value; - if (hasValidated) { - widthChanged(from, value); - } - } - - void widthChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DrawableAssetBase) { - _height = source._height; - _width = source._width; - } - } -} diff --git a/lib/src/generated/assets/export_audio_base.dart b/lib/src/generated/assets/export_audio_base.dart deleted file mode 100644 index c0a496c..0000000 --- a/lib/src/generated/assets/export_audio_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/assets/export_audio_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; - -abstract class ExportAudioBase extends FileAsset { - static const int typeKey = 422; - @override - int get coreType => ExportAudioBase.typeKey; - @override - Set get coreTypes => - {ExportAudioBase.typeKey, FileAssetBase.typeKey, AssetBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Volume field with key 530. - static const int volumePropertyKey = 530; - static const double volumeInitialValue = 1; - double _volume = volumeInitialValue; - - /// Volume applied to all instances of this audio asset. - double get volume => _volume; - - /// Change the [_volume] field value. - /// [volumeChanged] will be invoked only if the field's value has changed. - set volume(double value) { - if (_volume == value) { - return; - } - double from = _volume; - _volume = value; - if (hasValidated) { - volumeChanged(from, value); - } - } - - void volumeChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ExportAudioBase) { - _volume = source._volume; - } - } -} diff --git a/lib/src/generated/assets/file_asset_base.dart b/lib/src/generated/assets/file_asset_base.dart deleted file mode 100644 index f727e37..0000000 --- a/lib/src/generated/assets/file_asset_base.dart +++ /dev/null @@ -1,96 +0,0 @@ -// Core automatically generated lib/src/generated/assets/file_asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/assets/asset.dart'; - -abstract class FileAssetBase extends Asset { - static const int typeKey = 103; - @override - int get coreType => FileAssetBase.typeKey; - @override - Set get coreTypes => {FileAssetBase.typeKey, AssetBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// AssetId field with key 204. - static const int assetIdPropertyKey = 204; - static const int assetIdInitialValue = 0; - int _assetId = assetIdInitialValue; - - /// Id of the asset as stored on the backend - int get assetId => _assetId; - - /// Change the [_assetId] field value. - /// [assetIdChanged] will be invoked only if the field's value has changed. - set assetId(int value) { - if (_assetId == value) { - return; - } - int from = _assetId; - _assetId = value; - if (hasValidated) { - assetIdChanged(from, value); - } - } - - void assetIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// CdnUuid field with key 359. - static const int cdnUuidPropertyKey = 359; - static final Uint8List cdnUuidInitialValue = Uint8List(0); - Uint8List _cdnUuid = cdnUuidInitialValue; - - /// The cdn uuid if it exists - Uint8List get cdnUuid => _cdnUuid; - - /// Change the [_cdnUuid] field value. - /// [cdnUuidChanged] will be invoked only if the field's value has changed. - set cdnUuid(Uint8List value) { - if (listEquals(_cdnUuid, value)) { - return; - } - Uint8List from = _cdnUuid; - _cdnUuid = value; - if (hasValidated) { - cdnUuidChanged(from, value); - } - } - - void cdnUuidChanged(Uint8List from, Uint8List to); - - /// -------------------------------------------------------------------------- - /// CdnBaseUrl field with key 362. - static const int cdnBaseUrlPropertyKey = 362; - static const String cdnBaseUrlInitialValue = - 'https://public.rive.app/cdn/uuid'; - String _cdnBaseUrl = cdnBaseUrlInitialValue; - - /// Set the base url of our cdn. - String get cdnBaseUrl => _cdnBaseUrl; - - /// Change the [_cdnBaseUrl] field value. - /// [cdnBaseUrlChanged] will be invoked only if the field's value has changed. - set cdnBaseUrl(String value) { - if (_cdnBaseUrl == value) { - return; - } - String from = _cdnBaseUrl; - _cdnBaseUrl = value; - if (hasValidated) { - cdnBaseUrlChanged(from, value); - } - } - - void cdnBaseUrlChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is FileAssetBase) { - _assetId = source._assetId; - _cdnUuid = source._cdnUuid; - _cdnBaseUrl = source._cdnBaseUrl; - } - } -} diff --git a/lib/src/generated/assets/file_asset_contents_base.dart b/lib/src/generated/assets/file_asset_contents_base.dart deleted file mode 100644 index d817e17..0000000 --- a/lib/src/generated/assets/file_asset_contents_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/assets/file_asset_contents_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class FileAssetContentsBase extends Core { - static const int typeKey = 106; - @override - int get coreType => FileAssetContentsBase.typeKey; - @override - Set get coreTypes => {FileAssetContentsBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Bytes field with key 212. - static const int bytesPropertyKey = 212; - static final Uint8List bytesInitialValue = Uint8List(0); - Uint8List _bytes = bytesInitialValue; - - /// Byte data of the file. - Uint8List get bytes => _bytes; - - /// Change the [_bytes] field value. - /// [bytesChanged] will be invoked only if the field's value has changed. - set bytes(Uint8List value) { - if (listEquals(_bytes, value)) { - return; - } - Uint8List from = _bytes; - _bytes = value; - if (hasValidated) { - bytesChanged(from, value); - } - } - - void bytesChanged(Uint8List from, Uint8List to); - - @override - void copy(Core source) { - super.copy(source); - if (source is FileAssetContentsBase) { - _bytes = source._bytes; - } - } -} diff --git a/lib/src/generated/assets/folder_base.dart b/lib/src/generated/assets/folder_base.dart deleted file mode 100644 index 1250154..0000000 --- a/lib/src/generated/assets/folder_base.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Core automatically generated lib/src/generated/assets/folder_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/assets/asset.dart'; - -abstract class FolderBase extends Asset { - static const int typeKey = 102; - @override - int get coreType => FolderBase.typeKey; - @override - Set get coreTypes => {FolderBase.typeKey, AssetBase.typeKey}; -} diff --git a/lib/src/generated/assets/font_asset_base.dart b/lib/src/generated/assets/font_asset_base.dart deleted file mode 100644 index 4b08926..0000000 --- a/lib/src/generated/assets/font_asset_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated lib/src/generated/assets/font_asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; - -abstract class FontAssetBase extends FileAsset { - static const int typeKey = 141; - @override - int get coreType => FontAssetBase.typeKey; - @override - Set get coreTypes => - {FontAssetBase.typeKey, FileAssetBase.typeKey, AssetBase.typeKey}; -} diff --git a/lib/src/generated/assets/image_asset_base.dart b/lib/src/generated/assets/image_asset_base.dart deleted file mode 100644 index 83b9faa..0000000 --- a/lib/src/generated/assets/image_asset_base.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Core automatically generated lib/src/generated/assets/image_asset_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/generated/assets/file_asset_base.dart'; -import 'package:rive/src/rive_core/assets/drawable_asset.dart'; - -abstract class ImageAssetBase extends DrawableAsset { - static const int typeKey = 105; - @override - int get coreType => ImageAssetBase.typeKey; - @override - Set get coreTypes => { - ImageAssetBase.typeKey, - DrawableAssetBase.typeKey, - FileAssetBase.typeKey, - AssetBase.typeKey - }; -} diff --git a/lib/src/generated/audio_event_base.dart b/lib/src/generated/audio_event_base.dart deleted file mode 100644 index 98697d6..0000000 --- a/lib/src/generated/audio_event_base.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Core automatically generated lib/src/generated/audio_event_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/event.dart'; - -abstract class AudioEventBase extends Event { - static const int typeKey = 407; - @override - int get coreType => AudioEventBase.typeKey; - @override - Set get coreTypes => { - AudioEventBase.typeKey, - EventBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AssetId field with key 408. - static const int assetIdPropertyKey = 408; - static const int assetIdInitialValue = -1; - int _assetId = assetIdInitialValue; - - /// Audio asset to play when event fires - int get assetId => _assetId; - - /// Change the [_assetId] field value. - /// [assetIdChanged] will be invoked only if the field's value has changed. - set assetId(int value) { - if (_assetId == value) { - return; - } - int from = _assetId; - _assetId = value; - if (hasValidated) { - assetIdChanged(from, value); - } - } - - void assetIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is AudioEventBase) { - _assetId = source._assetId; - } - } -} diff --git a/lib/src/generated/backboard_base.dart b/lib/src/generated/backboard_base.dart deleted file mode 100644 index 5a5ffaf..0000000 --- a/lib/src/generated/backboard_base.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Core automatically generated lib/src/generated/backboard_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class BackboardBase extends Core { - static const int typeKey = 23; - @override - int get coreType => BackboardBase.typeKey; - @override - Set get coreTypes => {BackboardBase.typeKey}; -} diff --git a/lib/src/generated/bones/bone_base.dart b/lib/src/generated/bones/bone_base.dart deleted file mode 100644 index 9d13775..0000000 --- a/lib/src/generated/bones/bone_base.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Core automatically generated lib/src/generated/bones/bone_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/bones/skeletal_component.dart'; - -abstract class BoneBase extends SkeletalComponent { - static const int typeKey = 40; - @override - int get coreType => BoneBase.typeKey; - @override - Set get coreTypes => { - BoneBase.typeKey, - SkeletalComponentBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Length field with key 89. - static const int lengthPropertyKey = 89; - static const double lengthInitialValue = 0; - double _length = lengthInitialValue; - double get length => _length; - - /// Change the [_length] field value. - /// [lengthChanged] will be invoked only if the field's value has changed. - set length(double value) { - if (_length == value) { - return; - } - double from = _length; - _length = value; - if (hasValidated) { - lengthChanged(from, value); - } - } - - void lengthChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BoneBase) { - _length = source._length; - } - } -} diff --git a/lib/src/generated/bones/cubic_weight_base.dart b/lib/src/generated/bones/cubic_weight_base.dart deleted file mode 100644 index fa1fb00..0000000 --- a/lib/src/generated/bones/cubic_weight_base.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Core automatically generated lib/src/generated/bones/cubic_weight_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; - -abstract class CubicWeightBase extends Weight { - static const int typeKey = 46; - @override - int get coreType => CubicWeightBase.typeKey; - @override - Set get coreTypes => - {CubicWeightBase.typeKey, WeightBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// InValues field with key 110. - static const int inValuesPropertyKey = 110; - static const int inValuesInitialValue = 255; - int _inValues = inValuesInitialValue; - int get inValues => _inValues; - - /// Change the [_inValues] field value. - /// [inValuesChanged] will be invoked only if the field's value has changed. - set inValues(int value) { - if (_inValues == value) { - return; - } - int from = _inValues; - _inValues = value; - if (hasValidated) { - inValuesChanged(from, value); - } - } - - void inValuesChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InIndices field with key 111. - static const int inIndicesPropertyKey = 111; - static const int inIndicesInitialValue = 1; - int _inIndices = inIndicesInitialValue; - int get inIndices => _inIndices; - - /// Change the [_inIndices] field value. - /// [inIndicesChanged] will be invoked only if the field's value has changed. - set inIndices(int value) { - if (_inIndices == value) { - return; - } - int from = _inIndices; - _inIndices = value; - if (hasValidated) { - inIndicesChanged(from, value); - } - } - - void inIndicesChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OutValues field with key 112. - static const int outValuesPropertyKey = 112; - static const int outValuesInitialValue = 255; - int _outValues = outValuesInitialValue; - int get outValues => _outValues; - - /// Change the [_outValues] field value. - /// [outValuesChanged] will be invoked only if the field's value has changed. - set outValues(int value) { - if (_outValues == value) { - return; - } - int from = _outValues; - _outValues = value; - if (hasValidated) { - outValuesChanged(from, value); - } - } - - void outValuesChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OutIndices field with key 113. - static const int outIndicesPropertyKey = 113; - static const int outIndicesInitialValue = 1; - int _outIndices = outIndicesInitialValue; - int get outIndices => _outIndices; - - /// Change the [_outIndices] field value. - /// [outIndicesChanged] will be invoked only if the field's value has changed. - set outIndices(int value) { - if (_outIndices == value) { - return; - } - int from = _outIndices; - _outIndices = value; - if (hasValidated) { - outIndicesChanged(from, value); - } - } - - void outIndicesChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicWeightBase) { - _inValues = source._inValues; - _inIndices = source._inIndices; - _outValues = source._outValues; - _outIndices = source._outIndices; - } - } -} diff --git a/lib/src/generated/bones/root_bone_base.dart b/lib/src/generated/bones/root_bone_base.dart deleted file mode 100644 index ffd1fe7..0000000 --- a/lib/src/generated/bones/root_bone_base.dart +++ /dev/null @@ -1,83 +0,0 @@ -// Core automatically generated lib/src/generated/bones/root_bone_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/bones/skeletal_component_base.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/bones/bone.dart'; - -abstract class RootBoneBase extends Bone { - static const int typeKey = 41; - @override - int get coreType => RootBoneBase.typeKey; - @override - Set get coreTypes => { - RootBoneBase.typeKey, - BoneBase.typeKey, - SkeletalComponentBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// X field with key 90. - static const int xPropertyKey = 90; - static const double xInitialValue = 0; - double _x = xInitialValue; - @override - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - @override - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 91. - static const int yPropertyKey = 91; - static const double yInitialValue = 0; - double _y = yInitialValue; - @override - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - @override - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is RootBoneBase) { - _x = source._x; - _y = source._y; - } - } -} diff --git a/lib/src/generated/bones/skeletal_component_base.dart b/lib/src/generated/bones/skeletal_component_base.dart deleted file mode 100644 index baf4aa5..0000000 --- a/lib/src/generated/bones/skeletal_component_base.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Core automatically generated -// lib/src/generated/bones/skeletal_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; - -abstract class SkeletalComponentBase extends TransformComponent { - static const int typeKey = 39; - @override - int get coreType => SkeletalComponentBase.typeKey; - @override - Set get coreTypes => { - SkeletalComponentBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/bones/skin_base.dart b/lib/src/generated/bones/skin_base.dart deleted file mode 100644 index b98bfae..0000000 --- a/lib/src/generated/bones/skin_base.dart +++ /dev/null @@ -1,172 +0,0 @@ -// Core automatically generated lib/src/generated/bones/skin_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class SkinBase extends ContainerComponent { - static const int typeKey = 43; - @override - int get coreType => SkinBase.typeKey; - @override - Set get coreTypes => - {SkinBase.typeKey, ContainerComponentBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Xx field with key 104. - static const int xxPropertyKey = 104; - static const double xxInitialValue = 1; - double _xx = xxInitialValue; - - /// x component of x unit vector in the bind transform - double get xx => _xx; - - /// Change the [_xx] field value. - /// [xxChanged] will be invoked only if the field's value has changed. - set xx(double value) { - if (_xx == value) { - return; - } - double from = _xx; - _xx = value; - if (hasValidated) { - xxChanged(from, value); - } - } - - void xxChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Yx field with key 105. - static const int yxPropertyKey = 105; - static const double yxInitialValue = 0; - double _yx = yxInitialValue; - - /// y component of x unit vector in the bind transform - double get yx => _yx; - - /// Change the [_yx] field value. - /// [yxChanged] will be invoked only if the field's value has changed. - set yx(double value) { - if (_yx == value) { - return; - } - double from = _yx; - _yx = value; - if (hasValidated) { - yxChanged(from, value); - } - } - - void yxChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Xy field with key 106. - static const int xyPropertyKey = 106; - static const double xyInitialValue = 0; - double _xy = xyInitialValue; - - /// x component of y unit vector in the bind transform - double get xy => _xy; - - /// Change the [_xy] field value. - /// [xyChanged] will be invoked only if the field's value has changed. - set xy(double value) { - if (_xy == value) { - return; - } - double from = _xy; - _xy = value; - if (hasValidated) { - xyChanged(from, value); - } - } - - void xyChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Yy field with key 107. - static const int yyPropertyKey = 107; - static const double yyInitialValue = 1; - double _yy = yyInitialValue; - - /// y component of y unit vector in the bind transform - double get yy => _yy; - - /// Change the [_yy] field value. - /// [yyChanged] will be invoked only if the field's value has changed. - set yy(double value) { - if (_yy == value) { - return; - } - double from = _yy; - _yy = value; - if (hasValidated) { - yyChanged(from, value); - } - } - - void yyChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Tx field with key 108. - static const int txPropertyKey = 108; - static const double txInitialValue = 0; - double _tx = txInitialValue; - - /// x position component of the bind transform - double get tx => _tx; - - /// Change the [_tx] field value. - /// [txChanged] will be invoked only if the field's value has changed. - set tx(double value) { - if (_tx == value) { - return; - } - double from = _tx; - _tx = value; - if (hasValidated) { - txChanged(from, value); - } - } - - void txChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Ty field with key 109. - static const int tyPropertyKey = 109; - static const double tyInitialValue = 0; - double _ty = tyInitialValue; - - /// y position component of the bind transform - double get ty => _ty; - - /// Change the [_ty] field value. - /// [tyChanged] will be invoked only if the field's value has changed. - set ty(double value) { - if (_ty == value) { - return; - } - double from = _ty; - _ty = value; - if (hasValidated) { - tyChanged(from, value); - } - } - - void tyChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is SkinBase) { - _xx = source._xx; - _yx = source._yx; - _xy = source._xy; - _yy = source._yy; - _tx = source._tx; - _ty = source._ty; - } - } -} diff --git a/lib/src/generated/bones/tendon_base.dart b/lib/src/generated/bones/tendon_base.dart deleted file mode 100644 index 9614c14..0000000 --- a/lib/src/generated/bones/tendon_base.dart +++ /dev/null @@ -1,195 +0,0 @@ -// Core automatically generated lib/src/generated/bones/tendon_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TendonBase extends Component { - static const int typeKey = 44; - @override - int get coreType => TendonBase.typeKey; - @override - Set get coreTypes => {TendonBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// BoneId field with key 95. - static const int boneIdPropertyKey = 95; - static const int boneIdInitialValue = -1; - int _boneId = boneIdInitialValue; - - /// Identifier used to track the bone this tendon connects to. - int get boneId => _boneId; - - /// Change the [_boneId] field value. - /// [boneIdChanged] will be invoked only if the field's value has changed. - set boneId(int value) { - if (_boneId == value) { - return; - } - int from = _boneId; - _boneId = value; - if (hasValidated) { - boneIdChanged(from, value); - } - } - - void boneIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Xx field with key 96. - static const int xxPropertyKey = 96; - static const double xxInitialValue = 1; - double _xx = xxInitialValue; - - /// x component of x unit vector in the bind transform - double get xx => _xx; - - /// Change the [_xx] field value. - /// [xxChanged] will be invoked only if the field's value has changed. - set xx(double value) { - if (_xx == value) { - return; - } - double from = _xx; - _xx = value; - if (hasValidated) { - xxChanged(from, value); - } - } - - void xxChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Yx field with key 97. - static const int yxPropertyKey = 97; - static const double yxInitialValue = 0; - double _yx = yxInitialValue; - - /// y component of x unit vector in the bind transform - double get yx => _yx; - - /// Change the [_yx] field value. - /// [yxChanged] will be invoked only if the field's value has changed. - set yx(double value) { - if (_yx == value) { - return; - } - double from = _yx; - _yx = value; - if (hasValidated) { - yxChanged(from, value); - } - } - - void yxChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Xy field with key 98. - static const int xyPropertyKey = 98; - static const double xyInitialValue = 0; - double _xy = xyInitialValue; - - /// x component of y unit vector in the bind transform - double get xy => _xy; - - /// Change the [_xy] field value. - /// [xyChanged] will be invoked only if the field's value has changed. - set xy(double value) { - if (_xy == value) { - return; - } - double from = _xy; - _xy = value; - if (hasValidated) { - xyChanged(from, value); - } - } - - void xyChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Yy field with key 99. - static const int yyPropertyKey = 99; - static const double yyInitialValue = 1; - double _yy = yyInitialValue; - - /// y component of y unit vector in the bind transform - double get yy => _yy; - - /// Change the [_yy] field value. - /// [yyChanged] will be invoked only if the field's value has changed. - set yy(double value) { - if (_yy == value) { - return; - } - double from = _yy; - _yy = value; - if (hasValidated) { - yyChanged(from, value); - } - } - - void yyChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Tx field with key 100. - static const int txPropertyKey = 100; - static const double txInitialValue = 0; - double _tx = txInitialValue; - - /// x position component of the bind transform - double get tx => _tx; - - /// Change the [_tx] field value. - /// [txChanged] will be invoked only if the field's value has changed. - set tx(double value) { - if (_tx == value) { - return; - } - double from = _tx; - _tx = value; - if (hasValidated) { - txChanged(from, value); - } - } - - void txChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Ty field with key 101. - static const int tyPropertyKey = 101; - static const double tyInitialValue = 0; - double _ty = tyInitialValue; - - /// y position component of the bind transform - double get ty => _ty; - - /// Change the [_ty] field value. - /// [tyChanged] will be invoked only if the field's value has changed. - set ty(double value) { - if (_ty == value) { - return; - } - double from = _ty; - _ty = value; - if (hasValidated) { - tyChanged(from, value); - } - } - - void tyChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TendonBase) { - _boneId = source._boneId; - _xx = source._xx; - _yx = source._yx; - _xy = source._xy; - _yy = source._yy; - _tx = source._tx; - _ty = source._ty; - } - } -} diff --git a/lib/src/generated/bones/weight_base.dart b/lib/src/generated/bones/weight_base.dart deleted file mode 100644 index 8941762..0000000 --- a/lib/src/generated/bones/weight_base.dart +++ /dev/null @@ -1,66 +0,0 @@ -// Core automatically generated lib/src/generated/bones/weight_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class WeightBase extends Component { - static const int typeKey = 45; - @override - int get coreType => WeightBase.typeKey; - @override - Set get coreTypes => {WeightBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Values field with key 102. - static const int valuesPropertyKey = 102; - static const int valuesInitialValue = 255; - int _values = valuesInitialValue; - int get values => _values; - - /// Change the [_values] field value. - /// [valuesChanged] will be invoked only if the field's value has changed. - set values(int value) { - if (_values == value) { - return; - } - int from = _values; - _values = value; - if (hasValidated) { - valuesChanged(from, value); - } - } - - void valuesChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Indices field with key 103. - static const int indicesPropertyKey = 103; - static const int indicesInitialValue = 1; - int _indices = indicesInitialValue; - int get indices => _indices; - - /// Change the [_indices] field value. - /// [indicesChanged] will be invoked only if the field's value has changed. - set indices(int value) { - if (_indices == value) { - return; - } - int from = _indices; - _indices = value; - if (hasValidated) { - indicesChanged(from, value); - } - } - - void indicesChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is WeightBase) { - _values = source._values; - _indices = source._indices; - } - } -} diff --git a/lib/src/generated/component_base.dart b/lib/src/generated/component_base.dart deleted file mode 100644 index 2f795c1..0000000 --- a/lib/src/generated/component_base.dart +++ /dev/null @@ -1,70 +0,0 @@ -// Core automatically generated lib/src/generated/component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class ComponentBase extends Core { - static const int typeKey = 10; - @override - int get coreType => ComponentBase.typeKey; - @override - Set get coreTypes => {ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 4. - static const int namePropertyKey = 4; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Non-unique identifier, used to give friendly names to elements in the - /// hierarchy. Runtimes provide an API for finding components by this [name]. - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - /// -------------------------------------------------------------------------- - /// ParentId field with key 5. - static const int parentIdPropertyKey = 5; - static const int parentIdInitialValue = 0; - int _parentId = parentIdInitialValue; - - /// Identifier used to track parent ContainerComponent. - int get parentId => _parentId; - - /// Change the [_parentId] field value. - /// [parentIdChanged] will be invoked only if the field's value has changed. - set parentId(int value) { - if (_parentId == value) { - return; - } - int from = _parentId; - _parentId = value; - if (hasValidated) { - parentIdChanged(from, value); - } - } - - void parentIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ComponentBase) { - _name = source._name; - _parentId = source._parentId; - } - } -} diff --git a/lib/src/generated/constraints/constraint_base.dart b/lib/src/generated/constraints/constraint_base.dart deleted file mode 100644 index a5a36e3..0000000 --- a/lib/src/generated/constraints/constraint_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class ConstraintBase extends Component { - static const int typeKey = 79; - @override - int get coreType => ConstraintBase.typeKey; - @override - Set get coreTypes => {ConstraintBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Strength field with key 172. - static const int strengthPropertyKey = 172; - static const double strengthInitialValue = 1.0; - double _strength = strengthInitialValue; - - /// Strength of the constraint. 0 means off. 1 means fully constraining. - double get strength => _strength; - - /// Change the [_strength] field value. - /// [strengthChanged] will be invoked only if the field's value has changed. - set strength(double value) { - if (_strength == value) { - return; - } - double from = _strength; - _strength = value; - if (hasValidated) { - strengthChanged(from, value); - } - } - - void strengthChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ConstraintBase) { - _strength = source._strength; - } - } -} diff --git a/lib/src/generated/constraints/distance_constraint_base.dart b/lib/src/generated/constraints/distance_constraint_base.dart deleted file mode 100644 index dc5c38e..0000000 --- a/lib/src/generated/constraints/distance_constraint_base.dart +++ /dev/null @@ -1,79 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/distance_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/targeted_constraint.dart'; - -abstract class DistanceConstraintBase extends TargetedConstraint { - static const int typeKey = 82; - @override - int get coreType => DistanceConstraintBase.typeKey; - @override - Set get coreTypes => { - DistanceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Distance field with key 177. - static const int distancePropertyKey = 177; - static const double distanceInitialValue = 100.0; - double _distance = distanceInitialValue; - - /// The unit distance the constraint will move the constrained object relative - /// to the target. - double get distance => _distance; - - /// Change the [_distance] field value. - /// [distanceChanged] will be invoked only if the field's value has changed. - set distance(double value) { - if (_distance == value) { - return; - } - double from = _distance; - _distance = value; - if (hasValidated) { - distanceChanged(from, value); - } - } - - void distanceChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ModeValue field with key 178. - static const int modeValuePropertyKey = 178; - static const int modeValueInitialValue = 0; - int _modeValue = modeValueInitialValue; - - /// Backing value for the mode enum. - int get modeValue => _modeValue; - - /// Change the [_modeValue] field value. - /// [modeValueChanged] will be invoked only if the field's value has changed. - set modeValue(int value) { - if (_modeValue == value) { - return; - } - int from = _modeValue; - _modeValue = value; - if (hasValidated) { - modeValueChanged(from, value); - } - } - - void modeValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DistanceConstraintBase) { - _distance = source._distance; - _modeValue = source._modeValue; - } - } -} diff --git a/lib/src/generated/constraints/follow_path_constraint_base.dart b/lib/src/generated/constraints/follow_path_constraint_base.dart deleted file mode 100644 index 11438b4..0000000 --- a/lib/src/generated/constraints/follow_path_constraint_base.dart +++ /dev/null @@ -1,106 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/follow_path_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_space_constraint.dart'; - -abstract class FollowPathConstraintBase extends TransformSpaceConstraint { - static const int typeKey = 165; - @override - int get coreType => FollowPathConstraintBase.typeKey; - @override - Set get coreTypes => { - FollowPathConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Distance field with key 363. - static const int distancePropertyKey = 363; - static const double distanceInitialValue = 0; - double _distance = distanceInitialValue; - - /// Distance along the path to follow. - double get distance => _distance; - - /// Change the [_distance] field value. - /// [distanceChanged] will be invoked only if the field's value has changed. - set distance(double value) { - if (_distance == value) { - return; - } - double from = _distance; - _distance = value; - if (hasValidated) { - distanceChanged(from, value); - } - } - - void distanceChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Orient field with key 364. - static const int orientPropertyKey = 364; - static const bool orientInitialValue = true; - bool _orient = orientInitialValue; - - /// True when the orientation from the path is copied to the constrained - /// transform. - bool get orient => _orient; - - /// Change the [_orient] field value. - /// [orientChanged] will be invoked only if the field's value has changed. - set orient(bool value) { - if (_orient == value) { - return; - } - bool from = _orient; - _orient = value; - if (hasValidated) { - orientChanged(from, value); - } - } - - void orientChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// Offset field with key 365. - static const int offsetPropertyKey = 365; - static const bool offsetInitialValue = false; - bool _offset = offsetInitialValue; - - /// True when the local translation is used to offset the transformed one. - bool get offset => _offset; - - /// Change the [_offset] field value. - /// [offsetChanged] will be invoked only if the field's value has changed. - set offset(bool value) { - if (_offset == value) { - return; - } - bool from = _offset; - _offset = value; - if (hasValidated) { - offsetChanged(from, value); - } - } - - void offsetChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is FollowPathConstraintBase) { - _distance = source._distance; - _orient = source._orient; - _offset = source._offset; - } - } -} diff --git a/lib/src/generated/constraints/ik_constraint_base.dart b/lib/src/generated/constraints/ik_constraint_base.dart deleted file mode 100644 index e7f4e89..0000000 --- a/lib/src/generated/constraints/ik_constraint_base.dart +++ /dev/null @@ -1,82 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/ik_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/targeted_constraint.dart'; - -abstract class IKConstraintBase extends TargetedConstraint { - static const int typeKey = 81; - @override - int get coreType => IKConstraintBase.typeKey; - @override - Set get coreTypes => { - IKConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// InvertDirection field with key 174. - static const int invertDirectionPropertyKey = 174; - static const bool invertDirectionInitialValue = false; - bool _invertDirection = invertDirectionInitialValue; - - /// True when the direction taken towards the target should be inverted from - /// the default. - bool get invertDirection => _invertDirection; - - /// Change the [_invertDirection] field value. - /// [invertDirectionChanged] will be invoked only if the field's value has - /// changed. - set invertDirection(bool value) { - if (_invertDirection == value) { - return; - } - bool from = _invertDirection; - _invertDirection = value; - if (hasValidated) { - invertDirectionChanged(from, value); - } - } - - void invertDirectionChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// ParentBoneCount field with key 175. - static const int parentBoneCountPropertyKey = 175; - static const int parentBoneCountInitialValue = 0; - int _parentBoneCount = parentBoneCountInitialValue; - - /// The number of bones above this one that are influenced by this IK - /// constraint. - int get parentBoneCount => _parentBoneCount; - - /// Change the [_parentBoneCount] field value. - /// [parentBoneCountChanged] will be invoked only if the field's value has - /// changed. - set parentBoneCount(int value) { - if (_parentBoneCount == value) { - return; - } - int from = _parentBoneCount; - _parentBoneCount = value; - if (hasValidated) { - parentBoneCountChanged(from, value); - } - } - - void parentBoneCountChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is IKConstraintBase) { - _invertDirection = source._invertDirection; - _parentBoneCount = source._parentBoneCount; - } - } -} diff --git a/lib/src/generated/constraints/rotation_constraint_base.dart b/lib/src/generated/constraints/rotation_constraint_base.dart deleted file mode 100644 index d5aca32..0000000 --- a/lib/src/generated/constraints/rotation_constraint_base.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/rotation_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_component_constraint.dart'; - -abstract class RotationConstraintBase extends TransformComponentConstraint { - static const int typeKey = 89; - @override - int get coreType => RotationConstraintBase.typeKey; - @override - Set get coreTypes => { - RotationConstraintBase.typeKey, - TransformComponentConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/constraints/scale_constraint_base.dart b/lib/src/generated/constraints/scale_constraint_base.dart deleted file mode 100644 index 3b27d8b..0000000 --- a/lib/src/generated/constraints/scale_constraint_base.dart +++ /dev/null @@ -1,26 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/scale_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_component_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_component_constraint_y.dart'; - -abstract class ScaleConstraintBase extends TransformComponentConstraintY { - static const int typeKey = 88; - @override - int get coreType => ScaleConstraintBase.typeKey; - @override - Set get coreTypes => { - ScaleConstraintBase.typeKey, - TransformComponentConstraintYBase.typeKey, - TransformComponentConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/constraints/targeted_constraint_base.dart b/lib/src/generated/constraints/targeted_constraint_base.dart deleted file mode 100644 index c5ec1cc..0000000 --- a/lib/src/generated/constraints/targeted_constraint_base.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/targeted_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; - -abstract class TargetedConstraintBase extends Constraint { - static const int typeKey = 80; - @override - int get coreType => TargetedConstraintBase.typeKey; - @override - Set get coreTypes => { - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// TargetId field with key 173. - static const int targetIdPropertyKey = 173; - static const int targetIdInitialValue = -1; - int _targetId = targetIdInitialValue; - - /// Identifier used to track the TransformComponent used as the target for the - /// constraint. - int get targetId => _targetId; - - /// Change the [_targetId] field value. - /// [targetIdChanged] will be invoked only if the field's value has changed. - set targetId(int value) { - if (_targetId == value) { - return; - } - int from = _targetId; - _targetId = value; - if (hasValidated) { - targetIdChanged(from, value); - } - } - - void targetIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TargetedConstraintBase) { - _targetId = source._targetId; - } - } -} diff --git a/lib/src/generated/constraints/transform_component_constraint_base.dart b/lib/src/generated/constraints/transform_component_constraint_base.dart deleted file mode 100644 index 61d07ad..0000000 --- a/lib/src/generated/constraints/transform_component_constraint_base.dart +++ /dev/null @@ -1,233 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/transform_component_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_space_constraint.dart'; - -abstract class TransformComponentConstraintBase - extends TransformSpaceConstraint { - static const int typeKey = 85; - @override - int get coreType => TransformComponentConstraintBase.typeKey; - @override - Set get coreTypes => { - TransformComponentConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// MinMaxSpaceValue field with key 195. - static const int minMaxSpaceValuePropertyKey = 195; - static const int minMaxSpaceValueInitialValue = 0; - int _minMaxSpaceValue = minMaxSpaceValueInitialValue; - - /// The min/max transform space. - int get minMaxSpaceValue => _minMaxSpaceValue; - - /// Change the [_minMaxSpaceValue] field value. - /// [minMaxSpaceValueChanged] will be invoked only if the field's value has - /// changed. - set minMaxSpaceValue(int value) { - if (_minMaxSpaceValue == value) { - return; - } - int from = _minMaxSpaceValue; - _minMaxSpaceValue = value; - if (hasValidated) { - minMaxSpaceValueChanged(from, value); - } - } - - void minMaxSpaceValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// CopyFactor field with key 182. - static const int copyFactorPropertyKey = 182; - static const double copyFactorInitialValue = 1; - double _copyFactor = copyFactorInitialValue; - - /// Copy factor. - double get copyFactor => _copyFactor; - - /// Change the [_copyFactor] field value. - /// [copyFactorChanged] will be invoked only if the field's value has changed. - set copyFactor(double value) { - if (_copyFactor == value) { - return; - } - double from = _copyFactor; - _copyFactor = value; - if (hasValidated) { - copyFactorChanged(from, value); - } - } - - void copyFactorChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MinValue field with key 183. - static const int minValuePropertyKey = 183; - static const double minValueInitialValue = 0; - double _minValue = minValueInitialValue; - - /// Minimum value. - double get minValue => _minValue; - - /// Change the [_minValue] field value. - /// [minValueChanged] will be invoked only if the field's value has changed. - set minValue(double value) { - if (_minValue == value) { - return; - } - double from = _minValue; - _minValue = value; - if (hasValidated) { - minValueChanged(from, value); - } - } - - void minValueChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MaxValue field with key 184. - static const int maxValuePropertyKey = 184; - static const double maxValueInitialValue = 0; - double _maxValue = maxValueInitialValue; - - /// Maximum value. - double get maxValue => _maxValue; - - /// Change the [_maxValue] field value. - /// [maxValueChanged] will be invoked only if the field's value has changed. - set maxValue(double value) { - if (_maxValue == value) { - return; - } - double from = _maxValue; - _maxValue = value; - if (hasValidated) { - maxValueChanged(from, value); - } - } - - void maxValueChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Offset field with key 188. - static const int offsetPropertyKey = 188; - static const bool offsetInitialValue = false; - bool _offset = offsetInitialValue; - - /// True when the original component (rotation/scale/translation) is used to - /// offset the copied one. - bool get offset => _offset; - - /// Change the [_offset] field value. - /// [offsetChanged] will be invoked only if the field's value has changed. - set offset(bool value) { - if (_offset == value) { - return; - } - bool from = _offset; - _offset = value; - if (hasValidated) { - offsetChanged(from, value); - } - } - - void offsetChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// DoesCopy field with key 189. - static const int doesCopyPropertyKey = 189; - static const bool doesCopyInitialValue = true; - bool _doesCopy = doesCopyInitialValue; - - /// Whether the component is copied. - bool get doesCopy => _doesCopy; - - /// Change the [_doesCopy] field value. - /// [doesCopyChanged] will be invoked only if the field's value has changed. - set doesCopy(bool value) { - if (_doesCopy == value) { - return; - } - bool from = _doesCopy; - _doesCopy = value; - if (hasValidated) { - doesCopyChanged(from, value); - } - } - - void doesCopyChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// Min field with key 190. - static const int minPropertyKey = 190; - static const bool minInitialValue = false; - bool _min = minInitialValue; - - /// Whether min is used. - bool get min => _min; - - /// Change the [_min] field value. - /// [minChanged] will be invoked only if the field's value has changed. - set min(bool value) { - if (_min == value) { - return; - } - bool from = _min; - _min = value; - if (hasValidated) { - minChanged(from, value); - } - } - - void minChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// Max field with key 191. - static const int maxPropertyKey = 191; - static const bool maxInitialValue = false; - bool _max = maxInitialValue; - - /// Whether max is used. - bool get max => _max; - - /// Change the [_max] field value. - /// [maxChanged] will be invoked only if the field's value has changed. - set max(bool value) { - if (_max == value) { - return; - } - bool from = _max; - _max = value; - if (hasValidated) { - maxChanged(from, value); - } - } - - void maxChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransformComponentConstraintBase) { - _minMaxSpaceValue = source._minMaxSpaceValue; - _copyFactor = source._copyFactor; - _minValue = source._minValue; - _maxValue = source._maxValue; - _offset = source._offset; - _doesCopy = source._doesCopy; - _min = source._min; - _max = source._max; - } - } -} diff --git a/lib/src/generated/constraints/transform_component_constraint_y_base.dart b/lib/src/generated/constraints/transform_component_constraint_y_base.dart deleted file mode 100644 index 26a3b41..0000000 --- a/lib/src/generated/constraints/transform_component_constraint_y_base.dart +++ /dev/null @@ -1,184 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/transform_component_constraint_y_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_component_constraint.dart'; - -abstract class TransformComponentConstraintYBase - extends TransformComponentConstraint { - static const int typeKey = 86; - @override - int get coreType => TransformComponentConstraintYBase.typeKey; - @override - Set get coreTypes => { - TransformComponentConstraintYBase.typeKey, - TransformComponentConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// CopyFactorY field with key 185. - static const int copyFactorYPropertyKey = 185; - static const double copyFactorYInitialValue = 1; - double _copyFactorY = copyFactorYInitialValue; - - /// Copy factor. - double get copyFactorY => _copyFactorY; - - /// Change the [_copyFactorY] field value. - /// [copyFactorYChanged] will be invoked only if the field's value has - /// changed. - set copyFactorY(double value) { - if (_copyFactorY == value) { - return; - } - double from = _copyFactorY; - _copyFactorY = value; - if (hasValidated) { - copyFactorYChanged(from, value); - } - } - - void copyFactorYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MinValueY field with key 186. - static const int minValueYPropertyKey = 186; - static const double minValueYInitialValue = 0; - double _minValueY = minValueYInitialValue; - - /// Minimum value. - double get minValueY => _minValueY; - - /// Change the [_minValueY] field value. - /// [minValueYChanged] will be invoked only if the field's value has changed. - set minValueY(double value) { - if (_minValueY == value) { - return; - } - double from = _minValueY; - _minValueY = value; - if (hasValidated) { - minValueYChanged(from, value); - } - } - - void minValueYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MaxValueY field with key 187. - static const int maxValueYPropertyKey = 187; - static const double maxValueYInitialValue = 0; - double _maxValueY = maxValueYInitialValue; - - /// Maximum value. - double get maxValueY => _maxValueY; - - /// Change the [_maxValueY] field value. - /// [maxValueYChanged] will be invoked only if the field's value has changed. - set maxValueY(double value) { - if (_maxValueY == value) { - return; - } - double from = _maxValueY; - _maxValueY = value; - if (hasValidated) { - maxValueYChanged(from, value); - } - } - - void maxValueYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// DoesCopyY field with key 192. - static const int doesCopyYPropertyKey = 192; - static const bool doesCopyYInitialValue = true; - bool _doesCopyY = doesCopyYInitialValue; - - /// Whether the Y component is copied. - bool get doesCopyY => _doesCopyY; - - /// Change the [_doesCopyY] field value. - /// [doesCopyYChanged] will be invoked only if the field's value has changed. - set doesCopyY(bool value) { - if (_doesCopyY == value) { - return; - } - bool from = _doesCopyY; - _doesCopyY = value; - if (hasValidated) { - doesCopyYChanged(from, value); - } - } - - void doesCopyYChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// MinY field with key 193. - static const int minYPropertyKey = 193; - static const bool minYInitialValue = false; - bool _minY = minYInitialValue; - - /// Whether min Y is used. - bool get minY => _minY; - - /// Change the [_minY] field value. - /// [minYChanged] will be invoked only if the field's value has changed. - set minY(bool value) { - if (_minY == value) { - return; - } - bool from = _minY; - _minY = value; - if (hasValidated) { - minYChanged(from, value); - } - } - - void minYChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// MaxY field with key 194. - static const int maxYPropertyKey = 194; - static const bool maxYInitialValue = false; - bool _maxY = maxYInitialValue; - - /// Whether max Y is used. - bool get maxY => _maxY; - - /// Change the [_maxY] field value. - /// [maxYChanged] will be invoked only if the field's value has changed. - set maxY(bool value) { - if (_maxY == value) { - return; - } - bool from = _maxY; - _maxY = value; - if (hasValidated) { - maxYChanged(from, value); - } - } - - void maxYChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransformComponentConstraintYBase) { - _copyFactorY = source._copyFactorY; - _minValueY = source._minValueY; - _maxValueY = source._maxValueY; - _doesCopyY = source._doesCopyY; - _minY = source._minY; - _maxY = source._maxY; - } - } -} diff --git a/lib/src/generated/constraints/transform_constraint_base.dart b/lib/src/generated/constraints/transform_constraint_base.dart deleted file mode 100644 index 3912ba0..0000000 --- a/lib/src/generated/constraints/transform_constraint_base.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/transform_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_space_constraint.dart'; - -abstract class TransformConstraintBase extends TransformSpaceConstraint { - static const int typeKey = 83; - @override - int get coreType => TransformConstraintBase.typeKey; - @override - Set get coreTypes => { - TransformConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// OriginX field with key 372. - static const int originXPropertyKey = 372; - static const double originXInitialValue = 0.0; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 373. - static const int originYPropertyKey = 373; - static const double originYInitialValue = 0.0; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransformConstraintBase) { - _originX = source._originX; - _originY = source._originY; - } - } -} diff --git a/lib/src/generated/constraints/transform_space_constraint_base.dart b/lib/src/generated/constraints/transform_space_constraint_base.dart deleted file mode 100644 index 49f99ea..0000000 --- a/lib/src/generated/constraints/transform_space_constraint_base.dart +++ /dev/null @@ -1,80 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/transform_space_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/targeted_constraint.dart'; - -abstract class TransformSpaceConstraintBase extends TargetedConstraint { - static const int typeKey = 90; - @override - int get coreType => TransformSpaceConstraintBase.typeKey; - @override - Set get coreTypes => { - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// SourceSpaceValue field with key 179. - static const int sourceSpaceValuePropertyKey = 179; - static const int sourceSpaceValueInitialValue = 0; - int _sourceSpaceValue = sourceSpaceValueInitialValue; - - /// The source transform space. - int get sourceSpaceValue => _sourceSpaceValue; - - /// Change the [_sourceSpaceValue] field value. - /// [sourceSpaceValueChanged] will be invoked only if the field's value has - /// changed. - set sourceSpaceValue(int value) { - if (_sourceSpaceValue == value) { - return; - } - int from = _sourceSpaceValue; - _sourceSpaceValue = value; - if (hasValidated) { - sourceSpaceValueChanged(from, value); - } - } - - void sourceSpaceValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// DestSpaceValue field with key 180. - static const int destSpaceValuePropertyKey = 180; - static const int destSpaceValueInitialValue = 0; - int _destSpaceValue = destSpaceValueInitialValue; - - /// The destination transform space. - int get destSpaceValue => _destSpaceValue; - - /// Change the [_destSpaceValue] field value. - /// [destSpaceValueChanged] will be invoked only if the field's value has - /// changed. - set destSpaceValue(int value) { - if (_destSpaceValue == value) { - return; - } - int from = _destSpaceValue; - _destSpaceValue = value; - if (hasValidated) { - destSpaceValueChanged(from, value); - } - } - - void destSpaceValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransformSpaceConstraintBase) { - _sourceSpaceValue = source._sourceSpaceValue; - _destSpaceValue = source._destSpaceValue; - } - } -} diff --git a/lib/src/generated/constraints/translation_constraint_base.dart b/lib/src/generated/constraints/translation_constraint_base.dart deleted file mode 100644 index 5a83246..0000000 --- a/lib/src/generated/constraints/translation_constraint_base.dart +++ /dev/null @@ -1,26 +0,0 @@ -// Core automatically generated -// lib/src/generated/constraints/translation_constraint_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_component_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/transform_component_constraint_y.dart'; - -abstract class TranslationConstraintBase extends TransformComponentConstraintY { - static const int typeKey = 87; - @override - int get coreType => TranslationConstraintBase.typeKey; - @override - Set get coreTypes => { - TranslationConstraintBase.typeKey, - TransformComponentConstraintYBase.typeKey, - TransformComponentConstraintBase.typeKey, - TransformSpaceConstraintBase.typeKey, - TargetedConstraintBase.typeKey, - ConstraintBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/container_component_base.dart b/lib/src/generated/container_component_base.dart deleted file mode 100644 index a10473b..0000000 --- a/lib/src/generated/container_component_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/container_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/component.dart'; - -abstract class ContainerComponentBase extends Component { - static const int typeKey = 11; - @override - int get coreType => ContainerComponentBase.typeKey; - @override - Set get coreTypes => - {ContainerComponentBase.typeKey, ComponentBase.typeKey}; -} diff --git a/lib/src/generated/custom_property_base.dart b/lib/src/generated/custom_property_base.dart deleted file mode 100644 index 9a404d9..0000000 --- a/lib/src/generated/custom_property_base.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Core automatically generated lib/src/generated/custom_property_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/component.dart'; - -abstract class CustomPropertyBase extends Component { - static const int typeKey = 167; - @override - int get coreType => CustomPropertyBase.typeKey; - @override - Set get coreTypes => {CustomPropertyBase.typeKey, ComponentBase.typeKey}; -} diff --git a/lib/src/generated/custom_property_boolean_base.dart b/lib/src/generated/custom_property_boolean_base.dart deleted file mode 100644 index 00dcc3a..0000000 --- a/lib/src/generated/custom_property_boolean_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/custom_property_boolean_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/custom_property.dart'; - -abstract class CustomPropertyBooleanBase extends CustomProperty { - static const int typeKey = 129; - @override - int get coreType => CustomPropertyBooleanBase.typeKey; - @override - Set get coreTypes => { - CustomPropertyBooleanBase.typeKey, - CustomPropertyBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 245. - static const int propertyValuePropertyKey = 245; - static const bool propertyValueInitialValue = false; - bool _propertyValue = propertyValueInitialValue; - bool get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(bool value) { - if (_propertyValue == value) { - return; - } - bool from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CustomPropertyBooleanBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/custom_property_number_base.dart b/lib/src/generated/custom_property_number_base.dart deleted file mode 100644 index c41aee9..0000000 --- a/lib/src/generated/custom_property_number_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/custom_property_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/custom_property.dart'; - -abstract class CustomPropertyNumberBase extends CustomProperty { - static const int typeKey = 127; - @override - int get coreType => CustomPropertyNumberBase.typeKey; - @override - Set get coreTypes => { - CustomPropertyNumberBase.typeKey, - CustomPropertyBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 243. - static const int propertyValuePropertyKey = 243; - static const double propertyValueInitialValue = 0; - double _propertyValue = propertyValueInitialValue; - double get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(double value) { - if (_propertyValue == value) { - return; - } - double from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CustomPropertyNumberBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/custom_property_string_base.dart b/lib/src/generated/custom_property_string_base.dart deleted file mode 100644 index e9bb545..0000000 --- a/lib/src/generated/custom_property_string_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated -// lib/src/generated/custom_property_string_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/custom_property.dart'; - -abstract class CustomPropertyStringBase extends CustomProperty { - static const int typeKey = 130; - @override - int get coreType => CustomPropertyStringBase.typeKey; - @override - Set get coreTypes => { - CustomPropertyStringBase.typeKey, - CustomPropertyBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 246. - static const int propertyValuePropertyKey = 246; - static const String propertyValueInitialValue = ''; - String _propertyValue = propertyValueInitialValue; - String get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(String value) { - if (_propertyValue == value) { - return; - } - String from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CustomPropertyStringBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/bindable_property_base.dart b/lib/src/generated/data_bind/bindable_property_base.dart deleted file mode 100644 index 08199ee..0000000 --- a/lib/src/generated/data_bind/bindable_property_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class BindablePropertyBase extends Core { - static const int typeKey = 9; - @override - int get coreType => BindablePropertyBase.typeKey; - @override - Set get coreTypes => {BindablePropertyBase.typeKey}; -} diff --git a/lib/src/generated/data_bind/bindable_property_boolean_base.dart b/lib/src/generated/data_bind/bindable_property_boolean_base.dart deleted file mode 100644 index dc23e1d..0000000 --- a/lib/src/generated/data_bind/bindable_property_boolean_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_boolean_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property.dart'; - -abstract class BindablePropertyBooleanBase extends BindableProperty { - static const int typeKey = 472; - @override - int get coreType => BindablePropertyBooleanBase.typeKey; - @override - Set get coreTypes => - {BindablePropertyBooleanBase.typeKey, BindablePropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 634. - static const int propertyValuePropertyKey = 634; - static const bool propertyValueInitialValue = false; - bool _propertyValue = propertyValueInitialValue; - - /// A property of type bool that can be used for data binding. - bool get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(bool value) { - if (_propertyValue == value) { - return; - } - bool from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BindablePropertyBooleanBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/bindable_property_color_base.dart b/lib/src/generated/data_bind/bindable_property_color_base.dart deleted file mode 100644 index 60b7e36..0000000 --- a/lib/src/generated/data_bind/bindable_property_color_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_color_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property.dart'; - -abstract class BindablePropertyColorBase extends BindableProperty { - static const int typeKey = 475; - @override - int get coreType => BindablePropertyColorBase.typeKey; - @override - Set get coreTypes => - {BindablePropertyColorBase.typeKey, BindablePropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 638. - static const int propertyValuePropertyKey = 638; - static const int propertyValueInitialValue = 0xFF1D1D1D; - int _propertyValue = propertyValueInitialValue; - - /// A property of type int that can be used for data binding. - int get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(int value) { - if (_propertyValue == value) { - return; - } - int from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BindablePropertyColorBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/bindable_property_enum_base.dart b/lib/src/generated/data_bind/bindable_property_enum_base.dart deleted file mode 100644 index d642578..0000000 --- a/lib/src/generated/data_bind/bindable_property_enum_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_enum_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property.dart'; - -abstract class BindablePropertyEnumBase extends BindableProperty { - static const int typeKey = 474; - @override - int get coreType => BindablePropertyEnumBase.typeKey; - @override - Set get coreTypes => - {BindablePropertyEnumBase.typeKey, BindablePropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 637. - static const int propertyValuePropertyKey = 637; - static const int propertyValueInitialValue = -1; - int _propertyValue = propertyValueInitialValue; - - /// The id of the enum that can be used for data binding. - int get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(int value) { - if (_propertyValue == value) { - return; - } - int from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BindablePropertyEnumBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/bindable_property_number_base.dart b/lib/src/generated/data_bind/bindable_property_number_base.dart deleted file mode 100644 index ad0a9f6..0000000 --- a/lib/src/generated/data_bind/bindable_property_number_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property.dart'; - -abstract class BindablePropertyNumberBase extends BindableProperty { - static const int typeKey = 473; - @override - int get coreType => BindablePropertyNumberBase.typeKey; - @override - Set get coreTypes => - {BindablePropertyNumberBase.typeKey, BindablePropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 636. - static const int propertyValuePropertyKey = 636; - static const double propertyValueInitialValue = 0; - double _propertyValue = propertyValueInitialValue; - - /// A property of type double that can be used for data binding. - double get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(double value) { - if (_propertyValue == value) { - return; - } - double from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BindablePropertyNumberBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/bindable_property_string_base.dart b/lib/src/generated/data_bind/bindable_property_string_base.dart deleted file mode 100644 index 0afb27d..0000000 --- a/lib/src/generated/data_bind/bindable_property_string_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/bindable_property_string_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property.dart'; - -abstract class BindablePropertyStringBase extends BindableProperty { - static const int typeKey = 471; - @override - int get coreType => BindablePropertyStringBase.typeKey; - @override - Set get coreTypes => - {BindablePropertyStringBase.typeKey, BindablePropertyBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 635. - static const int propertyValuePropertyKey = 635; - static const String propertyValueInitialValue = ''; - String _propertyValue = propertyValueInitialValue; - - /// A property of type String that can be used for data binding. - String get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(String value) { - if (_propertyValue == value) { - return; - } - String from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is BindablePropertyStringBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/data_bind/converters/data_converter_base.dart b/lib/src/generated/data_bind/converters/data_converter_base.dart deleted file mode 100644 index 2c5624f..0000000 --- a/lib/src/generated/data_bind/converters/data_converter_base.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/converters/data_converter_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class DataConverterBase extends Core { - static const int typeKey = 488; - @override - int get coreType => DataConverterBase.typeKey; - @override - Set get coreTypes => {DataConverterBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 662. - static const int namePropertyKey = 662; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Non-unique identifier, used to give friendly names to data converters. - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DataConverterBase) { - _name = source._name; - } - } -} diff --git a/lib/src/generated/data_bind/data_bind_base.dart b/lib/src/generated/data_bind/data_bind_base.dart deleted file mode 100644 index 221ca9d..0000000 --- a/lib/src/generated/data_bind/data_bind_base.dart +++ /dev/null @@ -1,95 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/data_bind_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class DataBindBase extends Core { - static const int typeKey = 446; - @override - int get coreType => DataBindBase.typeKey; - @override - Set get coreTypes => {DataBindBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyKey field with key 586. - static const int propertyKeyPropertyKey = 586; - static const int propertyKeyInitialValue = CoreContext.invalidPropertyKey; - int _propertyKey = propertyKeyInitialValue; - - /// The property that is targeted. - int get propertyKey => _propertyKey; - - /// Change the [_propertyKey] field value. - /// [propertyKeyChanged] will be invoked only if the field's value has - /// changed. - set propertyKey(int value) { - if (_propertyKey == value) { - return; - } - int from = _propertyKey; - _propertyKey = value; - if (hasValidated) { - propertyKeyChanged(from, value); - } - } - - void propertyKeyChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Flags field with key 587. - static const int flagsPropertyKey = 587; - static const int flagsInitialValue = 0; - int _flags = flagsInitialValue; - int get flags => _flags; - - /// Change the [_flags] field value. - /// [flagsChanged] will be invoked only if the field's value has changed. - set flags(int value) { - if (_flags == value) { - return; - } - int from = _flags; - _flags = value; - if (hasValidated) { - flagsChanged(from, value); - } - } - - void flagsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ConverterId field with key 660. - static const int converterIdPropertyKey = 660; - static const int converterIdInitialValue = -1; - int _converterId = converterIdInitialValue; - - /// Identifier used to link to a data converter. - int get converterId => _converterId; - - /// Change the [_converterId] field value. - /// [converterIdChanged] will be invoked only if the field's value has - /// changed. - set converterId(int value) { - if (_converterId == value) { - return; - } - int from = _converterId; - _converterId = value; - if (hasValidated) { - converterIdChanged(from, value); - } - } - - void converterIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DataBindBase) { - _propertyKey = source._propertyKey; - _flags = source._flags; - _converterId = source._converterId; - } - } -} diff --git a/lib/src/generated/data_bind/data_bind_context_base.dart b/lib/src/generated/data_bind/data_bind_context_base.dart deleted file mode 100644 index b6ac440..0000000 --- a/lib/src/generated/data_bind/data_bind_context_base.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Core automatically generated -// lib/src/generated/data_bind/data_bind_context_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind.dart'; - -abstract class DataBindContextBase extends DataBind { - static const int typeKey = 447; - @override - int get coreType => DataBindContextBase.typeKey; - @override - Set get coreTypes => {DataBindContextBase.typeKey, DataBindBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// SourcePathIds field with key 588. - static const int sourcePathIdsPropertyKey = 588; - static final Uint8List sourcePathIdsInitialValue = Uint8List(0); - Uint8List _sourcePathIds = sourcePathIdsInitialValue; - - /// Path to the selected property. - Uint8List get sourcePathIds => _sourcePathIds; - - /// Change the [_sourcePathIds] field value. - /// [sourcePathIdsChanged] will be invoked only if the field's value has - /// changed. - set sourcePathIds(Uint8List value) { - if (listEquals(_sourcePathIds, value)) { - return; - } - Uint8List from = _sourcePathIds; - _sourcePathIds = value; - if (hasValidated) { - sourcePathIdsChanged(from, value); - } - } - - void sourcePathIdsChanged(Uint8List from, Uint8List to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DataBindContextBase) { - _sourcePathIds = source._sourcePathIds; - } - } -} diff --git a/lib/src/generated/draw_rules_base.dart b/lib/src/generated/draw_rules_base.dart deleted file mode 100644 index 46a81fd..0000000 --- a/lib/src/generated/draw_rules_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated lib/src/generated/draw_rules_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class DrawRulesBase extends ContainerComponent { - static const int typeKey = 49; - @override - int get coreType => DrawRulesBase.typeKey; - @override - Set get coreTypes => { - DrawRulesBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// DrawTargetId field with key 121. - static const int drawTargetIdPropertyKey = 121; - static const int drawTargetIdInitialValue = -1; - int _drawTargetId = drawTargetIdInitialValue; - - /// Id of the DrawTarget that is currently active for this set of rules. - int get drawTargetId => _drawTargetId; - - /// Change the [_drawTargetId] field value. - /// [drawTargetIdChanged] will be invoked only if the field's value has - /// changed. - set drawTargetId(int value) { - if (_drawTargetId == value) { - return; - } - int from = _drawTargetId; - _drawTargetId = value; - if (hasValidated) { - drawTargetIdChanged(from, value); - } - } - - void drawTargetIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DrawRulesBase) { - _drawTargetId = source._drawTargetId; - } - } -} diff --git a/lib/src/generated/draw_target_base.dart b/lib/src/generated/draw_target_base.dart deleted file mode 100644 index af1d767..0000000 --- a/lib/src/generated/draw_target_base.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Core automatically generated lib/src/generated/draw_target_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class DrawTargetBase extends Component { - static const int typeKey = 48; - @override - int get coreType => DrawTargetBase.typeKey; - @override - Set get coreTypes => {DrawTargetBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// DrawableId field with key 119. - static const int drawableIdPropertyKey = 119; - static const int drawableIdInitialValue = -1; - int _drawableId = drawableIdInitialValue; - - /// Id of the drawable this target references. - int get drawableId => _drawableId; - - /// Change the [_drawableId] field value. - /// [drawableIdChanged] will be invoked only if the field's value has changed. - set drawableId(int value) { - if (_drawableId == value) { - return; - } - int from = _drawableId; - _drawableId = value; - if (hasValidated) { - drawableIdChanged(from, value); - } - } - - void drawableIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PlacementValue field with key 120. - static const int placementValuePropertyKey = 120; - static const int placementValueInitialValue = 0; - int _placementValue = placementValueInitialValue; - - /// Backing enum value for the Placement. - int get placementValue => _placementValue; - - /// Change the [_placementValue] field value. - /// [placementValueChanged] will be invoked only if the field's value has - /// changed. - set placementValue(int value) { - if (_placementValue == value) { - return; - } - int from = _placementValue; - _placementValue = value; - if (hasValidated) { - placementValueChanged(from, value); - } - } - - void placementValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DrawTargetBase) { - _drawableId = source._drawableId; - _placementValue = source._placementValue; - } - } -} diff --git a/lib/src/generated/drawable_base.dart b/lib/src/generated/drawable_base.dart deleted file mode 100644 index 30507fd..0000000 --- a/lib/src/generated/drawable_base.dart +++ /dev/null @@ -1,79 +0,0 @@ -// Core automatically generated lib/src/generated/drawable_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/node.dart'; - -abstract class DrawableBase extends Node { - static const int typeKey = 13; - @override - int get coreType => DrawableBase.typeKey; - @override - Set get coreTypes => { - DrawableBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// BlendModeValue field with key 23. - static const int blendModeValuePropertyKey = 23; - static const int blendModeValueInitialValue = 3; - int _blendModeValue = blendModeValueInitialValue; - int get blendModeValue => _blendModeValue; - - /// Change the [_blendModeValue] field value. - /// [blendModeValueChanged] will be invoked only if the field's value has - /// changed. - set blendModeValue(int value) { - if (_blendModeValue == value) { - return; - } - int from = _blendModeValue; - _blendModeValue = value; - if (hasValidated) { - blendModeValueChanged(from, value); - } - } - - void blendModeValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// DrawableFlags field with key 129. - static const int drawableFlagsPropertyKey = 129; - static const int drawableFlagsInitialValue = 0; - int _drawableFlags = drawableFlagsInitialValue; - int get drawableFlags => _drawableFlags; - - /// Change the [_drawableFlags] field value. - /// [drawableFlagsChanged] will be invoked only if the field's value has - /// changed. - set drawableFlags(int value) { - if (_drawableFlags == value) { - return; - } - int from = _drawableFlags; - _drawableFlags = value; - if (hasValidated) { - drawableFlagsChanged(from, value); - } - } - - void drawableFlagsChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DrawableBase) { - _blendModeValue = source._blendModeValue; - _drawableFlags = source._drawableFlags; - } - } -} diff --git a/lib/src/generated/event_base.dart b/lib/src/generated/event_base.dart deleted file mode 100644 index 238ed61..0000000 --- a/lib/src/generated/event_base.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Core automatically generated lib/src/generated/event_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class EventBase extends ContainerComponent { - static const int typeKey = 128; - @override - int get coreType => EventBase.typeKey; - @override - Set get coreTypes => { - EventBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Trigger field with key 395. - static const int triggerPropertyKey = 395; - void trigger(CallbackData value); -} diff --git a/lib/src/generated/joystick_base.dart b/lib/src/generated/joystick_base.dart deleted file mode 100644 index bb0ef06..0000000 --- a/lib/src/generated/joystick_base.dart +++ /dev/null @@ -1,310 +0,0 @@ -// Core automatically generated lib/src/generated/joystick_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class JoystickBase extends Component { - static const int typeKey = 148; - @override - int get coreType => JoystickBase.typeKey; - @override - Set get coreTypes => {JoystickBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// X field with key 299. - static const int xPropertyKey = 299; - static const double xInitialValue = 0; - double _x = xInitialValue; - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 300. - static const int yPropertyKey = 300; - static const double yInitialValue = 0; - double _y = yInitialValue; - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PosX field with key 303. - static const int posXPropertyKey = 303; - static const double posXInitialValue = 0; - double _posX = posXInitialValue; - double get posX => _posX; - - /// Change the [_posX] field value. - /// [posXChanged] will be invoked only if the field's value has changed. - set posX(double value) { - if (_posX == value) { - return; - } - double from = _posX; - _posX = value; - if (hasValidated) { - posXChanged(from, value); - } - } - - void posXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PosY field with key 304. - static const int posYPropertyKey = 304; - static const double posYInitialValue = 0; - double _posY = posYInitialValue; - double get posY => _posY; - - /// Change the [_posY] field value. - /// [posYChanged] will be invoked only if the field's value has changed. - set posY(double value) { - if (_posY == value) { - return; - } - double from = _posY; - _posY = value; - if (hasValidated) { - posYChanged(from, value); - } - } - - void posYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 307. - static const int originXPropertyKey = 307; - static const double originXInitialValue = 0.5; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 308. - static const int originYPropertyKey = 308; - static const double originYInitialValue = 0.5; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Width field with key 305. - static const int widthPropertyKey = 305; - static const double widthInitialValue = 100; - double _width = widthInitialValue; - double get width => _width; - - /// Change the [_width] field value. - /// [widthChanged] will be invoked only if the field's value has changed. - set width(double value) { - if (_width == value) { - return; - } - double from = _width; - _width = value; - if (hasValidated) { - widthChanged(from, value); - } - } - - void widthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Height field with key 306. - static const int heightPropertyKey = 306; - static const double heightInitialValue = 100; - double _height = heightInitialValue; - double get height => _height; - - /// Change the [_height] field value. - /// [heightChanged] will be invoked only if the field's value has changed. - set height(double value) { - if (_height == value) { - return; - } - double from = _height; - _height = value; - if (hasValidated) { - heightChanged(from, value); - } - } - - void heightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// XId field with key 301. - static const int xIdPropertyKey = 301; - static const int xIdInitialValue = -1; - int _xId = xIdInitialValue; - - /// Identifier used to track the animation used for the x axis of the - /// joystick. - int get xId => _xId; - - /// Change the [_xId] field value. - /// [xIdChanged] will be invoked only if the field's value has changed. - set xId(int value) { - if (_xId == value) { - return; - } - int from = _xId; - _xId = value; - if (hasValidated) { - xIdChanged(from, value); - } - } - - void xIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// YId field with key 302. - static const int yIdPropertyKey = 302; - static const int yIdInitialValue = -1; - int _yId = yIdInitialValue; - - /// Identifier used to track the animation used for the y axis of the - /// joystick. - int get yId => _yId; - - /// Change the [_yId] field value. - /// [yIdChanged] will be invoked only if the field's value has changed. - set yId(int value) { - if (_yId == value) { - return; - } - int from = _yId; - _yId = value; - if (hasValidated) { - yIdChanged(from, value); - } - } - - void yIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// JoystickFlags field with key 312. - static const int joystickFlagsPropertyKey = 312; - static const int joystickFlagsInitialValue = 0; - int _joystickFlags = joystickFlagsInitialValue; - int get joystickFlags => _joystickFlags; - - /// Change the [_joystickFlags] field value. - /// [joystickFlagsChanged] will be invoked only if the field's value has - /// changed. - set joystickFlags(int value) { - if (_joystickFlags == value) { - return; - } - int from = _joystickFlags; - _joystickFlags = value; - if (hasValidated) { - joystickFlagsChanged(from, value); - } - } - - void joystickFlagsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// HandleSourceId field with key 313. - static const int handleSourceIdPropertyKey = 313; - static const int handleSourceIdInitialValue = -1; - int _handleSourceId = handleSourceIdInitialValue; - - /// Identifier used to track the custom handle source of the joystick. - int get handleSourceId => _handleSourceId; - - /// Change the [_handleSourceId] field value. - /// [handleSourceIdChanged] will be invoked only if the field's value has - /// changed. - set handleSourceId(int value) { - if (_handleSourceId == value) { - return; - } - int from = _handleSourceId; - _handleSourceId = value; - if (hasValidated) { - handleSourceIdChanged(from, value); - } - } - - void handleSourceIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is JoystickBase) { - _x = source._x; - _y = source._y; - _posX = source._posX; - _posY = source._posY; - _originX = source._originX; - _originY = source._originY; - _width = source._width; - _height = source._height; - _xId = source._xId; - _yId = source._yId; - _joystickFlags = source._joystickFlags; - _handleSourceId = source._handleSourceId; - } - } -} diff --git a/lib/src/generated/layout/grid_track_sizing_group_base.dart b/lib/src/generated/layout/grid_track_sizing_group_base.dart deleted file mode 100644 index 956993c..0000000 --- a/lib/src/generated/layout/grid_track_sizing_group_base.dart +++ /dev/null @@ -1,129 +0,0 @@ -// Core automatically generated -// lib/src/generated/layout/grid_track_sizing_group_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class GridTrackSizingGroupBase extends ContainerComponent { - static const int typeKey = 177; - @override - int get coreType => GridTrackSizingGroupBase.typeKey; - @override - Set get coreTypes => { - GridTrackSizingGroupBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// TrackTag field with key 465. - static const int trackTagPropertyKey = 465; - static const int trackTagInitialValue = 0; - int _trackTag = trackTagInitialValue; - - /// Track type (templateRow|templateColumn|autoRow|autoColumn). - int get trackTag => _trackTag; - - /// Change the [_trackTag] field value. - /// [trackTagChanged] will be invoked only if the field's value has changed. - set trackTag(int value) { - if (_trackTag == value) { - return; - } - int from = _trackTag; - _trackTag = value; - if (hasValidated) { - trackTagChanged(from, value); - } - } - - void trackTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// IsRepeating field with key 466. - static const int isRepeatingPropertyKey = 466; - static const bool isRepeatingInitialValue = false; - bool _isRepeating = isRepeatingInitialValue; - - /// Whether this sizing function repeats. If no, ignore repeatTag and - /// repeatCount and use the first item in the sizingFunctions list. - bool get isRepeating => _isRepeating; - - /// Change the [_isRepeating] field value. - /// [isRepeatingChanged] will be invoked only if the field's value has - /// changed. - set isRepeating(bool value) { - if (_isRepeating == value) { - return; - } - bool from = _isRepeating; - _isRepeating = value; - if (hasValidated) { - isRepeatingChanged(from, value); - } - } - - void isRepeatingChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// RepeatTag field with key 467. - static const int repeatTagPropertyKey = 467; - static const int repeatTagInitialValue = 0; - int _repeatTag = repeatTagInitialValue; - - /// Repeat tag (autoFill|autoFit|count). - int get repeatTag => _repeatTag; - - /// Change the [_repeatTag] field value. - /// [repeatTagChanged] will be invoked only if the field's value has changed. - set repeatTag(int value) { - if (_repeatTag == value) { - return; - } - int from = _repeatTag; - _repeatTag = value; - if (hasValidated) { - repeatTagChanged(from, value); - } - } - - void repeatTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// RepeatCount field with key 468. - static const int repeatCountPropertyKey = 468; - static const int repeatCountInitialValue = 0; - int _repeatCount = repeatCountInitialValue; - - /// Number of times to repeat if repeatTag is set to count - int get repeatCount => _repeatCount; - - /// Change the [_repeatCount] field value. - /// [repeatCountChanged] will be invoked only if the field's value has - /// changed. - set repeatCount(int value) { - if (_repeatCount == value) { - return; - } - int from = _repeatCount; - _repeatCount = value; - if (hasValidated) { - repeatCountChanged(from, value); - } - } - - void repeatCountChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is GridTrackSizingGroupBase) { - _trackTag = source._trackTag; - _isRepeating = source._isRepeating; - _repeatTag = source._repeatTag; - _repeatCount = source._repeatCount; - } - } -} diff --git a/lib/src/generated/layout/layout_component_style_base.dart b/lib/src/generated/layout/layout_component_style_base.dart deleted file mode 100644 index 484d891..0000000 --- a/lib/src/generated/layout/layout_component_style_base.dart +++ /dev/null @@ -1,1773 +0,0 @@ -// Core automatically generated -// lib/src/generated/layout/layout_component_style_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class LayoutComponentStyleBase extends Component { - static const int typeKey = 420; - @override - int get coreType => LayoutComponentStyleBase.typeKey; - @override - Set get coreTypes => - {LayoutComponentStyleBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// GapHorizontal field with key 498. - static const int gapHorizontalPropertyKey = 498; - static const double gapHorizontalInitialValue = 0; - double _gapHorizontal = gapHorizontalInitialValue; - - /// Horizontal gap between children in layout component - double get gapHorizontal => _gapHorizontal; - - /// Change the [_gapHorizontal] field value. - /// [gapHorizontalChanged] will be invoked only if the field's value has - /// changed. - set gapHorizontal(double value) { - if (_gapHorizontal == value) { - return; - } - double from = _gapHorizontal; - _gapHorizontal = value; - if (hasValidated) { - gapHorizontalChanged(from, value); - } - } - - void gapHorizontalChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// GapVertical field with key 499. - static const int gapVerticalPropertyKey = 499; - static const double gapVerticalInitialValue = 0; - double _gapVertical = gapVerticalInitialValue; - - /// Vertical gap between children in layout component - double get gapVertical => _gapVertical; - - /// Change the [_gapVertical] field value. - /// [gapVerticalChanged] will be invoked only if the field's value has - /// changed. - set gapVertical(double value) { - if (_gapVertical == value) { - return; - } - double from = _gapVertical; - _gapVertical = value; - if (hasValidated) { - gapVerticalChanged(from, value); - } - } - - void gapVerticalChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MaxWidth field with key 500. - static const int maxWidthPropertyKey = 500; - static const double maxWidthInitialValue = 0; - double _maxWidth = maxWidthInitialValue; - - /// Max width of the item. - double get maxWidth => _maxWidth; - - /// Change the [_maxWidth] field value. - /// [maxWidthChanged] will be invoked only if the field's value has changed. - set maxWidth(double value) { - if (_maxWidth == value) { - return; - } - double from = _maxWidth; - _maxWidth = value; - if (hasValidated) { - maxWidthChanged(from, value); - } - } - - void maxWidthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MaxHeight field with key 501. - static const int maxHeightPropertyKey = 501; - static const double maxHeightInitialValue = 0; - double _maxHeight = maxHeightInitialValue; - - /// Max height of the item. - double get maxHeight => _maxHeight; - - /// Change the [_maxHeight] field value. - /// [maxHeightChanged] will be invoked only if the field's value has changed. - set maxHeight(double value) { - if (_maxHeight == value) { - return; - } - double from = _maxHeight; - _maxHeight = value; - if (hasValidated) { - maxHeightChanged(from, value); - } - } - - void maxHeightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MinWidth field with key 502. - static const int minWidthPropertyKey = 502; - static const double minWidthInitialValue = 0; - double _minWidth = minWidthInitialValue; - - /// Min width of the item. - double get minWidth => _minWidth; - - /// Change the [_minWidth] field value. - /// [minWidthChanged] will be invoked only if the field's value has changed. - set minWidth(double value) { - if (_minWidth == value) { - return; - } - double from = _minWidth; - _minWidth = value; - if (hasValidated) { - minWidthChanged(from, value); - } - } - - void minWidthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MinHeight field with key 503. - static const int minHeightPropertyKey = 503; - static const double minHeightInitialValue = 0; - double _minHeight = minHeightInitialValue; - - /// Min height of the item. - double get minHeight => _minHeight; - - /// Change the [_minHeight] field value. - /// [minHeightChanged] will be invoked only if the field's value has changed. - set minHeight(double value) { - if (_minHeight == value) { - return; - } - double from = _minHeight; - _minHeight = value; - if (hasValidated) { - minHeightChanged(from, value); - } - } - - void minHeightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// BorderLeft field with key 504. - static const int borderLeftPropertyKey = 504; - static const double borderLeftInitialValue = 0; - double _borderLeft = borderLeftInitialValue; - - /// Left border value. - double get borderLeft => _borderLeft; - - /// Change the [_borderLeft] field value. - /// [borderLeftChanged] will be invoked only if the field's value has changed. - set borderLeft(double value) { - if (_borderLeft == value) { - return; - } - double from = _borderLeft; - _borderLeft = value; - if (hasValidated) { - borderLeftChanged(from, value); - } - } - - void borderLeftChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// BorderRight field with key 505. - static const int borderRightPropertyKey = 505; - static const double borderRightInitialValue = 0; - double _borderRight = borderRightInitialValue; - - /// Right border value. - double get borderRight => _borderRight; - - /// Change the [_borderRight] field value. - /// [borderRightChanged] will be invoked only if the field's value has - /// changed. - set borderRight(double value) { - if (_borderRight == value) { - return; - } - double from = _borderRight; - _borderRight = value; - if (hasValidated) { - borderRightChanged(from, value); - } - } - - void borderRightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// BorderTop field with key 506. - static const int borderTopPropertyKey = 506; - static const double borderTopInitialValue = 0; - double _borderTop = borderTopInitialValue; - - /// Top border value. - double get borderTop => _borderTop; - - /// Change the [_borderTop] field value. - /// [borderTopChanged] will be invoked only if the field's value has changed. - set borderTop(double value) { - if (_borderTop == value) { - return; - } - double from = _borderTop; - _borderTop = value; - if (hasValidated) { - borderTopChanged(from, value); - } - } - - void borderTopChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// BorderBottom field with key 507. - static const int borderBottomPropertyKey = 507; - static const double borderBottomInitialValue = 0; - double _borderBottom = borderBottomInitialValue; - - /// Bottom border value. - double get borderBottom => _borderBottom; - - /// Change the [_borderBottom] field value. - /// [borderBottomChanged] will be invoked only if the field's value has - /// changed. - set borderBottom(double value) { - if (_borderBottom == value) { - return; - } - double from = _borderBottom; - _borderBottom = value; - if (hasValidated) { - borderBottomChanged(from, value); - } - } - - void borderBottomChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MarginLeft field with key 508. - static const int marginLeftPropertyKey = 508; - static const double marginLeftInitialValue = 0; - double _marginLeft = marginLeftInitialValue; - - /// Left margin value. - double get marginLeft => _marginLeft; - - /// Change the [_marginLeft] field value. - /// [marginLeftChanged] will be invoked only if the field's value has changed. - set marginLeft(double value) { - if (_marginLeft == value) { - return; - } - double from = _marginLeft; - _marginLeft = value; - if (hasValidated) { - marginLeftChanged(from, value); - } - } - - void marginLeftChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MarginRight field with key 509. - static const int marginRightPropertyKey = 509; - static const double marginRightInitialValue = 0; - double _marginRight = marginRightInitialValue; - - /// Right margin value. - double get marginRight => _marginRight; - - /// Change the [_marginRight] field value. - /// [marginRightChanged] will be invoked only if the field's value has - /// changed. - set marginRight(double value) { - if (_marginRight == value) { - return; - } - double from = _marginRight; - _marginRight = value; - if (hasValidated) { - marginRightChanged(from, value); - } - } - - void marginRightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MarginTop field with key 510. - static const int marginTopPropertyKey = 510; - static const double marginTopInitialValue = 0; - double _marginTop = marginTopInitialValue; - - /// Top margin value. - double get marginTop => _marginTop; - - /// Change the [_marginTop] field value. - /// [marginTopChanged] will be invoked only if the field's value has changed. - set marginTop(double value) { - if (_marginTop == value) { - return; - } - double from = _marginTop; - _marginTop = value; - if (hasValidated) { - marginTopChanged(from, value); - } - } - - void marginTopChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MarginBottom field with key 511. - static const int marginBottomPropertyKey = 511; - static const double marginBottomInitialValue = 0; - double _marginBottom = marginBottomInitialValue; - - /// Bottom margin value. - double get marginBottom => _marginBottom; - - /// Change the [_marginBottom] field value. - /// [marginBottomChanged] will be invoked only if the field's value has - /// changed. - set marginBottom(double value) { - if (_marginBottom == value) { - return; - } - double from = _marginBottom; - _marginBottom = value; - if (hasValidated) { - marginBottomChanged(from, value); - } - } - - void marginBottomChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PaddingLeft field with key 512. - static const int paddingLeftPropertyKey = 512; - static const double paddingLeftInitialValue = 0; - double _paddingLeft = paddingLeftInitialValue; - - /// Left padding value. - double get paddingLeft => _paddingLeft; - - /// Change the [_paddingLeft] field value. - /// [paddingLeftChanged] will be invoked only if the field's value has - /// changed. - set paddingLeft(double value) { - if (_paddingLeft == value) { - return; - } - double from = _paddingLeft; - _paddingLeft = value; - if (hasValidated) { - paddingLeftChanged(from, value); - } - } - - void paddingLeftChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PaddingRight field with key 513. - static const int paddingRightPropertyKey = 513; - static const double paddingRightInitialValue = 0; - double _paddingRight = paddingRightInitialValue; - - /// Right padding value. - double get paddingRight => _paddingRight; - - /// Change the [_paddingRight] field value. - /// [paddingRightChanged] will be invoked only if the field's value has - /// changed. - set paddingRight(double value) { - if (_paddingRight == value) { - return; - } - double from = _paddingRight; - _paddingRight = value; - if (hasValidated) { - paddingRightChanged(from, value); - } - } - - void paddingRightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PaddingTop field with key 514. - static const int paddingTopPropertyKey = 514; - static const double paddingTopInitialValue = 0; - double _paddingTop = paddingTopInitialValue; - - /// Top padding value. - double get paddingTop => _paddingTop; - - /// Change the [_paddingTop] field value. - /// [paddingTopChanged] will be invoked only if the field's value has changed. - set paddingTop(double value) { - if (_paddingTop == value) { - return; - } - double from = _paddingTop; - _paddingTop = value; - if (hasValidated) { - paddingTopChanged(from, value); - } - } - - void paddingTopChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PaddingBottom field with key 515. - static const int paddingBottomPropertyKey = 515; - static const double paddingBottomInitialValue = 0; - double _paddingBottom = paddingBottomInitialValue; - - /// Bottom padding value. - double get paddingBottom => _paddingBottom; - - /// Change the [_paddingBottom] field value. - /// [paddingBottomChanged] will be invoked only if the field's value has - /// changed. - set paddingBottom(double value) { - if (_paddingBottom == value) { - return; - } - double from = _paddingBottom; - _paddingBottom = value; - if (hasValidated) { - paddingBottomChanged(from, value); - } - } - - void paddingBottomChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PositionLeft field with key 516. - static const int positionLeftPropertyKey = 516; - static const double positionLeftInitialValue = 0; - double _positionLeft = positionLeftInitialValue; - - /// Left position value. - double get positionLeft => _positionLeft; - - /// Change the [_positionLeft] field value. - /// [positionLeftChanged] will be invoked only if the field's value has - /// changed. - set positionLeft(double value) { - if (_positionLeft == value) { - return; - } - double from = _positionLeft; - _positionLeft = value; - if (hasValidated) { - positionLeftChanged(from, value); - } - } - - void positionLeftChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PositionRight field with key 517. - static const int positionRightPropertyKey = 517; - static const double positionRightInitialValue = 0; - double _positionRight = positionRightInitialValue; - - /// Right position value. - double get positionRight => _positionRight; - - /// Change the [_positionRight] field value. - /// [positionRightChanged] will be invoked only if the field's value has - /// changed. - set positionRight(double value) { - if (_positionRight == value) { - return; - } - double from = _positionRight; - _positionRight = value; - if (hasValidated) { - positionRightChanged(from, value); - } - } - - void positionRightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PositionTop field with key 518. - static const int positionTopPropertyKey = 518; - static const double positionTopInitialValue = 0; - double _positionTop = positionTopInitialValue; - - /// Top position value. - double get positionTop => _positionTop; - - /// Change the [_positionTop] field value. - /// [positionTopChanged] will be invoked only if the field's value has - /// changed. - set positionTop(double value) { - if (_positionTop == value) { - return; - } - double from = _positionTop; - _positionTop = value; - if (hasValidated) { - positionTopChanged(from, value); - } - } - - void positionTopChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// PositionBottom field with key 519. - static const int positionBottomPropertyKey = 519; - static const double positionBottomInitialValue = 0; - double _positionBottom = positionBottomInitialValue; - - /// Bottom position value. - double get positionBottom => _positionBottom; - - /// Change the [_positionBottom] field value. - /// [positionBottomChanged] will be invoked only if the field's value has - /// changed. - set positionBottom(double value) { - if (_positionBottom == value) { - return; - } - double from = _positionBottom; - _positionBottom = value; - if (hasValidated) { - positionBottomChanged(from, value); - } - } - - void positionBottomChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Flex field with key 520. - static const int flexPropertyKey = 520; - static const double flexInitialValue = 0; - double _flex = flexInitialValue; - - /// Flex value. - double get flex => _flex; - - /// Change the [_flex] field value. - /// [flexChanged] will be invoked only if the field's value has changed. - set flex(double value) { - if (_flex == value) { - return; - } - double from = _flex; - _flex = value; - if (hasValidated) { - flexChanged(from, value); - } - } - - void flexChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// FlexGrow field with key 521. - static const int flexGrowPropertyKey = 521; - static const double flexGrowInitialValue = 0; - double _flexGrow = flexGrowInitialValue; - - /// Flex grow value. - double get flexGrow => _flexGrow; - - /// Change the [_flexGrow] field value. - /// [flexGrowChanged] will be invoked only if the field's value has changed. - set flexGrow(double value) { - if (_flexGrow == value) { - return; - } - double from = _flexGrow; - _flexGrow = value; - if (hasValidated) { - flexGrowChanged(from, value); - } - } - - void flexGrowChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// FlexShrink field with key 522. - static const int flexShrinkPropertyKey = 522; - static const double flexShrinkInitialValue = 1; - double _flexShrink = flexShrinkInitialValue; - - /// Flex shrink value. - double get flexShrink => _flexShrink; - - /// Change the [_flexShrink] field value. - /// [flexShrinkChanged] will be invoked only if the field's value has changed. - set flexShrink(double value) { - if (_flexShrink == value) { - return; - } - double from = _flexShrink; - _flexShrink = value; - if (hasValidated) { - flexShrinkChanged(from, value); - } - } - - void flexShrinkChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// FlexBasis field with key 523. - static const int flexBasisPropertyKey = 523; - static const double flexBasisInitialValue = 1; - double _flexBasis = flexBasisInitialValue; - - /// Flex basis value. - double get flexBasis => _flexBasis; - - /// Change the [_flexBasis] field value. - /// [flexBasisChanged] will be invoked only if the field's value has changed. - set flexBasis(double value) { - if (_flexBasis == value) { - return; - } - double from = _flexBasis; - _flexBasis = value; - if (hasValidated) { - flexBasisChanged(from, value); - } - } - - void flexBasisChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// AspectRatio field with key 524. - static const int aspectRatioPropertyKey = 524; - static const double aspectRatioInitialValue = 0; - double _aspectRatio = aspectRatioInitialValue; - - /// Aspect ratio value. - double get aspectRatio => _aspectRatio; - - /// Change the [_aspectRatio] field value. - /// [aspectRatioChanged] will be invoked only if the field's value has - /// changed. - set aspectRatio(double value) { - if (_aspectRatio == value) { - return; - } - double from = _aspectRatio; - _aspectRatio = value; - if (hasValidated) { - aspectRatioChanged(from, value); - } - } - - void aspectRatioChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ScaleType field with key 546. - static const int scaleTypePropertyKey = 546; - static const int scaleTypeInitialValue = 0; - int _scaleType = scaleTypeInitialValue; - int get scaleType => _scaleType; - - /// Change the [_scaleType] field value. - /// [scaleTypeChanged] will be invoked only if the field's value has changed. - set scaleType(int value) { - if (_scaleType == value) { - return; - } - int from = _scaleType; - _scaleType = value; - if (hasValidated) { - scaleTypeChanged(from, value); - } - } - - void scaleTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// LayoutAlignmentType field with key 632. - static const int layoutAlignmentTypePropertyKey = 632; - static const int layoutAlignmentTypeInitialValue = 0; - int _layoutAlignmentType = layoutAlignmentTypeInitialValue; - int get layoutAlignmentType => _layoutAlignmentType; - - /// Change the [_layoutAlignmentType] field value. - /// [layoutAlignmentTypeChanged] will be invoked only if the field's value has - /// changed. - set layoutAlignmentType(int value) { - if (_layoutAlignmentType == value) { - return; - } - int from = _layoutAlignmentType; - _layoutAlignmentType = value; - if (hasValidated) { - layoutAlignmentTypeChanged(from, value); - } - } - - void layoutAlignmentTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AnimationStyleType field with key 589. - static const int animationStyleTypePropertyKey = 589; - static const int animationStyleTypeInitialValue = 0; - int _animationStyleType = animationStyleTypeInitialValue; - - /// The type of animation none|custom|inherit applied to this layout. - int get animationStyleType => _animationStyleType; - - /// Change the [_animationStyleType] field value. - /// [animationStyleTypeChanged] will be invoked only if the field's value has - /// changed. - set animationStyleType(int value) { - if (_animationStyleType == value) { - return; - } - int from = _animationStyleType; - _animationStyleType = value; - if (hasValidated) { - animationStyleTypeChanged(from, value); - } - } - - void animationStyleTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolationType field with key 590. - static const int interpolationTypePropertyKey = 590; - static const int interpolationTypeInitialValue = 0; - int _interpolationType = interpolationTypeInitialValue; - - /// The type of interpolation index in KeyframeInterpolation applied to this - /// layout. - int get interpolationType => _interpolationType; - - /// Change the [_interpolationType] field value. - /// [interpolationTypeChanged] will be invoked only if the field's value has - /// changed. - set interpolationType(int value) { - if (_interpolationType == value) { - return; - } - int from = _interpolationType; - _interpolationType = value; - if (hasValidated) { - interpolationTypeChanged(from, value); - } - } - - void interpolationTypeChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolatorId field with key 591. - static const int interpolatorIdPropertyKey = 591; - static const int interpolatorIdInitialValue = -1; - int _interpolatorId = interpolatorIdInitialValue; - - /// The id of the custom interpolator used when interpolation is Cubic. - int get interpolatorId => _interpolatorId; - - /// Change the [_interpolatorId] field value. - /// [interpolatorIdChanged] will be invoked only if the field's value has - /// changed. - set interpolatorId(int value) { - if (_interpolatorId == value) { - return; - } - int from = _interpolatorId; - _interpolatorId = value; - if (hasValidated) { - interpolatorIdChanged(from, value); - } - } - - void interpolatorIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// InterpolationTime field with key 592. - static const int interpolationTimePropertyKey = 592; - static const double interpolationTimeInitialValue = 0; - double _interpolationTime = interpolationTimeInitialValue; - - /// The time over which the interpolator applies. - double get interpolationTime => _interpolationTime; - - /// Change the [_interpolationTime] field value. - /// [interpolationTimeChanged] will be invoked only if the field's value has - /// changed. - set interpolationTime(double value) { - if (_interpolationTime == value) { - return; - } - double from = _interpolationTime; - _interpolationTime = value; - if (hasValidated) { - interpolationTimeChanged(from, value); - } - } - - void interpolationTimeChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// DisplayValue field with key 596. - static const int displayValuePropertyKey = 596; - static const int displayValueInitialValue = 0; - int _displayValue = displayValueInitialValue; - - /// - int get displayValue => _displayValue; - - /// Change the [_displayValue] field value. - /// [displayValueChanged] will be invoked only if the field's value has - /// changed. - set displayValue(int value) { - if (_displayValue == value) { - return; - } - int from = _displayValue; - _displayValue = value; - if (hasValidated) { - displayValueChanged(from, value); - } - } - - void displayValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PositionTypeValue field with key 597. - static const int positionTypeValuePropertyKey = 597; - static const int positionTypeValueInitialValue = 1; - int _positionTypeValue = positionTypeValueInitialValue; - - /// - int get positionTypeValue => _positionTypeValue; - - /// Change the [_positionTypeValue] field value. - /// [positionTypeValueChanged] will be invoked only if the field's value has - /// changed. - set positionTypeValue(int value) { - if (_positionTypeValue == value) { - return; - } - int from = _positionTypeValue; - _positionTypeValue = value; - if (hasValidated) { - positionTypeValueChanged(from, value); - } - } - - void positionTypeValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// FlexDirectionValue field with key 598. - static const int flexDirectionValuePropertyKey = 598; - static const int flexDirectionValueInitialValue = 2; - int _flexDirectionValue = flexDirectionValueInitialValue; - - /// Flex dir - int get flexDirectionValue => _flexDirectionValue; - - /// Change the [_flexDirectionValue] field value. - /// [flexDirectionValueChanged] will be invoked only if the field's value has - /// changed. - set flexDirectionValue(int value) { - if (_flexDirectionValue == value) { - return; - } - int from = _flexDirectionValue; - _flexDirectionValue = value; - if (hasValidated) { - flexDirectionValueChanged(from, value); - } - } - - void flexDirectionValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// DirectionValue field with key 599. - static const int directionValuePropertyKey = 599; - static const int directionValueInitialValue = 0; - int _directionValue = directionValueInitialValue; - - /// - int get directionValue => _directionValue; - - /// Change the [_directionValue] field value. - /// [directionValueChanged] will be invoked only if the field's value has - /// changed. - set directionValue(int value) { - if (_directionValue == value) { - return; - } - int from = _directionValue; - _directionValue = value; - if (hasValidated) { - directionValueChanged(from, value); - } - } - - void directionValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AlignContentValue field with key 600. - static const int alignContentValuePropertyKey = 600; - static const int alignContentValueInitialValue = 0; - int _alignContentValue = alignContentValueInitialValue; - - /// - int get alignContentValue => _alignContentValue; - - /// Change the [_alignContentValue] field value. - /// [alignContentValueChanged] will be invoked only if the field's value has - /// changed. - set alignContentValue(int value) { - if (_alignContentValue == value) { - return; - } - int from = _alignContentValue; - _alignContentValue = value; - if (hasValidated) { - alignContentValueChanged(from, value); - } - } - - void alignContentValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AlignItemsValue field with key 601. - static const int alignItemsValuePropertyKey = 601; - static const int alignItemsValueInitialValue = 1; - int _alignItemsValue = alignItemsValueInitialValue; - - /// - int get alignItemsValue => _alignItemsValue; - - /// Change the [_alignItemsValue] field value. - /// [alignItemsValueChanged] will be invoked only if the field's value has - /// changed. - set alignItemsValue(int value) { - if (_alignItemsValue == value) { - return; - } - int from = _alignItemsValue; - _alignItemsValue = value; - if (hasValidated) { - alignItemsValueChanged(from, value); - } - } - - void alignItemsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AlignSelfValue field with key 602. - static const int alignSelfValuePropertyKey = 602; - static const int alignSelfValueInitialValue = 0; - int _alignSelfValue = alignSelfValueInitialValue; - - /// - int get alignSelfValue => _alignSelfValue; - - /// Change the [_alignSelfValue] field value. - /// [alignSelfValueChanged] will be invoked only if the field's value has - /// changed. - set alignSelfValue(int value) { - if (_alignSelfValue == value) { - return; - } - int from = _alignSelfValue; - _alignSelfValue = value; - if (hasValidated) { - alignSelfValueChanged(from, value); - } - } - - void alignSelfValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// JustifyContentValue field with key 603. - static const int justifyContentValuePropertyKey = 603; - static const int justifyContentValueInitialValue = 0; - int _justifyContentValue = justifyContentValueInitialValue; - - /// - int get justifyContentValue => _justifyContentValue; - - /// Change the [_justifyContentValue] field value. - /// [justifyContentValueChanged] will be invoked only if the field's value has - /// changed. - set justifyContentValue(int value) { - if (_justifyContentValue == value) { - return; - } - int from = _justifyContentValue; - _justifyContentValue = value; - if (hasValidated) { - justifyContentValueChanged(from, value); - } - } - - void justifyContentValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// FlexWrapValue field with key 604. - static const int flexWrapValuePropertyKey = 604; - static const int flexWrapValueInitialValue = 0; - int _flexWrapValue = flexWrapValueInitialValue; - - /// - int get flexWrapValue => _flexWrapValue; - - /// Change the [_flexWrapValue] field value. - /// [flexWrapValueChanged] will be invoked only if the field's value has - /// changed. - set flexWrapValue(int value) { - if (_flexWrapValue == value) { - return; - } - int from = _flexWrapValue; - _flexWrapValue = value; - if (hasValidated) { - flexWrapValueChanged(from, value); - } - } - - void flexWrapValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OverflowValue field with key 605. - static const int overflowValuePropertyKey = 605; - static const int overflowValueInitialValue = 0; - int _overflowValue = overflowValueInitialValue; - - /// - int get overflowValue => _overflowValue; - - /// Change the [_overflowValue] field value. - /// [overflowValueChanged] will be invoked only if the field's value has - /// changed. - set overflowValue(int value) { - if (_overflowValue == value) { - return; - } - int from = _overflowValue; - _overflowValue = value; - if (hasValidated) { - overflowValueChanged(from, value); - } - } - - void overflowValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// IntrinsicallySizedValue field with key 606. - static const int intrinsicallySizedValuePropertyKey = 606; - static const bool intrinsicallySizedValueInitialValue = false; - bool _intrinsicallySizedValue = intrinsicallySizedValueInitialValue; - - /// - bool get intrinsicallySizedValue => _intrinsicallySizedValue; - - /// Change the [_intrinsicallySizedValue] field value. - /// [intrinsicallySizedValueChanged] will be invoked only if the field's value - /// has changed. - set intrinsicallySizedValue(bool value) { - if (_intrinsicallySizedValue == value) { - return; - } - bool from = _intrinsicallySizedValue; - _intrinsicallySizedValue = value; - if (hasValidated) { - intrinsicallySizedValueChanged(from, value); - } - } - - void intrinsicallySizedValueChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// WidthUnitsValue field with key 607. - static const int widthUnitsValuePropertyKey = 607; - static const int widthUnitsValueInitialValue = 1; - int _widthUnitsValue = widthUnitsValueInitialValue; - - /// - int get widthUnitsValue => _widthUnitsValue; - - /// Change the [_widthUnitsValue] field value. - /// [widthUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set widthUnitsValue(int value) { - if (_widthUnitsValue == value) { - return; - } - int from = _widthUnitsValue; - _widthUnitsValue = value; - if (hasValidated) { - widthUnitsValueChanged(from, value); - } - } - - void widthUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// HeightUnitsValue field with key 608. - static const int heightUnitsValuePropertyKey = 608; - static const int heightUnitsValueInitialValue = 1; - int _heightUnitsValue = heightUnitsValueInitialValue; - - /// - int get heightUnitsValue => _heightUnitsValue; - - /// Change the [_heightUnitsValue] field value. - /// [heightUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set heightUnitsValue(int value) { - if (_heightUnitsValue == value) { - return; - } - int from = _heightUnitsValue; - _heightUnitsValue = value; - if (hasValidated) { - heightUnitsValueChanged(from, value); - } - } - - void heightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// BorderLeftUnitsValue field with key 609. - static const int borderLeftUnitsValuePropertyKey = 609; - static const int borderLeftUnitsValueInitialValue = 0; - int _borderLeftUnitsValue = borderLeftUnitsValueInitialValue; - - /// - int get borderLeftUnitsValue => _borderLeftUnitsValue; - - /// Change the [_borderLeftUnitsValue] field value. - /// [borderLeftUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set borderLeftUnitsValue(int value) { - if (_borderLeftUnitsValue == value) { - return; - } - int from = _borderLeftUnitsValue; - _borderLeftUnitsValue = value; - if (hasValidated) { - borderLeftUnitsValueChanged(from, value); - } - } - - void borderLeftUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// BorderRightUnitsValue field with key 610. - static const int borderRightUnitsValuePropertyKey = 610; - static const int borderRightUnitsValueInitialValue = 0; - int _borderRightUnitsValue = borderRightUnitsValueInitialValue; - - /// - int get borderRightUnitsValue => _borderRightUnitsValue; - - /// Change the [_borderRightUnitsValue] field value. - /// [borderRightUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set borderRightUnitsValue(int value) { - if (_borderRightUnitsValue == value) { - return; - } - int from = _borderRightUnitsValue; - _borderRightUnitsValue = value; - if (hasValidated) { - borderRightUnitsValueChanged(from, value); - } - } - - void borderRightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// BorderTopUnitsValue field with key 611. - static const int borderTopUnitsValuePropertyKey = 611; - static const int borderTopUnitsValueInitialValue = 0; - int _borderTopUnitsValue = borderTopUnitsValueInitialValue; - - /// - int get borderTopUnitsValue => _borderTopUnitsValue; - - /// Change the [_borderTopUnitsValue] field value. - /// [borderTopUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set borderTopUnitsValue(int value) { - if (_borderTopUnitsValue == value) { - return; - } - int from = _borderTopUnitsValue; - _borderTopUnitsValue = value; - if (hasValidated) { - borderTopUnitsValueChanged(from, value); - } - } - - void borderTopUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// BorderBottomUnitsValue field with key 612. - static const int borderBottomUnitsValuePropertyKey = 612; - static const int borderBottomUnitsValueInitialValue = 0; - int _borderBottomUnitsValue = borderBottomUnitsValueInitialValue; - - /// - int get borderBottomUnitsValue => _borderBottomUnitsValue; - - /// Change the [_borderBottomUnitsValue] field value. - /// [borderBottomUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set borderBottomUnitsValue(int value) { - if (_borderBottomUnitsValue == value) { - return; - } - int from = _borderBottomUnitsValue; - _borderBottomUnitsValue = value; - if (hasValidated) { - borderBottomUnitsValueChanged(from, value); - } - } - - void borderBottomUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MarginLeftUnitsValue field with key 613. - static const int marginLeftUnitsValuePropertyKey = 613; - static const int marginLeftUnitsValueInitialValue = 0; - int _marginLeftUnitsValue = marginLeftUnitsValueInitialValue; - - /// - int get marginLeftUnitsValue => _marginLeftUnitsValue; - - /// Change the [_marginLeftUnitsValue] field value. - /// [marginLeftUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set marginLeftUnitsValue(int value) { - if (_marginLeftUnitsValue == value) { - return; - } - int from = _marginLeftUnitsValue; - _marginLeftUnitsValue = value; - if (hasValidated) { - marginLeftUnitsValueChanged(from, value); - } - } - - void marginLeftUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MarginRightUnitsValue field with key 614. - static const int marginRightUnitsValuePropertyKey = 614; - static const int marginRightUnitsValueInitialValue = 0; - int _marginRightUnitsValue = marginRightUnitsValueInitialValue; - - /// - int get marginRightUnitsValue => _marginRightUnitsValue; - - /// Change the [_marginRightUnitsValue] field value. - /// [marginRightUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set marginRightUnitsValue(int value) { - if (_marginRightUnitsValue == value) { - return; - } - int from = _marginRightUnitsValue; - _marginRightUnitsValue = value; - if (hasValidated) { - marginRightUnitsValueChanged(from, value); - } - } - - void marginRightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MarginTopUnitsValue field with key 615. - static const int marginTopUnitsValuePropertyKey = 615; - static const int marginTopUnitsValueInitialValue = 0; - int _marginTopUnitsValue = marginTopUnitsValueInitialValue; - - /// - int get marginTopUnitsValue => _marginTopUnitsValue; - - /// Change the [_marginTopUnitsValue] field value. - /// [marginTopUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set marginTopUnitsValue(int value) { - if (_marginTopUnitsValue == value) { - return; - } - int from = _marginTopUnitsValue; - _marginTopUnitsValue = value; - if (hasValidated) { - marginTopUnitsValueChanged(from, value); - } - } - - void marginTopUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MarginBottomUnitsValue field with key 616. - static const int marginBottomUnitsValuePropertyKey = 616; - static const int marginBottomUnitsValueInitialValue = 0; - int _marginBottomUnitsValue = marginBottomUnitsValueInitialValue; - - /// - int get marginBottomUnitsValue => _marginBottomUnitsValue; - - /// Change the [_marginBottomUnitsValue] field value. - /// [marginBottomUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set marginBottomUnitsValue(int value) { - if (_marginBottomUnitsValue == value) { - return; - } - int from = _marginBottomUnitsValue; - _marginBottomUnitsValue = value; - if (hasValidated) { - marginBottomUnitsValueChanged(from, value); - } - } - - void marginBottomUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PaddingLeftUnitsValue field with key 617. - static const int paddingLeftUnitsValuePropertyKey = 617; - static const int paddingLeftUnitsValueInitialValue = 0; - int _paddingLeftUnitsValue = paddingLeftUnitsValueInitialValue; - - /// - int get paddingLeftUnitsValue => _paddingLeftUnitsValue; - - /// Change the [_paddingLeftUnitsValue] field value. - /// [paddingLeftUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set paddingLeftUnitsValue(int value) { - if (_paddingLeftUnitsValue == value) { - return; - } - int from = _paddingLeftUnitsValue; - _paddingLeftUnitsValue = value; - if (hasValidated) { - paddingLeftUnitsValueChanged(from, value); - } - } - - void paddingLeftUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PaddingRightUnitsValue field with key 618. - static const int paddingRightUnitsValuePropertyKey = 618; - static const int paddingRightUnitsValueInitialValue = 0; - int _paddingRightUnitsValue = paddingRightUnitsValueInitialValue; - - /// - int get paddingRightUnitsValue => _paddingRightUnitsValue; - - /// Change the [_paddingRightUnitsValue] field value. - /// [paddingRightUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set paddingRightUnitsValue(int value) { - if (_paddingRightUnitsValue == value) { - return; - } - int from = _paddingRightUnitsValue; - _paddingRightUnitsValue = value; - if (hasValidated) { - paddingRightUnitsValueChanged(from, value); - } - } - - void paddingRightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PaddingTopUnitsValue field with key 619. - static const int paddingTopUnitsValuePropertyKey = 619; - static const int paddingTopUnitsValueInitialValue = 0; - int _paddingTopUnitsValue = paddingTopUnitsValueInitialValue; - - /// - int get paddingTopUnitsValue => _paddingTopUnitsValue; - - /// Change the [_paddingTopUnitsValue] field value. - /// [paddingTopUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set paddingTopUnitsValue(int value) { - if (_paddingTopUnitsValue == value) { - return; - } - int from = _paddingTopUnitsValue; - _paddingTopUnitsValue = value; - if (hasValidated) { - paddingTopUnitsValueChanged(from, value); - } - } - - void paddingTopUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PaddingBottomUnitsValue field with key 620. - static const int paddingBottomUnitsValuePropertyKey = 620; - static const int paddingBottomUnitsValueInitialValue = 0; - int _paddingBottomUnitsValue = paddingBottomUnitsValueInitialValue; - - /// - int get paddingBottomUnitsValue => _paddingBottomUnitsValue; - - /// Change the [_paddingBottomUnitsValue] field value. - /// [paddingBottomUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set paddingBottomUnitsValue(int value) { - if (_paddingBottomUnitsValue == value) { - return; - } - int from = _paddingBottomUnitsValue; - _paddingBottomUnitsValue = value; - if (hasValidated) { - paddingBottomUnitsValueChanged(from, value); - } - } - - void paddingBottomUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PositionLeftUnitsValue field with key 621. - static const int positionLeftUnitsValuePropertyKey = 621; - static const int positionLeftUnitsValueInitialValue = 0; - int _positionLeftUnitsValue = positionLeftUnitsValueInitialValue; - - /// - int get positionLeftUnitsValue => _positionLeftUnitsValue; - - /// Change the [_positionLeftUnitsValue] field value. - /// [positionLeftUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set positionLeftUnitsValue(int value) { - if (_positionLeftUnitsValue == value) { - return; - } - int from = _positionLeftUnitsValue; - _positionLeftUnitsValue = value; - if (hasValidated) { - positionLeftUnitsValueChanged(from, value); - } - } - - void positionLeftUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PositionRightUnitsValue field with key 622. - static const int positionRightUnitsValuePropertyKey = 622; - static const int positionRightUnitsValueInitialValue = 0; - int _positionRightUnitsValue = positionRightUnitsValueInitialValue; - - /// - int get positionRightUnitsValue => _positionRightUnitsValue; - - /// Change the [_positionRightUnitsValue] field value. - /// [positionRightUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set positionRightUnitsValue(int value) { - if (_positionRightUnitsValue == value) { - return; - } - int from = _positionRightUnitsValue; - _positionRightUnitsValue = value; - if (hasValidated) { - positionRightUnitsValueChanged(from, value); - } - } - - void positionRightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PositionTopUnitsValue field with key 623. - static const int positionTopUnitsValuePropertyKey = 623; - static const int positionTopUnitsValueInitialValue = 0; - int _positionTopUnitsValue = positionTopUnitsValueInitialValue; - - /// - int get positionTopUnitsValue => _positionTopUnitsValue; - - /// Change the [_positionTopUnitsValue] field value. - /// [positionTopUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set positionTopUnitsValue(int value) { - if (_positionTopUnitsValue == value) { - return; - } - int from = _positionTopUnitsValue; - _positionTopUnitsValue = value; - if (hasValidated) { - positionTopUnitsValueChanged(from, value); - } - } - - void positionTopUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// PositionBottomUnitsValue field with key 624. - static const int positionBottomUnitsValuePropertyKey = 624; - static const int positionBottomUnitsValueInitialValue = 0; - int _positionBottomUnitsValue = positionBottomUnitsValueInitialValue; - - /// - int get positionBottomUnitsValue => _positionBottomUnitsValue; - - /// Change the [_positionBottomUnitsValue] field value. - /// [positionBottomUnitsValueChanged] will be invoked only if the field's - /// value has changed. - set positionBottomUnitsValue(int value) { - if (_positionBottomUnitsValue == value) { - return; - } - int from = _positionBottomUnitsValue; - _positionBottomUnitsValue = value; - if (hasValidated) { - positionBottomUnitsValueChanged(from, value); - } - } - - void positionBottomUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// GapHorizontalUnitsValue field with key 625. - static const int gapHorizontalUnitsValuePropertyKey = 625; - static const int gapHorizontalUnitsValueInitialValue = 0; - int _gapHorizontalUnitsValue = gapHorizontalUnitsValueInitialValue; - - /// - int get gapHorizontalUnitsValue => _gapHorizontalUnitsValue; - - /// Change the [_gapHorizontalUnitsValue] field value. - /// [gapHorizontalUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set gapHorizontalUnitsValue(int value) { - if (_gapHorizontalUnitsValue == value) { - return; - } - int from = _gapHorizontalUnitsValue; - _gapHorizontalUnitsValue = value; - if (hasValidated) { - gapHorizontalUnitsValueChanged(from, value); - } - } - - void gapHorizontalUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// GapVerticalUnitsValue field with key 626. - static const int gapVerticalUnitsValuePropertyKey = 626; - static const int gapVerticalUnitsValueInitialValue = 0; - int _gapVerticalUnitsValue = gapVerticalUnitsValueInitialValue; - - /// - int get gapVerticalUnitsValue => _gapVerticalUnitsValue; - - /// Change the [_gapVerticalUnitsValue] field value. - /// [gapVerticalUnitsValueChanged] will be invoked only if the field's value - /// has changed. - set gapVerticalUnitsValue(int value) { - if (_gapVerticalUnitsValue == value) { - return; - } - int from = _gapVerticalUnitsValue; - _gapVerticalUnitsValue = value; - if (hasValidated) { - gapVerticalUnitsValueChanged(from, value); - } - } - - void gapVerticalUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MinWidthUnitsValue field with key 627. - static const int minWidthUnitsValuePropertyKey = 627; - static const int minWidthUnitsValueInitialValue = 0; - int _minWidthUnitsValue = minWidthUnitsValueInitialValue; - - /// - int get minWidthUnitsValue => _minWidthUnitsValue; - - /// Change the [_minWidthUnitsValue] field value. - /// [minWidthUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set minWidthUnitsValue(int value) { - if (_minWidthUnitsValue == value) { - return; - } - int from = _minWidthUnitsValue; - _minWidthUnitsValue = value; - if (hasValidated) { - minWidthUnitsValueChanged(from, value); - } - } - - void minWidthUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MinHeightUnitsValue field with key 628. - static const int minHeightUnitsValuePropertyKey = 628; - static const int minHeightUnitsValueInitialValue = 0; - int _minHeightUnitsValue = minHeightUnitsValueInitialValue; - - /// - int get minHeightUnitsValue => _minHeightUnitsValue; - - /// Change the [_minHeightUnitsValue] field value. - /// [minHeightUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set minHeightUnitsValue(int value) { - if (_minHeightUnitsValue == value) { - return; - } - int from = _minHeightUnitsValue; - _minHeightUnitsValue = value; - if (hasValidated) { - minHeightUnitsValueChanged(from, value); - } - } - - void minHeightUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MaxWidthUnitsValue field with key 629. - static const int maxWidthUnitsValuePropertyKey = 629; - static const int maxWidthUnitsValueInitialValue = 0; - int _maxWidthUnitsValue = maxWidthUnitsValueInitialValue; - - /// - int get maxWidthUnitsValue => _maxWidthUnitsValue; - - /// Change the [_maxWidthUnitsValue] field value. - /// [maxWidthUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set maxWidthUnitsValue(int value) { - if (_maxWidthUnitsValue == value) { - return; - } - int from = _maxWidthUnitsValue; - _maxWidthUnitsValue = value; - if (hasValidated) { - maxWidthUnitsValueChanged(from, value); - } - } - - void maxWidthUnitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MaxHeightUnitsValue field with key 630. - static const int maxHeightUnitsValuePropertyKey = 630; - static const int maxHeightUnitsValueInitialValue = 0; - int _maxHeightUnitsValue = maxHeightUnitsValueInitialValue; - - /// - int get maxHeightUnitsValue => _maxHeightUnitsValue; - - /// Change the [_maxHeightUnitsValue] field value. - /// [maxHeightUnitsValueChanged] will be invoked only if the field's value has - /// changed. - set maxHeightUnitsValue(int value) { - if (_maxHeightUnitsValue == value) { - return; - } - int from = _maxHeightUnitsValue; - _maxHeightUnitsValue = value; - if (hasValidated) { - maxHeightUnitsValueChanged(from, value); - } - } - - void maxHeightUnitsValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is LayoutComponentStyleBase) { - _gapHorizontal = source._gapHorizontal; - _gapVertical = source._gapVertical; - _maxWidth = source._maxWidth; - _maxHeight = source._maxHeight; - _minWidth = source._minWidth; - _minHeight = source._minHeight; - _borderLeft = source._borderLeft; - _borderRight = source._borderRight; - _borderTop = source._borderTop; - _borderBottom = source._borderBottom; - _marginLeft = source._marginLeft; - _marginRight = source._marginRight; - _marginTop = source._marginTop; - _marginBottom = source._marginBottom; - _paddingLeft = source._paddingLeft; - _paddingRight = source._paddingRight; - _paddingTop = source._paddingTop; - _paddingBottom = source._paddingBottom; - _positionLeft = source._positionLeft; - _positionRight = source._positionRight; - _positionTop = source._positionTop; - _positionBottom = source._positionBottom; - _flex = source._flex; - _flexGrow = source._flexGrow; - _flexShrink = source._flexShrink; - _flexBasis = source._flexBasis; - _aspectRatio = source._aspectRatio; - _scaleType = source._scaleType; - _layoutAlignmentType = source._layoutAlignmentType; - _animationStyleType = source._animationStyleType; - _interpolationType = source._interpolationType; - _interpolatorId = source._interpolatorId; - _interpolationTime = source._interpolationTime; - _displayValue = source._displayValue; - _positionTypeValue = source._positionTypeValue; - _flexDirectionValue = source._flexDirectionValue; - _directionValue = source._directionValue; - _alignContentValue = source._alignContentValue; - _alignItemsValue = source._alignItemsValue; - _alignSelfValue = source._alignSelfValue; - _justifyContentValue = source._justifyContentValue; - _flexWrapValue = source._flexWrapValue; - _overflowValue = source._overflowValue; - _intrinsicallySizedValue = source._intrinsicallySizedValue; - _widthUnitsValue = source._widthUnitsValue; - _heightUnitsValue = source._heightUnitsValue; - _borderLeftUnitsValue = source._borderLeftUnitsValue; - _borderRightUnitsValue = source._borderRightUnitsValue; - _borderTopUnitsValue = source._borderTopUnitsValue; - _borderBottomUnitsValue = source._borderBottomUnitsValue; - _marginLeftUnitsValue = source._marginLeftUnitsValue; - _marginRightUnitsValue = source._marginRightUnitsValue; - _marginTopUnitsValue = source._marginTopUnitsValue; - _marginBottomUnitsValue = source._marginBottomUnitsValue; - _paddingLeftUnitsValue = source._paddingLeftUnitsValue; - _paddingRightUnitsValue = source._paddingRightUnitsValue; - _paddingTopUnitsValue = source._paddingTopUnitsValue; - _paddingBottomUnitsValue = source._paddingBottomUnitsValue; - _positionLeftUnitsValue = source._positionLeftUnitsValue; - _positionRightUnitsValue = source._positionRightUnitsValue; - _positionTopUnitsValue = source._positionTopUnitsValue; - _positionBottomUnitsValue = source._positionBottomUnitsValue; - _gapHorizontalUnitsValue = source._gapHorizontalUnitsValue; - _gapVerticalUnitsValue = source._gapVerticalUnitsValue; - _minWidthUnitsValue = source._minWidthUnitsValue; - _minHeightUnitsValue = source._minHeightUnitsValue; - _maxWidthUnitsValue = source._maxWidthUnitsValue; - _maxHeightUnitsValue = source._maxHeightUnitsValue; - } - } -} diff --git a/lib/src/generated/layout/track_sizing_function_base.dart b/lib/src/generated/layout/track_sizing_function_base.dart deleted file mode 100644 index 804078a..0000000 --- a/lib/src/generated/layout/track_sizing_function_base.dart +++ /dev/null @@ -1,175 +0,0 @@ -// Core automatically generated -// lib/src/generated/layout/track_sizing_function_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TrackSizingFunctionBase extends Component { - static const int typeKey = 176; - @override - int get coreType => TrackSizingFunctionBase.typeKey; - @override - Set get coreTypes => - {TrackSizingFunctionBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// MinTypeTag field with key 459. - static const int minTypeTagPropertyKey = 459; - static const int minTypeTagInitialValue = 3; - int _minTypeTag = minTypeTagInitialValue; - - /// Layout tag (type) for min size value (fixed|minContent|maxContent|auto). - int get minTypeTag => _minTypeTag; - - /// Change the [_minTypeTag] field value. - /// [minTypeTagChanged] will be invoked only if the field's value has changed. - set minTypeTag(int value) { - if (_minTypeTag == value) { - return; - } - int from = _minTypeTag; - _minTypeTag = value; - if (hasValidated) { - minTypeTagChanged(from, value); - } - } - - void minTypeTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MinValueTag field with key 460. - static const int minValueTagPropertyKey = 460; - static const int minValueTagInitialValue = 0; - int _minValueTag = minValueTagInitialValue; - - /// Dimension tag (type) for min size value (points|percent|auto). - int get minValueTag => _minValueTag; - - /// Change the [_minValueTag] field value. - /// [minValueTagChanged] will be invoked only if the field's value has - /// changed. - set minValueTag(int value) { - if (_minValueTag == value) { - return; - } - int from = _minValueTag; - _minValueTag = value; - if (hasValidated) { - minValueTagChanged(from, value); - } - } - - void minValueTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MinValue field with key 461. - static const int minValuePropertyKey = 461; - static const double minValueInitialValue = 0; - double _minValue = minValueInitialValue; - - /// Min size value. - double get minValue => _minValue; - - /// Change the [_minValue] field value. - /// [minValueChanged] will be invoked only if the field's value has changed. - set minValue(double value) { - if (_minValue == value) { - return; - } - double from = _minValue; - _minValue = value; - if (hasValidated) { - minValueChanged(from, value); - } - } - - void minValueChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// MaxTypeTag field with key 462. - static const int maxTypeTagPropertyKey = 462; - static const int maxTypeTagInitialValue = 4; - int _maxTypeTag = maxTypeTagInitialValue; - - /// Layout tag for max size value - /// (fixed|minContent|maxContent|fitContent|auto|fraction). - int get maxTypeTag => _maxTypeTag; - - /// Change the [_maxTypeTag] field value. - /// [maxTypeTagChanged] will be invoked only if the field's value has changed. - set maxTypeTag(int value) { - if (_maxTypeTag == value) { - return; - } - int from = _maxTypeTag; - _maxTypeTag = value; - if (hasValidated) { - maxTypeTagChanged(from, value); - } - } - - void maxTypeTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MaxValueTag field with key 463. - static const int maxValueTagPropertyKey = 463; - static const int maxValueTagInitialValue = 0; - int _maxValueTag = maxValueTagInitialValue; - - /// Dimension tag (type) for max size value (points|percent|auto). - int get maxValueTag => _maxValueTag; - - /// Change the [_maxValueTag] field value. - /// [maxValueTagChanged] will be invoked only if the field's value has - /// changed. - set maxValueTag(int value) { - if (_maxValueTag == value) { - return; - } - int from = _maxValueTag; - _maxValueTag = value; - if (hasValidated) { - maxValueTagChanged(from, value); - } - } - - void maxValueTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// MaxValue field with key 464. - static const int maxValuePropertyKey = 464; - static const double maxValueInitialValue = 0; - double _maxValue = maxValueInitialValue; - - /// Max size value. - double get maxValue => _maxValue; - - /// Change the [_maxValue] field value. - /// [maxValueChanged] will be invoked only if the field's value has changed. - set maxValue(double value) { - if (_maxValue == value) { - return; - } - double from = _maxValue; - _maxValue = value; - if (hasValidated) { - maxValueChanged(from, value); - } - } - - void maxValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TrackSizingFunctionBase) { - _minTypeTag = source._minTypeTag; - _minValueTag = source._minValueTag; - _minValue = source._minValue; - _maxTypeTag = source._maxTypeTag; - _maxValueTag = source._maxValueTag; - _maxValue = source._maxValue; - } - } -} diff --git a/lib/src/generated/layout_component_absolute_base.dart b/lib/src/generated/layout_component_absolute_base.dart deleted file mode 100644 index f979448..0000000 --- a/lib/src/generated/layout_component_absolute_base.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Core automatically generated -// lib/src/generated/layout_component_absolute_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/layout_component.dart'; - -abstract class AbsoluteLayoutComponentBase extends LayoutComponent { - static const int typeKey = 423; - @override - int get coreType => AbsoluteLayoutComponentBase.typeKey; - @override - Set get coreTypes => { - AbsoluteLayoutComponentBase.typeKey, - LayoutComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/layout_component_base.dart b/lib/src/generated/layout_component_base.dart deleted file mode 100644 index 4525b27..0000000 --- a/lib/src/generated/layout_component_base.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Core automatically generated lib/src/generated/layout_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; - -abstract class LayoutComponentBase extends WorldTransformComponent { - static const int typeKey = 409; - @override - int get coreType => LayoutComponentBase.typeKey; - @override - Set get coreTypes => { - LayoutComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Clip field with key 196. - static const int clipPropertyKey = 196; - static const bool clipInitialValue = true; - bool _clip = clipInitialValue; - - /// True when the layout component bounds clip its contents. - bool get clip => _clip; - - /// Change the [_clip] field value. - /// [clipChanged] will be invoked only if the field's value has changed. - set clip(bool value) { - if (_clip == value) { - return; - } - bool from = _clip; - _clip = value; - if (hasValidated) { - clipChanged(from, value); - } - } - - void clipChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// Width field with key 7. - static const int widthPropertyKey = 7; - static const double widthInitialValue = 0; - double _width = widthInitialValue; - - /// Initial width of the item. - double get width => _width; - - /// Change the [_width] field value. - /// [widthChanged] will be invoked only if the field's value has changed. - set width(double value) { - if (_width == value) { - return; - } - double from = _width; - _width = value; - if (hasValidated) { - widthChanged(from, value); - } - } - - void widthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Height field with key 8. - static const int heightPropertyKey = 8; - static const double heightInitialValue = 0; - double _height = heightInitialValue; - - /// Initial height of the item. - double get height => _height; - - /// Change the [_height] field value. - /// [heightChanged] will be invoked only if the field's value has changed. - set height(double value) { - if (_height == value) { - return; - } - double from = _height; - _height = value; - if (hasValidated) { - heightChanged(from, value); - } - } - - void heightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// StyleId field with key 494. - static const int styleIdPropertyKey = 494; - static const int styleIdInitialValue = -1; - int _styleId = styleIdInitialValue; - - /// LayoutStyle that defines the styling for this LayoutComponent - int get styleId => _styleId; - - /// Change the [_styleId] field value. - /// [styleIdChanged] will be invoked only if the field's value has changed. - set styleId(int value) { - if (_styleId == value) { - return; - } - int from = _styleId; - _styleId = value; - if (hasValidated) { - styleIdChanged(from, value); - } - } - - void styleIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is LayoutComponentBase) { - _clip = source._clip; - _width = source._width; - _height = source._height; - _styleId = source._styleId; - } - } -} diff --git a/lib/src/generated/nested_animation_base.dart b/lib/src/generated/nested_animation_base.dart deleted file mode 100644 index 13ff83b..0000000 --- a/lib/src/generated/nested_animation_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated lib/src/generated/nested_animation_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class NestedAnimationBase extends ContainerComponent { - static const int typeKey = 93; - @override - int get coreType => NestedAnimationBase.typeKey; - @override - Set get coreTypes => { - NestedAnimationBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AnimationId field with key 198. - static const int animationIdPropertyKey = 198; - static const int animationIdInitialValue = -1; - int _animationId = animationIdInitialValue; - - /// Identifier used to track the animation in the nested artboard. - int get animationId => _animationId; - - /// Change the [_animationId] field value. - /// [animationIdChanged] will be invoked only if the field's value has - /// changed. - set animationId(int value) { - if (_animationId == value) { - return; - } - int from = _animationId; - _animationId = value; - if (hasValidated) { - animationIdChanged(from, value); - } - } - - void animationIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedAnimationBase) { - _animationId = source._animationId; - } - } -} diff --git a/lib/src/generated/nested_artboard_base.dart b/lib/src/generated/nested_artboard_base.dart deleted file mode 100644 index 47ee9e8..0000000 --- a/lib/src/generated/nested_artboard_base.dart +++ /dev/null @@ -1,134 +0,0 @@ -// Core automatically generated lib/src/generated/nested_artboard_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/drawable.dart'; - -abstract class NestedArtboardBase extends Drawable { - static const int typeKey = 92; - @override - int get coreType => NestedArtboardBase.typeKey; - @override - Set get coreTypes => { - NestedArtboardBase.typeKey, - DrawableBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ArtboardId field with key 197. - static const int artboardIdPropertyKey = 197; - static const int artboardIdInitialValue = -1; - int _artboardId = artboardIdInitialValue; - - /// Identifier used to track the Artboard nested. - int get artboardId => _artboardId; - - /// Change the [_artboardId] field value. - /// [artboardIdChanged] will be invoked only if the field's value has changed. - set artboardId(int value) { - if (_artboardId == value) { - return; - } - int from = _artboardId; - _artboardId = value; - if (hasValidated) { - artboardIdChanged(from, value); - } - } - - void artboardIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Fit field with key 538. - static const int fitPropertyKey = 538; - static const int fitInitialValue = 0; - int _fit = fitInitialValue; - - /// Fit type for the nested artboard's runtime artboard. - int get fit => _fit; - - /// Change the [_fit] field value. - /// [fitChanged] will be invoked only if the field's value has changed. - set fit(int value) { - if (_fit == value) { - return; - } - int from = _fit; - _fit = value; - if (hasValidated) { - fitChanged(from, value); - } - } - - void fitChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Alignment field with key 539. - static const int alignmentPropertyKey = 539; - static const int alignmentInitialValue = 0; - int _alignment = alignmentInitialValue; - - /// Alignment type for the nested artboard's runtime artboard. - int get alignment => _alignment; - - /// Change the [_alignment] field value. - /// [alignmentChanged] will be invoked only if the field's value has changed. - set alignment(int value) { - if (_alignment == value) { - return; - } - int from = _alignment; - _alignment = value; - if (hasValidated) { - alignmentChanged(from, value); - } - } - - void alignmentChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// DataBindPathIds field with key 582. - static const int dataBindPathIdsPropertyKey = 582; - static final Uint8List dataBindPathIdsInitialValue = Uint8List(0); - Uint8List _dataBindPathIds = dataBindPathIdsInitialValue; - - /// Path to the selected property. - Uint8List get dataBindPathIds => _dataBindPathIds; - - /// Change the [_dataBindPathIds] field value. - /// [dataBindPathIdsChanged] will be invoked only if the field's value has - /// changed. - set dataBindPathIds(Uint8List value) { - if (listEquals(_dataBindPathIds, value)) { - return; - } - Uint8List from = _dataBindPathIds; - _dataBindPathIds = value; - if (hasValidated) { - dataBindPathIdsChanged(from, value); - } - } - - void dataBindPathIdsChanged(Uint8List from, Uint8List to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NestedArtboardBase) { - _artboardId = source._artboardId; - _fit = source._fit; - _alignment = source._alignment; - _dataBindPathIds = source._dataBindPathIds; - } - } -} diff --git a/lib/src/generated/node_base.dart b/lib/src/generated/node_base.dart deleted file mode 100644 index f02fe17..0000000 --- a/lib/src/generated/node_base.dart +++ /dev/null @@ -1,79 +0,0 @@ -// Core automatically generated lib/src/generated/node_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; - -abstract class NodeBase extends TransformComponent { - static const int typeKey = 2; - @override - int get coreType => NodeBase.typeKey; - @override - Set get coreTypes => { - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// X field with key 13. - static const int xPropertyKey = 13; - static const double xInitialValue = 0; - double _x = xInitialValue; - @override - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - @override - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 14. - static const int yPropertyKey = 14; - static const double yInitialValue = 0; - double _y = yInitialValue; - @override - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - @override - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is NodeBase) { - _x = source._x; - _y = source._y; - } - } -} diff --git a/lib/src/generated/open_url_event_base.dart b/lib/src/generated/open_url_event_base.dart deleted file mode 100644 index a3fdd61..0000000 --- a/lib/src/generated/open_url_event_base.dart +++ /dev/null @@ -1,78 +0,0 @@ -// Core automatically generated lib/src/generated/open_url_event_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/event.dart'; - -abstract class OpenUrlEventBase extends Event { - static const int typeKey = 131; - @override - int get coreType => OpenUrlEventBase.typeKey; - @override - Set get coreTypes => { - OpenUrlEventBase.typeKey, - EventBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Url field with key 248. - static const int urlPropertyKey = 248; - static const String urlInitialValue = ''; - String _url = urlInitialValue; - - /// URL to open. - String get url => _url; - - /// Change the [_url] field value. - /// [urlChanged] will be invoked only if the field's value has changed. - set url(String value) { - if (_url == value) { - return; - } - String from = _url; - _url = value; - if (hasValidated) { - urlChanged(from, value); - } - } - - void urlChanged(String from, String to); - - /// -------------------------------------------------------------------------- - /// TargetValue field with key 249. - static const int targetValuePropertyKey = 249; - static const int targetValueInitialValue = 0; - int _targetValue = targetValueInitialValue; - - /// Backing value for the target enum. - int get targetValue => _targetValue; - - /// Change the [_targetValue] field value. - /// [targetValueChanged] will be invoked only if the field's value has - /// changed. - set targetValue(int value) { - if (_targetValue == value) { - return; - } - int from = _targetValue; - _targetValue = value; - if (hasValidated) { - targetValueChanged(from, value); - } - } - - void targetValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is OpenUrlEventBase) { - _url = source._url; - _targetValue = source._targetValue; - } - } -} diff --git a/lib/src/generated/rive_core_context.dart b/lib/src/generated/rive_core_context.dart deleted file mode 100644 index ac4d68e..0000000 --- a/lib/src/generated/rive_core_context.dart +++ /dev/null @@ -1,5526 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/core/field_types/core_bool_type.dart'; -import 'package:rive/src/core/field_types/core_bytes_type.dart'; -import 'package:rive/src/core/field_types/core_color_type.dart'; -import 'package:rive/src/core/field_types/core_double_type.dart'; -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive/src/core/field_types/core_string_type.dart'; -import 'package:rive/src/core/field_types/core_uint_type.dart'; -import 'package:rive/src/generated/animation/advanceable_state_base.dart'; -import 'package:rive/src/generated/animation/blend_animation_base.dart'; -import 'package:rive/src/generated/animation/cubic_ease_interpolator_base.dart'; -import 'package:rive/src/generated/animation/cubic_interpolator_base.dart'; -import 'package:rive/src/generated/animation/interpolating_keyframe_base.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/generated/animation/keyframe_string_base.dart'; -import 'package:rive/src/generated/animation/layer_state_base.dart'; -import 'package:rive/src/generated/animation/listener_input_change_base.dart'; -import 'package:rive/src/generated/animation/nested_input_base.dart'; -import 'package:rive/src/generated/animation/nested_linear_animation_base.dart'; -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/generated/animation/transition_input_condition_base.dart'; -import 'package:rive/src/generated/animation/transition_value_condition_base.dart'; -import 'package:rive/src/generated/assets/asset_base.dart'; -import 'package:rive/src/generated/assets/drawable_asset_base.dart'; -import 'package:rive/src/generated/assets/export_audio_base.dart'; -import 'package:rive/src/generated/assets/file_asset_base.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_component_constraint_base.dart'; -import 'package:rive/src/generated/constraints/transform_component_constraint_y_base.dart'; -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/generated/data_bind/converters/data_converter_base.dart'; -import 'package:rive/src/generated/drawable_base.dart'; -import 'package:rive/src/generated/nested_animation_base.dart'; -import 'package:rive/src/generated/shapes/paint/shape_paint_base.dart'; -import 'package:rive/src/generated/shapes/parametric_path_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/animation/animation.dart'; -import 'package:rive/src/rive_core/animation/animation_state.dart'; -import 'package:rive/src/rive_core/animation/any_state.dart'; -import 'package:rive/src/rive_core/animation/blend_animation_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_animation_direct.dart'; -import 'package:rive/src/rive_core/animation/blend_state_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_state_direct.dart'; -import 'package:rive/src/rive_core/animation/blend_state_transition.dart'; -import 'package:rive/src/rive_core/animation/cubic_ease_interpolator.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator_component.dart'; -import 'package:rive/src/rive_core/animation/cubic_value_interpolator.dart'; -import 'package:rive/src/rive_core/animation/elastic_interpolator.dart'; -import 'package:rive/src/rive_core/animation/entry_state.dart'; -import 'package:rive/src/rive_core/animation/exit_state.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; -import 'package:rive/src/rive_core/animation/keyframe_bool.dart'; -import 'package:rive/src/rive_core/animation/keyframe_callback.dart'; -import 'package:rive/src/rive_core/animation/keyframe_color.dart'; -import 'package:rive/src/rive_core/animation/keyframe_double.dart'; -import 'package:rive/src/rive_core/animation/keyframe_id.dart'; -import 'package:rive/src/rive_core/animation/keyframe_string.dart'; -import 'package:rive/src/rive_core/animation/keyframe_uint.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/listener_align_target.dart'; -import 'package:rive/src/rive_core/animation/listener_bool_change.dart'; -import 'package:rive/src/rive_core/animation/listener_fire_event.dart'; -import 'package:rive/src/rive_core/animation/listener_number_change.dart'; -import 'package:rive/src/rive_core/animation/listener_trigger_change.dart'; -import 'package:rive/src/rive_core/animation/listener_viewmodel_change.dart'; -import 'package:rive/src/rive_core/animation/nested_bool.dart'; -import 'package:rive/src/rive_core/animation/nested_number.dart'; -import 'package:rive/src/rive_core/animation/nested_remap_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_simple_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/animation/nested_trigger.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_bool.dart'; -import 'package:rive/src/rive_core/animation/state_machine_fire_event.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; -import 'package:rive/src/rive_core/animation/state_machine_listener.dart'; -import 'package:rive/src/rive_core/animation/state_machine_number.dart'; -import 'package:rive/src/rive_core/animation/state_machine_trigger.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; -import 'package:rive/src/rive_core/animation/transition_bool_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_number_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_property_viewmodel_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_trigger_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_value_boolean_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_value_color_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_value_enum_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_value_number_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_value_string_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_viewmodel_condition.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/assets/audio_asset.dart'; -import 'package:rive/src/rive_core/assets/file_asset_contents.dart'; -import 'package:rive/src/rive_core/assets/folder.dart'; -import 'package:rive/src/rive_core/assets/font_asset.dart'; -import 'package:rive/src/rive_core/assets/image_asset.dart'; -import 'package:rive/src/rive_core/audio_event.dart'; -import 'package:rive/src/rive_core/backboard.dart'; -import 'package:rive/src/rive_core/bones/bone.dart'; -import 'package:rive/src/rive_core/bones/cubic_weight.dart'; -import 'package:rive/src/rive_core/bones/root_bone.dart'; -import 'package:rive/src/rive_core/bones/skin.dart'; -import 'package:rive/src/rive_core/bones/tendon.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/constraints/distance_constraint.dart'; -import 'package:rive/src/rive_core/constraints/follow_path_constraint.dart'; -import 'package:rive/src/rive_core/constraints/ik_constraint.dart'; -import 'package:rive/src/rive_core/constraints/rotation_constraint.dart'; -import 'package:rive/src/rive_core/constraints/scale_constraint.dart'; -import 'package:rive/src/rive_core/constraints/transform_constraint.dart'; -import 'package:rive/src/rive_core/constraints/translation_constraint.dart'; -import 'package:rive/src/rive_core/custom_property_boolean.dart'; -import 'package:rive/src/rive_core/custom_property_number.dart'; -import 'package:rive/src/rive_core/custom_property_string.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property_boolean.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property_color.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property_enum.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property_number.dart'; -import 'package:rive/src/rive_core/data_bind/bindable_property_string.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind_context.dart'; -import 'package:rive/src/rive_core/draw_rules.dart'; -import 'package:rive/src/rive_core/draw_target.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/joystick.dart'; -import 'package:rive/src/rive_core/layout/layout_component_style.dart'; -import 'package:rive/src/rive_core/layout_component.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/rive_core/node.dart'; -import 'package:rive/src/rive_core/open_url_event.dart'; -import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; -import 'package:rive/src/rive_core/shapes/contour_mesh_vertex.dart'; -import 'package:rive/src/rive_core/shapes/cubic_asymmetric_vertex.dart'; -import 'package:rive/src/rive_core/shapes/cubic_detached_vertex.dart'; -import 'package:rive/src/rive_core/shapes/cubic_mirrored_vertex.dart'; -import 'package:rive/src/rive_core/shapes/ellipse.dart'; -import 'package:rive/src/rive_core/shapes/image.dart'; -import 'package:rive/src/rive_core/shapes/mesh.dart'; -import 'package:rive/src/rive_core/shapes/mesh_vertex.dart'; -import 'package:rive/src/rive_core/shapes/paint/fill.dart'; -import 'package:rive/src/rive_core/shapes/paint/gradient_stop.dart'; -import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart'; -import 'package:rive/src/rive_core/shapes/paint/radial_gradient.dart'; -import 'package:rive/src/rive_core/shapes/paint/solid_color.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; -import 'package:rive/src/rive_core/shapes/paint/trim_path.dart'; -import 'package:rive/src/rive_core/shapes/points_path.dart'; -import 'package:rive/src/rive_core/shapes/polygon.dart'; -import 'package:rive/src/rive_core/shapes/rectangle.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/shapes/star.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; -import 'package:rive/src/rive_core/shapes/triangle.dart'; -import 'package:rive/src/rive_core/solo.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive/src/rive_core/text/text_modifier_group.dart'; -import 'package:rive/src/rive_core/text/text_modifier_range.dart'; -import 'package:rive/src/rive_core/text/text_style.dart'; -import 'package:rive/src/rive_core/text/text_style_axis.dart'; -import 'package:rive/src/rive_core/text/text_style_feature.dart'; -import 'package:rive/src/rive_core/text/text_value_run.dart'; -import 'package:rive/src/rive_core/text/text_variation_modifier.dart'; -import 'package:rive/src/rive_core/viewmodel/data_enum.dart'; -import 'package:rive/src/rive_core/viewmodel/data_enum_value.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_component.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_boolean.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_color.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_enum.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_list.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_list_item.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_number.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_string.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_boolean.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_color.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_enum.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_list.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_number.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_string.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property_viewmodel.dart'; - -// ignore: avoid_classes_with_only_static_members -class RiveCoreContext { - static Core? makeCoreInstance(int typeKey) { - switch (typeKey) { - case ViewModelInstanceListItemBase.typeKey: - return ViewModelInstanceListItem(); - case ViewModelInstanceColorBase.typeKey: - return ViewModelInstanceColor(); - case ViewModelComponentBase.typeKey: - return ViewModelComponent(); - case ViewModelPropertyBase.typeKey: - return ViewModelProperty(); - case ViewModelPropertyNumberBase.typeKey: - return ViewModelPropertyNumber(); - case ViewModelInstanceEnumBase.typeKey: - return ViewModelInstanceEnum(); - case ViewModelInstanceStringBase.typeKey: - return ViewModelInstanceString(); - case ViewModelPropertyListBase.typeKey: - return ViewModelPropertyList(); - case ViewModelBase.typeKey: - return ViewModel(); - case ViewModelPropertyViewModelBase.typeKey: - return ViewModelPropertyViewModel(); - case ViewModelInstanceBase.typeKey: - return ViewModelInstance(); - case ViewModelPropertyBooleanBase.typeKey: - return ViewModelPropertyBoolean(); - case DataEnumBase.typeKey: - return DataEnum(); - case ViewModelPropertyEnumBase.typeKey: - return ViewModelPropertyEnum(); - case ViewModelPropertyColorBase.typeKey: - return ViewModelPropertyColor(); - case ViewModelInstanceBooleanBase.typeKey: - return ViewModelInstanceBoolean(); - case ViewModelInstanceListBase.typeKey: - return ViewModelInstanceList(); - case ViewModelInstanceNumberBase.typeKey: - return ViewModelInstanceNumber(); - case ViewModelPropertyStringBase.typeKey: - return ViewModelPropertyString(); - case ViewModelInstanceViewModelBase.typeKey: - return ViewModelInstanceViewModel(); - case DataEnumValueBase.typeKey: - return DataEnumValue(); - case DrawTargetBase.typeKey: - return DrawTarget(); - case CustomPropertyNumberBase.typeKey: - return CustomPropertyNumber(); - case DistanceConstraintBase.typeKey: - return DistanceConstraint(); - case IKConstraintBase.typeKey: - return IKConstraint(); - case FollowPathConstraintBase.typeKey: - return FollowPathConstraint(); - case TranslationConstraintBase.typeKey: - return TranslationConstraint(); - case TransformConstraintBase.typeKey: - return TransformConstraint(); - case ScaleConstraintBase.typeKey: - return ScaleConstraint(); - case RotationConstraintBase.typeKey: - return RotationConstraint(); - case NodeBase.typeKey: - return Node(); - case NestedArtboardBase.typeKey: - return NestedArtboard(); - case SoloBase.typeKey: - return Solo(); - case LayoutComponentStyleBase.typeKey: - return LayoutComponentStyle(); - case ListenerFireEventBase.typeKey: - return ListenerFireEvent(); - case KeyFrameUintBase.typeKey: - return KeyFrameUint(); - case AnimationBase.typeKey: - return Animation(); - case LinearAnimationBase.typeKey: - return LinearAnimation(); - case NestedSimpleAnimationBase.typeKey: - return NestedSimpleAnimation(); - case AnimationStateBase.typeKey: - return AnimationState(); - case NestedTriggerBase.typeKey: - return NestedTrigger(); - case KeyedObjectBase.typeKey: - return KeyedObject(); - case BlendAnimationDirectBase.typeKey: - return BlendAnimationDirect(); - case StateMachineNumberBase.typeKey: - return StateMachineNumber(); - case CubicValueInterpolatorBase.typeKey: - return CubicValueInterpolator(); - case TransitionTriggerConditionBase.typeKey: - return TransitionTriggerCondition(); - case KeyedPropertyBase.typeKey: - return KeyedProperty(); - case StateMachineListenerBase.typeKey: - return StateMachineListener(); - case TransitionPropertyViewModelComparatorBase.typeKey: - return TransitionPropertyViewModelComparator(); - case KeyFrameIdBase.typeKey: - return KeyFrameId(); - case KeyFrameBoolBase.typeKey: - return KeyFrameBool(); - case ListenerBoolChangeBase.typeKey: - return ListenerBoolChange(); - case ListenerAlignTargetBase.typeKey: - return ListenerAlignTarget(); - case TransitionNumberConditionBase.typeKey: - return TransitionNumberCondition(); - case TransitionValueBooleanComparatorBase.typeKey: - return TransitionValueBooleanComparator(); - case AnyStateBase.typeKey: - return AnyState(); - case CubicInterpolatorComponentBase.typeKey: - return CubicInterpolatorComponent(); - case StateMachineLayerBase.typeKey: - return StateMachineLayer(); - case KeyFrameStringBase.typeKey: - return KeyFrameString(); - case ListenerNumberChangeBase.typeKey: - return ListenerNumberChange(); - case TransitionViewModelConditionBase.typeKey: - return TransitionViewModelCondition(); - case CubicEaseInterpolatorBase.typeKey: - return CubicEaseInterpolator(); - case StateTransitionBase.typeKey: - return StateTransition(); - case NestedBoolBase.typeKey: - return NestedBool(); - case KeyFrameDoubleBase.typeKey: - return KeyFrameDouble(); - case KeyFrameColorBase.typeKey: - return KeyFrameColor(); - case StateMachineBase.typeKey: - return StateMachine(); - case StateMachineFireEventBase.typeKey: - return StateMachineFireEvent(); - case EntryStateBase.typeKey: - return EntryState(); - case StateMachineTriggerBase.typeKey: - return StateMachineTrigger(); - case TransitionValueColorComparatorBase.typeKey: - return TransitionValueColorComparator(); - case ListenerTriggerChangeBase.typeKey: - return ListenerTriggerChange(); - case BlendStateDirectBase.typeKey: - return BlendStateDirect(); - case ListenerViewModelChangeBase.typeKey: - return ListenerViewModelChange(); - case TransitionValueNumberComparatorBase.typeKey: - return TransitionValueNumberComparator(); - case NestedStateMachineBase.typeKey: - return NestedStateMachine(); - case ElasticInterpolatorBase.typeKey: - return ElasticInterpolator(); - case ExitStateBase.typeKey: - return ExitState(); - case NestedNumberBase.typeKey: - return NestedNumber(); - case BlendAnimation1DBase.typeKey: - return BlendAnimation1D(); - case BlendState1DBase.typeKey: - return BlendState1D(); - case TransitionValueEnumComparatorBase.typeKey: - return TransitionValueEnumComparator(); - case KeyFrameCallbackBase.typeKey: - return KeyFrameCallback(); - case TransitionValueStringComparatorBase.typeKey: - return TransitionValueStringComparator(); - case NestedRemapAnimationBase.typeKey: - return NestedRemapAnimation(); - case TransitionBoolConditionBase.typeKey: - return TransitionBoolCondition(); - case BlendStateTransitionBase.typeKey: - return BlendStateTransition(); - case StateMachineBoolBase.typeKey: - return StateMachineBool(); - case LinearGradientBase.typeKey: - return LinearGradient(); - case RadialGradientBase.typeKey: - return RadialGradient(); - case StrokeBase.typeKey: - return Stroke(); - case SolidColorBase.typeKey: - return SolidColor(); - case GradientStopBase.typeKey: - return GradientStop(); - case TrimPathBase.typeKey: - return TrimPath(); - case FillBase.typeKey: - return Fill(); - case MeshVertexBase.typeKey: - return MeshVertex(); - case ShapeBase.typeKey: - return Shape(); - case WeightBase.typeKey: - return Weight(); - case StraightVertexBase.typeKey: - return StraightVertex(); - case CubicWeightBase.typeKey: - return CubicWeight(); - case CubicAsymmetricVertexBase.typeKey: - return CubicAsymmetricVertex(); - case MeshBase.typeKey: - return Mesh(); - case PointsPathBase.typeKey: - return PointsPath(); - case ContourMeshVertexBase.typeKey: - return ContourMeshVertex(); - case RectangleBase.typeKey: - return Rectangle(); - case CubicMirroredVertexBase.typeKey: - return CubicMirroredVertex(); - case TriangleBase.typeKey: - return Triangle(); - case EllipseBase.typeKey: - return Ellipse(); - case ClippingShapeBase.typeKey: - return ClippingShape(); - case PolygonBase.typeKey: - return Polygon(); - case StarBase.typeKey: - return Star(); - case ImageBase.typeKey: - return Image(); - case CubicDetachedVertexBase.typeKey: - return CubicDetachedVertex(); - case EventBase.typeKey: - return Event(); - case DrawRulesBase.typeKey: - return DrawRules(); - case CustomPropertyBooleanBase.typeKey: - return CustomPropertyBoolean(); - case LayoutComponentBase.typeKey: - return LayoutComponent(); - case ArtboardBase.typeKey: - return Artboard(); - case JoystickBase.typeKey: - return Joystick(); - case BackboardBase.typeKey: - return Backboard(); - case OpenUrlEventBase.typeKey: - return OpenUrlEvent(); - case BindablePropertyBooleanBase.typeKey: - return BindablePropertyBoolean(); - case DataBindBase.typeKey: - return DataBind(); - case DataBindContextBase.typeKey: - return DataBindContext(); - case BindablePropertyStringBase.typeKey: - return BindablePropertyString(); - case BindablePropertyNumberBase.typeKey: - return BindablePropertyNumber(); - case BindablePropertyEnumBase.typeKey: - return BindablePropertyEnum(); - case BindablePropertyColorBase.typeKey: - return BindablePropertyColor(); - case BoneBase.typeKey: - return Bone(); - case RootBoneBase.typeKey: - return RootBone(); - case SkinBase.typeKey: - return Skin(); - case TendonBase.typeKey: - return Tendon(); - case TextModifierRangeBase.typeKey: - return TextModifierRange(); - case TextStyleFeatureBase.typeKey: - return TextStyleFeature(); - case TextVariationModifierBase.typeKey: - return TextVariationModifier(); - case TextModifierGroupBase.typeKey: - return TextModifierGroup(); - case TextStyleBase.typeKey: - return TextStyle(); - case TextStyleAxisBase.typeKey: - return TextStyleAxis(); - case TextBase.typeKey: - return Text(); - case TextValueRunBase.typeKey: - return TextValueRun(); - case CustomPropertyStringBase.typeKey: - return CustomPropertyString(); - case FolderBase.typeKey: - return Folder(); - case ImageAssetBase.typeKey: - return ImageAsset(); - case FontAssetBase.typeKey: - return FontAsset(); - case AudioAssetBase.typeKey: - return AudioAsset(); - case FileAssetContentsBase.typeKey: - return FileAssetContents(); - case AudioEventBase.typeKey: - return AudioEvent(); - default: - return null; - } - } - - static void setObjectProperty(Core object, int propertyKey, Object value) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.useLinkedArtboardPropertyKey: - if (object is ViewModelInstanceListItemBase && value is bool) { - object.useLinkedArtboard = value; - } - break; - case ViewModelInstanceListItemBase.viewModelIdPropertyKey: - if (object is ViewModelInstanceListItemBase && value is int) { - object.viewModelId = value; - } - break; - case ViewModelInstanceListItemBase.viewModelInstanceIdPropertyKey: - if (object is ViewModelInstanceListItemBase && value is int) { - object.viewModelInstanceId = value; - } - break; - case ViewModelInstanceListItemBase.artboardIdPropertyKey: - if (object is ViewModelInstanceListItemBase && value is int) { - object.artboardId = value; - } - break; - case ViewModelInstanceValueBase.viewModelPropertyIdPropertyKey: - if (object is ViewModelInstanceValueBase && value is int) { - object.viewModelPropertyId = value; - } - break; - case ViewModelInstanceColorBase.propertyValuePropertyKey: - if (object is ViewModelInstanceColorBase && value is int) { - object.propertyValue = value; - } - break; - case ViewModelComponentBase.namePropertyKey: - if (object is ViewModelComponentBase && value is String) { - object.name = value; - } - break; - case ViewModelInstanceEnumBase.propertyValuePropertyKey: - if (object is ViewModelInstanceEnumBase && value is int) { - object.propertyValue = value; - } - break; - case ViewModelInstanceStringBase.propertyValuePropertyKey: - if (object is ViewModelInstanceStringBase && value is String) { - object.propertyValue = value; - } - break; - case ViewModelBase.defaultInstanceIdPropertyKey: - if (object is ViewModelBase && value is int) { - object.defaultInstanceId = value; - } - break; - case ViewModelPropertyViewModelBase.viewModelReferenceIdPropertyKey: - if (object is ViewModelPropertyViewModelBase && value is int) { - object.viewModelReferenceId = value; - } - break; - case ComponentBase.namePropertyKey: - if (object is ComponentBase && value is String) { - object.name = value; - } - break; - case ComponentBase.parentIdPropertyKey: - if (object is ComponentBase && value is int) { - object.parentId = value; - } - break; - case ViewModelInstanceBase.viewModelIdPropertyKey: - if (object is ViewModelInstanceBase && value is int) { - object.viewModelId = value; - } - break; - case ViewModelPropertyEnumBase.enumIdPropertyKey: - if (object is ViewModelPropertyEnumBase && value is int) { - object.enumId = value; - } - break; - case ViewModelInstanceBooleanBase.propertyValuePropertyKey: - if (object is ViewModelInstanceBooleanBase && value is bool) { - object.propertyValue = value; - } - break; - case ViewModelInstanceNumberBase.propertyValuePropertyKey: - if (object is ViewModelInstanceNumberBase && value is double) { - object.propertyValue = value; - } - break; - case ViewModelInstanceViewModelBase.propertyValuePropertyKey: - if (object is ViewModelInstanceViewModelBase && value is int) { - object.propertyValue = value; - } - break; - case DataEnumValueBase.keyPropertyKey: - if (object is DataEnumValueBase && value is String) { - object.key = value; - } - break; - case DataEnumValueBase.valuePropertyKey: - if (object is DataEnumValueBase && value is String) { - object.value = value; - } - break; - case DrawTargetBase.drawableIdPropertyKey: - if (object is DrawTargetBase && value is int) { - object.drawableId = value; - } - break; - case DrawTargetBase.placementValuePropertyKey: - if (object is DrawTargetBase && value is int) { - object.placementValue = value; - } - break; - case CustomPropertyNumberBase.propertyValuePropertyKey: - if (object is CustomPropertyNumberBase && value is double) { - object.propertyValue = value; - } - break; - case ConstraintBase.strengthPropertyKey: - if (object is ConstraintBase && value is double) { - object.strength = value; - } - break; - case TargetedConstraintBase.targetIdPropertyKey: - if (object is TargetedConstraintBase && value is int) { - object.targetId = value; - } - break; - case DistanceConstraintBase.distancePropertyKey: - if (object is DistanceConstraintBase && value is double) { - object.distance = value; - } - break; - case DistanceConstraintBase.modeValuePropertyKey: - if (object is DistanceConstraintBase && value is int) { - object.modeValue = value; - } - break; - case TransformSpaceConstraintBase.sourceSpaceValuePropertyKey: - if (object is TransformSpaceConstraintBase && value is int) { - object.sourceSpaceValue = value; - } - break; - case TransformSpaceConstraintBase.destSpaceValuePropertyKey: - if (object is TransformSpaceConstraintBase && value is int) { - object.destSpaceValue = value; - } - break; - case TransformComponentConstraintBase.minMaxSpaceValuePropertyKey: - if (object is TransformComponentConstraintBase && value is int) { - object.minMaxSpaceValue = value; - } - break; - case TransformComponentConstraintBase.copyFactorPropertyKey: - if (object is TransformComponentConstraintBase && value is double) { - object.copyFactor = value; - } - break; - case TransformComponentConstraintBase.minValuePropertyKey: - if (object is TransformComponentConstraintBase && value is double) { - object.minValue = value; - } - break; - case TransformComponentConstraintBase.maxValuePropertyKey: - if (object is TransformComponentConstraintBase && value is double) { - object.maxValue = value; - } - break; - case TransformComponentConstraintBase.offsetPropertyKey: - if (object is TransformComponentConstraintBase && value is bool) { - object.offset = value; - } - break; - case TransformComponentConstraintBase.doesCopyPropertyKey: - if (object is TransformComponentConstraintBase && value is bool) { - object.doesCopy = value; - } - break; - case TransformComponentConstraintBase.minPropertyKey: - if (object is TransformComponentConstraintBase && value is bool) { - object.min = value; - } - break; - case TransformComponentConstraintBase.maxPropertyKey: - if (object is TransformComponentConstraintBase && value is bool) { - object.max = value; - } - break; - case TransformComponentConstraintYBase.copyFactorYPropertyKey: - if (object is TransformComponentConstraintYBase && value is double) { - object.copyFactorY = value; - } - break; - case TransformComponentConstraintYBase.minValueYPropertyKey: - if (object is TransformComponentConstraintYBase && value is double) { - object.minValueY = value; - } - break; - case TransformComponentConstraintYBase.maxValueYPropertyKey: - if (object is TransformComponentConstraintYBase && value is double) { - object.maxValueY = value; - } - break; - case TransformComponentConstraintYBase.doesCopyYPropertyKey: - if (object is TransformComponentConstraintYBase && value is bool) { - object.doesCopyY = value; - } - break; - case TransformComponentConstraintYBase.minYPropertyKey: - if (object is TransformComponentConstraintYBase && value is bool) { - object.minY = value; - } - break; - case TransformComponentConstraintYBase.maxYPropertyKey: - if (object is TransformComponentConstraintYBase && value is bool) { - object.maxY = value; - } - break; - case IKConstraintBase.invertDirectionPropertyKey: - if (object is IKConstraintBase && value is bool) { - object.invertDirection = value; - } - break; - case IKConstraintBase.parentBoneCountPropertyKey: - if (object is IKConstraintBase && value is int) { - object.parentBoneCount = value; - } - break; - case FollowPathConstraintBase.distancePropertyKey: - if (object is FollowPathConstraintBase && value is double) { - object.distance = value; - } - break; - case FollowPathConstraintBase.orientPropertyKey: - if (object is FollowPathConstraintBase && value is bool) { - object.orient = value; - } - break; - case FollowPathConstraintBase.offsetPropertyKey: - if (object is FollowPathConstraintBase && value is bool) { - object.offset = value; - } - break; - case TransformConstraintBase.originXPropertyKey: - if (object is TransformConstraintBase && value is double) { - object.originX = value; - } - break; - case TransformConstraintBase.originYPropertyKey: - if (object is TransformConstraintBase && value is double) { - object.originY = value; - } - break; - case WorldTransformComponentBase.opacityPropertyKey: - if (object is WorldTransformComponentBase && value is double) { - object.opacity = value; - } - break; - case TransformComponentBase.rotationPropertyKey: - if (object is TransformComponentBase && value is double) { - object.rotation = value; - } - break; - case TransformComponentBase.scaleXPropertyKey: - if (object is TransformComponentBase && value is double) { - object.scaleX = value; - } - break; - case TransformComponentBase.scaleYPropertyKey: - if (object is TransformComponentBase && value is double) { - object.scaleY = value; - } - break; - case NodeBase.xPropertyKey: - if (object is NodeBase && value is double) { - object.x = value; - } - break; - case NodeBase.yPropertyKey: - if (object is NodeBase && value is double) { - object.y = value; - } - break; - case DrawableBase.blendModeValuePropertyKey: - if (object is DrawableBase && value is int) { - object.blendModeValue = value; - } - break; - case DrawableBase.drawableFlagsPropertyKey: - if (object is DrawableBase && value is int) { - object.drawableFlags = value; - } - break; - case NestedArtboardBase.artboardIdPropertyKey: - if (object is NestedArtboardBase && value is int) { - object.artboardId = value; - } - break; - case NestedArtboardBase.fitPropertyKey: - if (object is NestedArtboardBase && value is int) { - object.fit = value; - } - break; - case NestedArtboardBase.alignmentPropertyKey: - if (object is NestedArtboardBase && value is int) { - object.alignment = value; - } - break; - case NestedArtboardBase.dataBindPathIdsPropertyKey: - if (object is NestedArtboardBase && value is Uint8List) { - object.dataBindPathIds = value; - } - break; - case NestedAnimationBase.animationIdPropertyKey: - if (object is NestedAnimationBase && value is int) { - object.animationId = value; - } - break; - case SoloBase.activeComponentIdPropertyKey: - if (object is SoloBase && value is int) { - object.activeComponentId = value; - } - break; - case LayoutComponentStyleBase.gapHorizontalPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.gapHorizontal = value; - } - break; - case LayoutComponentStyleBase.gapVerticalPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.gapVertical = value; - } - break; - case LayoutComponentStyleBase.maxWidthPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.maxWidth = value; - } - break; - case LayoutComponentStyleBase.maxHeightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.maxHeight = value; - } - break; - case LayoutComponentStyleBase.minWidthPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.minWidth = value; - } - break; - case LayoutComponentStyleBase.minHeightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.minHeight = value; - } - break; - case LayoutComponentStyleBase.borderLeftPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.borderLeft = value; - } - break; - case LayoutComponentStyleBase.borderRightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.borderRight = value; - } - break; - case LayoutComponentStyleBase.borderTopPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.borderTop = value; - } - break; - case LayoutComponentStyleBase.borderBottomPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.borderBottom = value; - } - break; - case LayoutComponentStyleBase.marginLeftPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.marginLeft = value; - } - break; - case LayoutComponentStyleBase.marginRightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.marginRight = value; - } - break; - case LayoutComponentStyleBase.marginTopPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.marginTop = value; - } - break; - case LayoutComponentStyleBase.marginBottomPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.marginBottom = value; - } - break; - case LayoutComponentStyleBase.paddingLeftPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.paddingLeft = value; - } - break; - case LayoutComponentStyleBase.paddingRightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.paddingRight = value; - } - break; - case LayoutComponentStyleBase.paddingTopPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.paddingTop = value; - } - break; - case LayoutComponentStyleBase.paddingBottomPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.paddingBottom = value; - } - break; - case LayoutComponentStyleBase.positionLeftPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.positionLeft = value; - } - break; - case LayoutComponentStyleBase.positionRightPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.positionRight = value; - } - break; - case LayoutComponentStyleBase.positionTopPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.positionTop = value; - } - break; - case LayoutComponentStyleBase.positionBottomPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.positionBottom = value; - } - break; - case LayoutComponentStyleBase.flexPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.flex = value; - } - break; - case LayoutComponentStyleBase.flexGrowPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.flexGrow = value; - } - break; - case LayoutComponentStyleBase.flexShrinkPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.flexShrink = value; - } - break; - case LayoutComponentStyleBase.flexBasisPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.flexBasis = value; - } - break; - case LayoutComponentStyleBase.aspectRatioPropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.aspectRatio = value; - } - break; - case LayoutComponentStyleBase.scaleTypePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.scaleType = value; - } - break; - case LayoutComponentStyleBase.layoutAlignmentTypePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.layoutAlignmentType = value; - } - break; - case LayoutComponentStyleBase.animationStyleTypePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.animationStyleType = value; - } - break; - case LayoutComponentStyleBase.interpolationTypePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.interpolationType = value; - } - break; - case LayoutComponentStyleBase.interpolatorIdPropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.interpolatorId = value; - } - break; - case LayoutComponentStyleBase.interpolationTimePropertyKey: - if (object is LayoutComponentStyleBase && value is double) { - object.interpolationTime = value; - } - break; - case LayoutComponentStyleBase.displayValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.displayValue = value; - } - break; - case LayoutComponentStyleBase.positionTypeValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.positionTypeValue = value; - } - break; - case LayoutComponentStyleBase.flexDirectionValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.flexDirectionValue = value; - } - break; - case LayoutComponentStyleBase.directionValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.directionValue = value; - } - break; - case LayoutComponentStyleBase.alignContentValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.alignContentValue = value; - } - break; - case LayoutComponentStyleBase.alignItemsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.alignItemsValue = value; - } - break; - case LayoutComponentStyleBase.alignSelfValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.alignSelfValue = value; - } - break; - case LayoutComponentStyleBase.justifyContentValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.justifyContentValue = value; - } - break; - case LayoutComponentStyleBase.flexWrapValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.flexWrapValue = value; - } - break; - case LayoutComponentStyleBase.overflowValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.overflowValue = value; - } - break; - case LayoutComponentStyleBase.intrinsicallySizedValuePropertyKey: - if (object is LayoutComponentStyleBase && value is bool) { - object.intrinsicallySizedValue = value; - } - break; - case LayoutComponentStyleBase.widthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.widthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.heightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.heightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.borderLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.borderRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.borderTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.borderBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.marginLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.marginRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.marginTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.marginBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.paddingLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.paddingRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.paddingTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.paddingBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.positionLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.positionRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.positionTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.positionBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.gapHorizontalUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.gapHorizontalUnitsValue = value; - } - break; - case LayoutComponentStyleBase.gapVerticalUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.gapVerticalUnitsValue = value; - } - break; - case LayoutComponentStyleBase.minWidthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.minWidthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.minHeightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.minHeightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.maxWidthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.maxWidthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.maxHeightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase && value is int) { - object.maxHeightUnitsValue = value; - } - break; - case ListenerFireEventBase.eventIdPropertyKey: - if (object is ListenerFireEventBase && value is int) { - object.eventId = value; - } - break; - case LayerStateBase.flagsPropertyKey: - if (object is LayerStateBase && value is int) { - object.flags = value; - } - break; - case KeyFrameBase.framePropertyKey: - if (object is KeyFrameBase && value is int) { - object.frame = value; - } - break; - case InterpolatingKeyFrameBase.interpolationTypePropertyKey: - if (object is InterpolatingKeyFrameBase && value is int) { - object.interpolationType = value; - } - break; - case InterpolatingKeyFrameBase.interpolatorIdPropertyKey: - if (object is InterpolatingKeyFrameBase && value is int) { - object.interpolatorId = value; - } - break; - case KeyFrameUintBase.valuePropertyKey: - if (object is KeyFrameUintBase && value is int) { - object.value = value; - } - break; - case AnimationBase.namePropertyKey: - if (object is AnimationBase && value is String) { - object.name = value; - } - break; - case LinearAnimationBase.fpsPropertyKey: - if (object is LinearAnimationBase && value is int) { - object.fps = value; - } - break; - case LinearAnimationBase.durationPropertyKey: - if (object is LinearAnimationBase && value is int) { - object.duration = value; - } - break; - case LinearAnimationBase.speedPropertyKey: - if (object is LinearAnimationBase && value is double) { - object.speed = value; - } - break; - case LinearAnimationBase.loopValuePropertyKey: - if (object is LinearAnimationBase && value is int) { - object.loopValue = value; - } - break; - case LinearAnimationBase.workStartPropertyKey: - if (object is LinearAnimationBase && value is int) { - object.workStart = value; - } - break; - case LinearAnimationBase.workEndPropertyKey: - if (object is LinearAnimationBase && value is int) { - object.workEnd = value; - } - break; - case LinearAnimationBase.enableWorkAreaPropertyKey: - if (object is LinearAnimationBase && value is bool) { - object.enableWorkArea = value; - } - break; - case LinearAnimationBase.quantizePropertyKey: - if (object is LinearAnimationBase && value is bool) { - object.quantize = value; - } - break; - case NestedLinearAnimationBase.mixPropertyKey: - if (object is NestedLinearAnimationBase && value is double) { - object.mix = value; - } - break; - case NestedSimpleAnimationBase.speedPropertyKey: - if (object is NestedSimpleAnimationBase && value is double) { - object.speed = value; - } - break; - case NestedSimpleAnimationBase.isPlayingPropertyKey: - if (object is NestedSimpleAnimationBase && value is bool) { - object.isPlaying = value; - } - break; - case ListenerInputChangeBase.inputIdPropertyKey: - if (object is ListenerInputChangeBase && value is int) { - object.inputId = value; - } - break; - case ListenerInputChangeBase.nestedInputIdPropertyKey: - if (object is ListenerInputChangeBase && value is int) { - object.nestedInputId = value; - } - break; - case AdvanceableStateBase.speedPropertyKey: - if (object is AdvanceableStateBase && value is double) { - object.speed = value; - } - break; - case AnimationStateBase.animationIdPropertyKey: - if (object is AnimationStateBase && value is int) { - object.animationId = value; - } - break; - case NestedInputBase.inputIdPropertyKey: - if (object is NestedInputBase && value is int) { - object.inputId = value; - } - break; - case KeyedObjectBase.objectIdPropertyKey: - if (object is KeyedObjectBase && value is int) { - object.objectId = value; - } - break; - case BlendAnimationBase.animationIdPropertyKey: - if (object is BlendAnimationBase && value is int) { - object.animationId = value; - } - break; - case BlendAnimationDirectBase.inputIdPropertyKey: - if (object is BlendAnimationDirectBase && value is int) { - object.inputId = value; - } - break; - case BlendAnimationDirectBase.mixValuePropertyKey: - if (object is BlendAnimationDirectBase && value is double) { - object.mixValue = value; - } - break; - case BlendAnimationDirectBase.blendSourcePropertyKey: - if (object is BlendAnimationDirectBase && value is int) { - object.blendSource = value; - } - break; - case StateMachineComponentBase.namePropertyKey: - if (object is StateMachineComponentBase && value is String) { - object.name = value; - } - break; - case StateMachineNumberBase.valuePropertyKey: - if (object is StateMachineNumberBase && value is double) { - object.value = value; - } - break; - case CubicInterpolatorBase.x1PropertyKey: - if (object is CubicInterpolatorBase && value is double) { - object.x1 = value; - } - break; - case CubicInterpolatorBase.y1PropertyKey: - if (object is CubicInterpolatorBase && value is double) { - object.y1 = value; - } - break; - case CubicInterpolatorBase.x2PropertyKey: - if (object is CubicInterpolatorBase && value is double) { - object.x2 = value; - } - break; - case CubicInterpolatorBase.y2PropertyKey: - if (object is CubicInterpolatorBase && value is double) { - object.y2 = value; - } - break; - case TransitionInputConditionBase.inputIdPropertyKey: - if (object is TransitionInputConditionBase && value is int) { - object.inputId = value; - } - break; - case KeyedPropertyBase.propertyKeyPropertyKey: - if (object is KeyedPropertyBase && value is int) { - object.propertyKey = value; - } - break; - case StateMachineListenerBase.targetIdPropertyKey: - if (object is StateMachineListenerBase && value is int) { - object.targetId = value; - } - break; - case StateMachineListenerBase.listenerTypeValuePropertyKey: - if (object is StateMachineListenerBase && value is int) { - object.listenerTypeValue = value; - } - break; - case StateMachineListenerBase.eventIdPropertyKey: - if (object is StateMachineListenerBase && value is int) { - object.eventId = value; - } - break; - case KeyFrameIdBase.valuePropertyKey: - if (object is KeyFrameIdBase && value is int) { - object.value = value; - } - break; - case KeyFrameBoolBase.valuePropertyKey: - if (object is KeyFrameBoolBase && value is bool) { - object.value = value; - } - break; - case ListenerBoolChangeBase.valuePropertyKey: - if (object is ListenerBoolChangeBase && value is int) { - object.value = value; - } - break; - case ListenerAlignTargetBase.targetIdPropertyKey: - if (object is ListenerAlignTargetBase && value is int) { - object.targetId = value; - } - break; - case ListenerAlignTargetBase.preserveOffsetPropertyKey: - if (object is ListenerAlignTargetBase && value is bool) { - object.preserveOffset = value; - } - break; - case TransitionValueConditionBase.opValuePropertyKey: - if (object is TransitionValueConditionBase && value is int) { - object.opValue = value; - } - break; - case TransitionNumberConditionBase.valuePropertyKey: - if (object is TransitionNumberConditionBase && value is double) { - object.value = value; - } - break; - case TransitionValueBooleanComparatorBase.valuePropertyKey: - if (object is TransitionValueBooleanComparatorBase && value is bool) { - object.value = value; - } - break; - case CubicInterpolatorComponentBase.x1PropertyKey: - if (object is CubicInterpolatorComponentBase && value is double) { - object.x1 = value; - } - break; - case CubicInterpolatorComponentBase.y1PropertyKey: - if (object is CubicInterpolatorComponentBase && value is double) { - object.y1 = value; - } - break; - case CubicInterpolatorComponentBase.x2PropertyKey: - if (object is CubicInterpolatorComponentBase && value is double) { - object.x2 = value; - } - break; - case CubicInterpolatorComponentBase.y2PropertyKey: - if (object is CubicInterpolatorComponentBase && value is double) { - object.y2 = value; - } - break; - case KeyFrameStringBase.valuePropertyKey: - if (object is KeyFrameStringBase && value is String) { - object.value = value; - } - break; - case ListenerNumberChangeBase.valuePropertyKey: - if (object is ListenerNumberChangeBase && value is double) { - object.value = value; - } - break; - case TransitionViewModelConditionBase.leftComparatorIdPropertyKey: - if (object is TransitionViewModelConditionBase && value is int) { - object.leftComparatorId = value; - } - break; - case TransitionViewModelConditionBase.rightComparatorIdPropertyKey: - if (object is TransitionViewModelConditionBase && value is int) { - object.rightComparatorId = value; - } - break; - case TransitionViewModelConditionBase.opValuePropertyKey: - if (object is TransitionViewModelConditionBase && value is int) { - object.opValue = value; - } - break; - case StateTransitionBase.stateToIdPropertyKey: - if (object is StateTransitionBase && value is int) { - object.stateToId = value; - } - break; - case StateTransitionBase.flagsPropertyKey: - if (object is StateTransitionBase && value is int) { - object.flags = value; - } - break; - case StateTransitionBase.durationPropertyKey: - if (object is StateTransitionBase && value is int) { - object.duration = value; - } - break; - case StateTransitionBase.exitTimePropertyKey: - if (object is StateTransitionBase && value is int) { - object.exitTime = value; - } - break; - case StateTransitionBase.interpolationTypePropertyKey: - if (object is StateTransitionBase && value is int) { - object.interpolationType = value; - } - break; - case StateTransitionBase.interpolatorIdPropertyKey: - if (object is StateTransitionBase && value is int) { - object.interpolatorId = value; - } - break; - case StateTransitionBase.randomWeightPropertyKey: - if (object is StateTransitionBase && value is int) { - object.randomWeight = value; - } - break; - case NestedBoolBase.nestedValuePropertyKey: - if (object is NestedBoolBase && value is bool) { - object.nestedValue = value; - } - break; - case KeyFrameDoubleBase.valuePropertyKey: - if (object is KeyFrameDoubleBase && value is double) { - object.value = value; - } - break; - case KeyFrameColorBase.valuePropertyKey: - if (object is KeyFrameColorBase && value is int) { - object.value = value; - } - break; - case StateMachineFireEventBase.eventIdPropertyKey: - if (object is StateMachineFireEventBase && value is int) { - object.eventId = value; - } - break; - case StateMachineFireEventBase.occursValuePropertyKey: - if (object is StateMachineFireEventBase && value is int) { - object.occursValue = value; - } - break; - case TransitionValueColorComparatorBase.valuePropertyKey: - if (object is TransitionValueColorComparatorBase && value is int) { - object.value = value; - } - break; - case TransitionValueNumberComparatorBase.valuePropertyKey: - if (object is TransitionValueNumberComparatorBase && value is double) { - object.value = value; - } - break; - case ElasticInterpolatorBase.easingValuePropertyKey: - if (object is ElasticInterpolatorBase && value is int) { - object.easingValue = value; - } - break; - case ElasticInterpolatorBase.amplitudePropertyKey: - if (object is ElasticInterpolatorBase && value is double) { - object.amplitude = value; - } - break; - case ElasticInterpolatorBase.periodPropertyKey: - if (object is ElasticInterpolatorBase && value is double) { - object.period = value; - } - break; - case NestedNumberBase.nestedValuePropertyKey: - if (object is NestedNumberBase && value is double) { - object.nestedValue = value; - } - break; - case BlendAnimation1DBase.valuePropertyKey: - if (object is BlendAnimation1DBase && value is double) { - object.value = value; - } - break; - case BlendState1DBase.inputIdPropertyKey: - if (object is BlendState1DBase && value is int) { - object.inputId = value; - } - break; - case TransitionValueEnumComparatorBase.valuePropertyKey: - if (object is TransitionValueEnumComparatorBase && value is int) { - object.value = value; - } - break; - case TransitionValueStringComparatorBase.valuePropertyKey: - if (object is TransitionValueStringComparatorBase && value is String) { - object.value = value; - } - break; - case NestedRemapAnimationBase.timePropertyKey: - if (object is NestedRemapAnimationBase && value is double) { - object.time = value; - } - break; - case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey: - if (object is BlendStateTransitionBase && value is int) { - object.exitBlendAnimationId = value; - } - break; - case StateMachineBoolBase.valuePropertyKey: - if (object is StateMachineBoolBase && value is bool) { - object.value = value; - } - break; - case ShapePaintBase.isVisiblePropertyKey: - if (object is ShapePaintBase && value is bool) { - object.isVisible = value; - } - break; - case LinearGradientBase.startXPropertyKey: - if (object is LinearGradientBase && value is double) { - object.startX = value; - } - break; - case LinearGradientBase.startYPropertyKey: - if (object is LinearGradientBase && value is double) { - object.startY = value; - } - break; - case LinearGradientBase.endXPropertyKey: - if (object is LinearGradientBase && value is double) { - object.endX = value; - } - break; - case LinearGradientBase.endYPropertyKey: - if (object is LinearGradientBase && value is double) { - object.endY = value; - } - break; - case LinearGradientBase.opacityPropertyKey: - if (object is LinearGradientBase && value is double) { - object.opacity = value; - } - break; - case StrokeBase.thicknessPropertyKey: - if (object is StrokeBase && value is double) { - object.thickness = value; - } - break; - case StrokeBase.capPropertyKey: - if (object is StrokeBase && value is int) { - object.cap = value; - } - break; - case StrokeBase.joinPropertyKey: - if (object is StrokeBase && value is int) { - object.join = value; - } - break; - case StrokeBase.transformAffectsStrokePropertyKey: - if (object is StrokeBase && value is bool) { - object.transformAffectsStroke = value; - } - break; - case SolidColorBase.colorValuePropertyKey: - if (object is SolidColorBase && value is int) { - object.colorValue = value; - } - break; - case GradientStopBase.colorValuePropertyKey: - if (object is GradientStopBase && value is int) { - object.colorValue = value; - } - break; - case GradientStopBase.positionPropertyKey: - if (object is GradientStopBase && value is double) { - object.position = value; - } - break; - case TrimPathBase.startPropertyKey: - if (object is TrimPathBase && value is double) { - object.start = value; - } - break; - case TrimPathBase.endPropertyKey: - if (object is TrimPathBase && value is double) { - object.end = value; - } - break; - case TrimPathBase.offsetPropertyKey: - if (object is TrimPathBase && value is double) { - object.offset = value; - } - break; - case TrimPathBase.modeValuePropertyKey: - if (object is TrimPathBase && value is int) { - object.modeValue = value; - } - break; - case FillBase.fillRulePropertyKey: - if (object is FillBase && value is int) { - object.fillRule = value; - } - break; - case VertexBase.xPropertyKey: - if (object is VertexBase && value is double) { - object.x = value; - } - break; - case VertexBase.yPropertyKey: - if (object is VertexBase && value is double) { - object.y = value; - } - break; - case MeshVertexBase.uPropertyKey: - if (object is MeshVertexBase && value is double) { - object.u = value; - } - break; - case MeshVertexBase.vPropertyKey: - if (object is MeshVertexBase && value is double) { - object.v = value; - } - break; - case PathBase.pathFlagsPropertyKey: - if (object is PathBase && value is int) { - object.pathFlags = value; - } - break; - case WeightBase.valuesPropertyKey: - if (object is WeightBase && value is int) { - object.values = value; - } - break; - case WeightBase.indicesPropertyKey: - if (object is WeightBase && value is int) { - object.indices = value; - } - break; - case StraightVertexBase.radiusPropertyKey: - if (object is StraightVertexBase && value is double) { - object.radius = value; - } - break; - case CubicWeightBase.inValuesPropertyKey: - if (object is CubicWeightBase && value is int) { - object.inValues = value; - } - break; - case CubicWeightBase.inIndicesPropertyKey: - if (object is CubicWeightBase && value is int) { - object.inIndices = value; - } - break; - case CubicWeightBase.outValuesPropertyKey: - if (object is CubicWeightBase && value is int) { - object.outValues = value; - } - break; - case CubicWeightBase.outIndicesPropertyKey: - if (object is CubicWeightBase && value is int) { - object.outIndices = value; - } - break; - case CubicAsymmetricVertexBase.rotationPropertyKey: - if (object is CubicAsymmetricVertexBase && value is double) { - object.rotation = value; - } - break; - case CubicAsymmetricVertexBase.inDistancePropertyKey: - if (object is CubicAsymmetricVertexBase && value is double) { - object.inDistance = value; - } - break; - case CubicAsymmetricVertexBase.outDistancePropertyKey: - if (object is CubicAsymmetricVertexBase && value is double) { - object.outDistance = value; - } - break; - case MeshBase.triangleIndexBytesPropertyKey: - if (object is MeshBase && value is Uint8List) { - object.triangleIndexBytes = value; - } - break; - case PointsPathBase.isClosedPropertyKey: - if (object is PointsPathBase && value is bool) { - object.isClosed = value; - } - break; - case ParametricPathBase.widthPropertyKey: - if (object is ParametricPathBase && value is double) { - object.width = value; - } - break; - case ParametricPathBase.heightPropertyKey: - if (object is ParametricPathBase && value is double) { - object.height = value; - } - break; - case ParametricPathBase.originXPropertyKey: - if (object is ParametricPathBase && value is double) { - object.originX = value; - } - break; - case ParametricPathBase.originYPropertyKey: - if (object is ParametricPathBase && value is double) { - object.originY = value; - } - break; - case RectangleBase.linkCornerRadiusPropertyKey: - if (object is RectangleBase && value is bool) { - object.linkCornerRadius = value; - } - break; - case RectangleBase.cornerRadiusTLPropertyKey: - if (object is RectangleBase && value is double) { - object.cornerRadiusTL = value; - } - break; - case RectangleBase.cornerRadiusTRPropertyKey: - if (object is RectangleBase && value is double) { - object.cornerRadiusTR = value; - } - break; - case RectangleBase.cornerRadiusBLPropertyKey: - if (object is RectangleBase && value is double) { - object.cornerRadiusBL = value; - } - break; - case RectangleBase.cornerRadiusBRPropertyKey: - if (object is RectangleBase && value is double) { - object.cornerRadiusBR = value; - } - break; - case CubicMirroredVertexBase.rotationPropertyKey: - if (object is CubicMirroredVertexBase && value is double) { - object.rotation = value; - } - break; - case CubicMirroredVertexBase.distancePropertyKey: - if (object is CubicMirroredVertexBase && value is double) { - object.distance = value; - } - break; - case ClippingShapeBase.sourceIdPropertyKey: - if (object is ClippingShapeBase && value is int) { - object.sourceId = value; - } - break; - case ClippingShapeBase.fillRulePropertyKey: - if (object is ClippingShapeBase && value is int) { - object.fillRule = value; - } - break; - case ClippingShapeBase.isVisiblePropertyKey: - if (object is ClippingShapeBase && value is bool) { - object.isVisible = value; - } - break; - case PolygonBase.pointsPropertyKey: - if (object is PolygonBase && value is int) { - object.points = value; - } - break; - case PolygonBase.cornerRadiusPropertyKey: - if (object is PolygonBase && value is double) { - object.cornerRadius = value; - } - break; - case StarBase.innerRadiusPropertyKey: - if (object is StarBase && value is double) { - object.innerRadius = value; - } - break; - case ImageBase.assetIdPropertyKey: - if (object is ImageBase && value is int) { - object.assetId = value; - } - break; - case ImageBase.originXPropertyKey: - if (object is ImageBase && value is double) { - object.originX = value; - } - break; - case ImageBase.originYPropertyKey: - if (object is ImageBase && value is double) { - object.originY = value; - } - break; - case CubicDetachedVertexBase.inRotationPropertyKey: - if (object is CubicDetachedVertexBase && value is double) { - object.inRotation = value; - } - break; - case CubicDetachedVertexBase.inDistancePropertyKey: - if (object is CubicDetachedVertexBase && value is double) { - object.inDistance = value; - } - break; - case CubicDetachedVertexBase.outRotationPropertyKey: - if (object is CubicDetachedVertexBase && value is double) { - object.outRotation = value; - } - break; - case CubicDetachedVertexBase.outDistancePropertyKey: - if (object is CubicDetachedVertexBase && value is double) { - object.outDistance = value; - } - break; - case DrawRulesBase.drawTargetIdPropertyKey: - if (object is DrawRulesBase && value is int) { - object.drawTargetId = value; - } - break; - case CustomPropertyBooleanBase.propertyValuePropertyKey: - if (object is CustomPropertyBooleanBase && value is bool) { - object.propertyValue = value; - } - break; - case LayoutComponentBase.clipPropertyKey: - if (object is LayoutComponentBase && value is bool) { - object.clip = value; - } - break; - case LayoutComponentBase.widthPropertyKey: - if (object is LayoutComponentBase && value is double) { - object.width = value; - } - break; - case LayoutComponentBase.heightPropertyKey: - if (object is LayoutComponentBase && value is double) { - object.height = value; - } - break; - case LayoutComponentBase.styleIdPropertyKey: - if (object is LayoutComponentBase && value is int) { - object.styleId = value; - } - break; - case ArtboardBase.xPropertyKey: - if (object is ArtboardBase && value is double) { - object.x = value; - } - break; - case ArtboardBase.yPropertyKey: - if (object is ArtboardBase && value is double) { - object.y = value; - } - break; - case ArtboardBase.originXPropertyKey: - if (object is ArtboardBase && value is double) { - object.originX = value; - } - break; - case ArtboardBase.originYPropertyKey: - if (object is ArtboardBase && value is double) { - object.originY = value; - } - break; - case ArtboardBase.defaultStateMachineIdPropertyKey: - if (object is ArtboardBase && value is int) { - object.defaultStateMachineId = value; - } - break; - case ArtboardBase.viewModelIdPropertyKey: - if (object is ArtboardBase && value is int) { - object.viewModelId = value; - } - break; - case JoystickBase.xPropertyKey: - if (object is JoystickBase && value is double) { - object.x = value; - } - break; - case JoystickBase.yPropertyKey: - if (object is JoystickBase && value is double) { - object.y = value; - } - break; - case JoystickBase.posXPropertyKey: - if (object is JoystickBase && value is double) { - object.posX = value; - } - break; - case JoystickBase.posYPropertyKey: - if (object is JoystickBase && value is double) { - object.posY = value; - } - break; - case JoystickBase.originXPropertyKey: - if (object is JoystickBase && value is double) { - object.originX = value; - } - break; - case JoystickBase.originYPropertyKey: - if (object is JoystickBase && value is double) { - object.originY = value; - } - break; - case JoystickBase.widthPropertyKey: - if (object is JoystickBase && value is double) { - object.width = value; - } - break; - case JoystickBase.heightPropertyKey: - if (object is JoystickBase && value is double) { - object.height = value; - } - break; - case JoystickBase.xIdPropertyKey: - if (object is JoystickBase && value is int) { - object.xId = value; - } - break; - case JoystickBase.yIdPropertyKey: - if (object is JoystickBase && value is int) { - object.yId = value; - } - break; - case JoystickBase.joystickFlagsPropertyKey: - if (object is JoystickBase && value is int) { - object.joystickFlags = value; - } - break; - case JoystickBase.handleSourceIdPropertyKey: - if (object is JoystickBase && value is int) { - object.handleSourceId = value; - } - break; - case OpenUrlEventBase.urlPropertyKey: - if (object is OpenUrlEventBase && value is String) { - object.url = value; - } - break; - case OpenUrlEventBase.targetValuePropertyKey: - if (object is OpenUrlEventBase && value is int) { - object.targetValue = value; - } - break; - case BindablePropertyBooleanBase.propertyValuePropertyKey: - if (object is BindablePropertyBooleanBase && value is bool) { - object.propertyValue = value; - } - break; - case DataBindBase.propertyKeyPropertyKey: - if (object is DataBindBase && value is int) { - object.propertyKey = value; - } - break; - case DataBindBase.flagsPropertyKey: - if (object is DataBindBase && value is int) { - object.flags = value; - } - break; - case DataBindBase.converterIdPropertyKey: - if (object is DataBindBase && value is int) { - object.converterId = value; - } - break; - case DataConverterBase.namePropertyKey: - if (object is DataConverterBase && value is String) { - object.name = value; - } - break; - case DataBindContextBase.sourcePathIdsPropertyKey: - if (object is DataBindContextBase && value is Uint8List) { - object.sourcePathIds = value; - } - break; - case BindablePropertyStringBase.propertyValuePropertyKey: - if (object is BindablePropertyStringBase && value is String) { - object.propertyValue = value; - } - break; - case BindablePropertyNumberBase.propertyValuePropertyKey: - if (object is BindablePropertyNumberBase && value is double) { - object.propertyValue = value; - } - break; - case BindablePropertyEnumBase.propertyValuePropertyKey: - if (object is BindablePropertyEnumBase && value is int) { - object.propertyValue = value; - } - break; - case BindablePropertyColorBase.propertyValuePropertyKey: - if (object is BindablePropertyColorBase && value is int) { - object.propertyValue = value; - } - break; - case BoneBase.lengthPropertyKey: - if (object is BoneBase && value is double) { - object.length = value; - } - break; - case RootBoneBase.xPropertyKey: - if (object is RootBoneBase && value is double) { - object.x = value; - } - break; - case RootBoneBase.yPropertyKey: - if (object is RootBoneBase && value is double) { - object.y = value; - } - break; - case SkinBase.xxPropertyKey: - if (object is SkinBase && value is double) { - object.xx = value; - } - break; - case SkinBase.yxPropertyKey: - if (object is SkinBase && value is double) { - object.yx = value; - } - break; - case SkinBase.xyPropertyKey: - if (object is SkinBase && value is double) { - object.xy = value; - } - break; - case SkinBase.yyPropertyKey: - if (object is SkinBase && value is double) { - object.yy = value; - } - break; - case SkinBase.txPropertyKey: - if (object is SkinBase && value is double) { - object.tx = value; - } - break; - case SkinBase.tyPropertyKey: - if (object is SkinBase && value is double) { - object.ty = value; - } - break; - case TendonBase.boneIdPropertyKey: - if (object is TendonBase && value is int) { - object.boneId = value; - } - break; - case TendonBase.xxPropertyKey: - if (object is TendonBase && value is double) { - object.xx = value; - } - break; - case TendonBase.yxPropertyKey: - if (object is TendonBase && value is double) { - object.yx = value; - } - break; - case TendonBase.xyPropertyKey: - if (object is TendonBase && value is double) { - object.xy = value; - } - break; - case TendonBase.yyPropertyKey: - if (object is TendonBase && value is double) { - object.yy = value; - } - break; - case TendonBase.txPropertyKey: - if (object is TendonBase && value is double) { - object.tx = value; - } - break; - case TendonBase.tyPropertyKey: - if (object is TendonBase && value is double) { - object.ty = value; - } - break; - case TextModifierRangeBase.modifyFromPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.modifyFrom = value; - } - break; - case TextModifierRangeBase.modifyToPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.modifyTo = value; - } - break; - case TextModifierRangeBase.strengthPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.strength = value; - } - break; - case TextModifierRangeBase.unitsValuePropertyKey: - if (object is TextModifierRangeBase && value is int) { - object.unitsValue = value; - } - break; - case TextModifierRangeBase.typeValuePropertyKey: - if (object is TextModifierRangeBase && value is int) { - object.typeValue = value; - } - break; - case TextModifierRangeBase.modeValuePropertyKey: - if (object is TextModifierRangeBase && value is int) { - object.modeValue = value; - } - break; - case TextModifierRangeBase.clampPropertyKey: - if (object is TextModifierRangeBase && value is bool) { - object.clamp = value; - } - break; - case TextModifierRangeBase.falloffFromPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.falloffFrom = value; - } - break; - case TextModifierRangeBase.falloffToPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.falloffTo = value; - } - break; - case TextModifierRangeBase.offsetPropertyKey: - if (object is TextModifierRangeBase && value is double) { - object.offset = value; - } - break; - case TextModifierRangeBase.runIdPropertyKey: - if (object is TextModifierRangeBase && value is int) { - object.runId = value; - } - break; - case TextStyleFeatureBase.tagPropertyKey: - if (object is TextStyleFeatureBase && value is int) { - object.tag = value; - } - break; - case TextStyleFeatureBase.featureValuePropertyKey: - if (object is TextStyleFeatureBase && value is int) { - object.featureValue = value; - } - break; - case TextVariationModifierBase.axisTagPropertyKey: - if (object is TextVariationModifierBase && value is int) { - object.axisTag = value; - } - break; - case TextVariationModifierBase.axisValuePropertyKey: - if (object is TextVariationModifierBase && value is double) { - object.axisValue = value; - } - break; - case TextModifierGroupBase.modifierFlagsPropertyKey: - if (object is TextModifierGroupBase && value is int) { - object.modifierFlags = value; - } - break; - case TextModifierGroupBase.originXPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.originX = value; - } - break; - case TextModifierGroupBase.originYPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.originY = value; - } - break; - case TextModifierGroupBase.opacityPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.opacity = value; - } - break; - case TextModifierGroupBase.xPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.x = value; - } - break; - case TextModifierGroupBase.yPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.y = value; - } - break; - case TextModifierGroupBase.rotationPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.rotation = value; - } - break; - case TextModifierGroupBase.scaleXPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.scaleX = value; - } - break; - case TextModifierGroupBase.scaleYPropertyKey: - if (object is TextModifierGroupBase && value is double) { - object.scaleY = value; - } - break; - case TextStyleBase.fontSizePropertyKey: - if (object is TextStyleBase && value is double) { - object.fontSize = value; - } - break; - case TextStyleBase.lineHeightPropertyKey: - if (object is TextStyleBase && value is double) { - object.lineHeight = value; - } - break; - case TextStyleBase.letterSpacingPropertyKey: - if (object is TextStyleBase && value is double) { - object.letterSpacing = value; - } - break; - case TextStyleBase.fontAssetIdPropertyKey: - if (object is TextStyleBase && value is int) { - object.fontAssetId = value; - } - break; - case TextStyleAxisBase.tagPropertyKey: - if (object is TextStyleAxisBase && value is int) { - object.tag = value; - } - break; - case TextStyleAxisBase.axisValuePropertyKey: - if (object is TextStyleAxisBase && value is double) { - object.axisValue = value; - } - break; - case TextBase.alignValuePropertyKey: - if (object is TextBase && value is int) { - object.alignValue = value; - } - break; - case TextBase.sizingValuePropertyKey: - if (object is TextBase && value is int) { - object.sizingValue = value; - } - break; - case TextBase.overflowValuePropertyKey: - if (object is TextBase && value is int) { - object.overflowValue = value; - } - break; - case TextBase.widthPropertyKey: - if (object is TextBase && value is double) { - object.width = value; - } - break; - case TextBase.heightPropertyKey: - if (object is TextBase && value is double) { - object.height = value; - } - break; - case TextBase.originXPropertyKey: - if (object is TextBase && value is double) { - object.originX = value; - } - break; - case TextBase.originYPropertyKey: - if (object is TextBase && value is double) { - object.originY = value; - } - break; - case TextBase.paragraphSpacingPropertyKey: - if (object is TextBase && value is double) { - object.paragraphSpacing = value; - } - break; - case TextBase.originValuePropertyKey: - if (object is TextBase && value is int) { - object.originValue = value; - } - break; - case TextBase.wrapValuePropertyKey: - if (object is TextBase && value is int) { - object.wrapValue = value; - } - break; - case TextBase.verticalAlignValuePropertyKey: - if (object is TextBase && value is int) { - object.verticalAlignValue = value; - } - break; - case TextBase.fitFromBaselinePropertyKey: - if (object is TextBase && value is bool) { - object.fitFromBaseline = value; - } - break; - case TextValueRunBase.styleIdPropertyKey: - if (object is TextValueRunBase && value is int) { - object.styleId = value; - } - break; - case TextValueRunBase.textPropertyKey: - if (object is TextValueRunBase && value is String) { - object.text = value; - } - break; - case CustomPropertyStringBase.propertyValuePropertyKey: - if (object is CustomPropertyStringBase && value is String) { - object.propertyValue = value; - } - break; - case AssetBase.namePropertyKey: - if (object is AssetBase && value is String) { - object.name = value; - } - break; - case FileAssetBase.assetIdPropertyKey: - if (object is FileAssetBase && value is int) { - object.assetId = value; - } - break; - case FileAssetBase.cdnUuidPropertyKey: - if (object is FileAssetBase && value is Uint8List) { - object.cdnUuid = value; - } - break; - case FileAssetBase.cdnBaseUrlPropertyKey: - if (object is FileAssetBase && value is String) { - object.cdnBaseUrl = value; - } - break; - case ExportAudioBase.volumePropertyKey: - if (object is ExportAudioBase && value is double) { - object.volume = value; - } - break; - case DrawableAssetBase.heightPropertyKey: - if (object is DrawableAssetBase && value is double) { - object.height = value; - } - break; - case DrawableAssetBase.widthPropertyKey: - if (object is DrawableAssetBase && value is double) { - object.width = value; - } - break; - case FileAssetContentsBase.bytesPropertyKey: - if (object is FileAssetContentsBase && value is Uint8List) { - object.bytes = value; - } - break; - case AudioEventBase.assetIdPropertyKey: - if (object is AudioEventBase && value is int) { - object.assetId = value; - } - break; - } - } - - static CoreFieldType boolType = CoreBoolType(); - static CoreFieldType uintType = CoreUintType(); - static CoreFieldType colorType = CoreColorType(); - static CoreFieldType stringType = CoreStringType(); - static CoreFieldType doubleType = CoreDoubleType(); - static CoreFieldType bytesType = CoreBytesType(); - static CoreFieldType callbackType = CoreCallbackType(); - static CoreFieldType? coreType(int propertyKey) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.useLinkedArtboardPropertyKey: - case ViewModelInstanceBooleanBase.propertyValuePropertyKey: - case TransformComponentConstraintBase.offsetPropertyKey: - case TransformComponentConstraintBase.doesCopyPropertyKey: - case TransformComponentConstraintBase.minPropertyKey: - case TransformComponentConstraintBase.maxPropertyKey: - case TransformComponentConstraintYBase.doesCopyYPropertyKey: - case TransformComponentConstraintYBase.minYPropertyKey: - case TransformComponentConstraintYBase.maxYPropertyKey: - case IKConstraintBase.invertDirectionPropertyKey: - case FollowPathConstraintBase.orientPropertyKey: - case FollowPathConstraintBase.offsetPropertyKey: - case LayoutComponentStyleBase.intrinsicallySizedValuePropertyKey: - case LinearAnimationBase.enableWorkAreaPropertyKey: - case LinearAnimationBase.quantizePropertyKey: - case NestedSimpleAnimationBase.isPlayingPropertyKey: - case KeyFrameBoolBase.valuePropertyKey: - case ListenerAlignTargetBase.preserveOffsetPropertyKey: - case TransitionValueBooleanComparatorBase.valuePropertyKey: - case NestedBoolBase.nestedValuePropertyKey: - case StateMachineBoolBase.valuePropertyKey: - case ShapePaintBase.isVisiblePropertyKey: - case StrokeBase.transformAffectsStrokePropertyKey: - case PointsPathBase.isClosedPropertyKey: - case RectangleBase.linkCornerRadiusPropertyKey: - case ClippingShapeBase.isVisiblePropertyKey: - case CustomPropertyBooleanBase.propertyValuePropertyKey: - case LayoutComponentBase.clipPropertyKey: - case BindablePropertyBooleanBase.propertyValuePropertyKey: - case TextModifierRangeBase.clampPropertyKey: - case TextBase.fitFromBaselinePropertyKey: - return boolType; - case ViewModelInstanceListItemBase.viewModelIdPropertyKey: - case ViewModelInstanceListItemBase.viewModelInstanceIdPropertyKey: - case ViewModelInstanceListItemBase.artboardIdPropertyKey: - case ViewModelInstanceValueBase.viewModelPropertyIdPropertyKey: - case ViewModelInstanceEnumBase.propertyValuePropertyKey: - case ViewModelBase.defaultInstanceIdPropertyKey: - case ViewModelPropertyViewModelBase.viewModelReferenceIdPropertyKey: - case ComponentBase.parentIdPropertyKey: - case ViewModelInstanceBase.viewModelIdPropertyKey: - case ViewModelPropertyEnumBase.enumIdPropertyKey: - case ViewModelInstanceViewModelBase.propertyValuePropertyKey: - case DrawTargetBase.drawableIdPropertyKey: - case DrawTargetBase.placementValuePropertyKey: - case TargetedConstraintBase.targetIdPropertyKey: - case DistanceConstraintBase.modeValuePropertyKey: - case TransformSpaceConstraintBase.sourceSpaceValuePropertyKey: - case TransformSpaceConstraintBase.destSpaceValuePropertyKey: - case TransformComponentConstraintBase.minMaxSpaceValuePropertyKey: - case IKConstraintBase.parentBoneCountPropertyKey: - case DrawableBase.blendModeValuePropertyKey: - case DrawableBase.drawableFlagsPropertyKey: - case NestedArtboardBase.artboardIdPropertyKey: - case NestedArtboardBase.fitPropertyKey: - case NestedArtboardBase.alignmentPropertyKey: - case NestedAnimationBase.animationIdPropertyKey: - case SoloBase.activeComponentIdPropertyKey: - case LayoutComponentStyleBase.scaleTypePropertyKey: - case LayoutComponentStyleBase.layoutAlignmentTypePropertyKey: - case LayoutComponentStyleBase.animationStyleTypePropertyKey: - case LayoutComponentStyleBase.interpolationTypePropertyKey: - case LayoutComponentStyleBase.interpolatorIdPropertyKey: - case LayoutComponentStyleBase.displayValuePropertyKey: - case LayoutComponentStyleBase.positionTypeValuePropertyKey: - case LayoutComponentStyleBase.flexDirectionValuePropertyKey: - case LayoutComponentStyleBase.directionValuePropertyKey: - case LayoutComponentStyleBase.alignContentValuePropertyKey: - case LayoutComponentStyleBase.alignItemsValuePropertyKey: - case LayoutComponentStyleBase.alignSelfValuePropertyKey: - case LayoutComponentStyleBase.justifyContentValuePropertyKey: - case LayoutComponentStyleBase.flexWrapValuePropertyKey: - case LayoutComponentStyleBase.overflowValuePropertyKey: - case LayoutComponentStyleBase.widthUnitsValuePropertyKey: - case LayoutComponentStyleBase.heightUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.gapHorizontalUnitsValuePropertyKey: - case LayoutComponentStyleBase.gapVerticalUnitsValuePropertyKey: - case LayoutComponentStyleBase.minWidthUnitsValuePropertyKey: - case LayoutComponentStyleBase.minHeightUnitsValuePropertyKey: - case LayoutComponentStyleBase.maxWidthUnitsValuePropertyKey: - case LayoutComponentStyleBase.maxHeightUnitsValuePropertyKey: - case ListenerFireEventBase.eventIdPropertyKey: - case LayerStateBase.flagsPropertyKey: - case KeyFrameBase.framePropertyKey: - case InterpolatingKeyFrameBase.interpolationTypePropertyKey: - case InterpolatingKeyFrameBase.interpolatorIdPropertyKey: - case KeyFrameUintBase.valuePropertyKey: - case LinearAnimationBase.fpsPropertyKey: - case LinearAnimationBase.durationPropertyKey: - case LinearAnimationBase.loopValuePropertyKey: - case LinearAnimationBase.workStartPropertyKey: - case LinearAnimationBase.workEndPropertyKey: - case ListenerInputChangeBase.inputIdPropertyKey: - case ListenerInputChangeBase.nestedInputIdPropertyKey: - case AnimationStateBase.animationIdPropertyKey: - case NestedInputBase.inputIdPropertyKey: - case KeyedObjectBase.objectIdPropertyKey: - case BlendAnimationBase.animationIdPropertyKey: - case BlendAnimationDirectBase.inputIdPropertyKey: - case BlendAnimationDirectBase.blendSourcePropertyKey: - case TransitionInputConditionBase.inputIdPropertyKey: - case KeyedPropertyBase.propertyKeyPropertyKey: - case StateMachineListenerBase.targetIdPropertyKey: - case StateMachineListenerBase.listenerTypeValuePropertyKey: - case StateMachineListenerBase.eventIdPropertyKey: - case KeyFrameIdBase.valuePropertyKey: - case ListenerBoolChangeBase.valuePropertyKey: - case ListenerAlignTargetBase.targetIdPropertyKey: - case TransitionValueConditionBase.opValuePropertyKey: - case TransitionViewModelConditionBase.leftComparatorIdPropertyKey: - case TransitionViewModelConditionBase.rightComparatorIdPropertyKey: - case TransitionViewModelConditionBase.opValuePropertyKey: - case StateTransitionBase.stateToIdPropertyKey: - case StateTransitionBase.flagsPropertyKey: - case StateTransitionBase.durationPropertyKey: - case StateTransitionBase.exitTimePropertyKey: - case StateTransitionBase.interpolationTypePropertyKey: - case StateTransitionBase.interpolatorIdPropertyKey: - case StateTransitionBase.randomWeightPropertyKey: - case StateMachineFireEventBase.eventIdPropertyKey: - case StateMachineFireEventBase.occursValuePropertyKey: - case ElasticInterpolatorBase.easingValuePropertyKey: - case BlendState1DBase.inputIdPropertyKey: - case TransitionValueEnumComparatorBase.valuePropertyKey: - case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey: - case StrokeBase.capPropertyKey: - case StrokeBase.joinPropertyKey: - case TrimPathBase.modeValuePropertyKey: - case FillBase.fillRulePropertyKey: - case PathBase.pathFlagsPropertyKey: - case WeightBase.valuesPropertyKey: - case WeightBase.indicesPropertyKey: - case CubicWeightBase.inValuesPropertyKey: - case CubicWeightBase.inIndicesPropertyKey: - case CubicWeightBase.outValuesPropertyKey: - case CubicWeightBase.outIndicesPropertyKey: - case ClippingShapeBase.sourceIdPropertyKey: - case ClippingShapeBase.fillRulePropertyKey: - case PolygonBase.pointsPropertyKey: - case ImageBase.assetIdPropertyKey: - case DrawRulesBase.drawTargetIdPropertyKey: - case LayoutComponentBase.styleIdPropertyKey: - case ArtboardBase.defaultStateMachineIdPropertyKey: - case ArtboardBase.viewModelIdPropertyKey: - case JoystickBase.xIdPropertyKey: - case JoystickBase.yIdPropertyKey: - case JoystickBase.joystickFlagsPropertyKey: - case JoystickBase.handleSourceIdPropertyKey: - case OpenUrlEventBase.targetValuePropertyKey: - case DataBindBase.propertyKeyPropertyKey: - case DataBindBase.flagsPropertyKey: - case DataBindBase.converterIdPropertyKey: - case BindablePropertyEnumBase.propertyValuePropertyKey: - case TendonBase.boneIdPropertyKey: - case TextModifierRangeBase.unitsValuePropertyKey: - case TextModifierRangeBase.typeValuePropertyKey: - case TextModifierRangeBase.modeValuePropertyKey: - case TextModifierRangeBase.runIdPropertyKey: - case TextStyleFeatureBase.tagPropertyKey: - case TextStyleFeatureBase.featureValuePropertyKey: - case TextVariationModifierBase.axisTagPropertyKey: - case TextModifierGroupBase.modifierFlagsPropertyKey: - case TextStyleBase.fontAssetIdPropertyKey: - case TextStyleAxisBase.tagPropertyKey: - case TextBase.alignValuePropertyKey: - case TextBase.sizingValuePropertyKey: - case TextBase.overflowValuePropertyKey: - case TextBase.originValuePropertyKey: - case TextBase.wrapValuePropertyKey: - case TextBase.verticalAlignValuePropertyKey: - case TextValueRunBase.styleIdPropertyKey: - case FileAssetBase.assetIdPropertyKey: - case AudioEventBase.assetIdPropertyKey: - return uintType; - case ViewModelInstanceColorBase.propertyValuePropertyKey: - case KeyFrameColorBase.valuePropertyKey: - case TransitionValueColorComparatorBase.valuePropertyKey: - case SolidColorBase.colorValuePropertyKey: - case GradientStopBase.colorValuePropertyKey: - case BindablePropertyColorBase.propertyValuePropertyKey: - return colorType; - case ViewModelComponentBase.namePropertyKey: - case ViewModelInstanceStringBase.propertyValuePropertyKey: - case ComponentBase.namePropertyKey: - case DataEnumValueBase.keyPropertyKey: - case DataEnumValueBase.valuePropertyKey: - case AnimationBase.namePropertyKey: - case StateMachineComponentBase.namePropertyKey: - case KeyFrameStringBase.valuePropertyKey: - case TransitionValueStringComparatorBase.valuePropertyKey: - case OpenUrlEventBase.urlPropertyKey: - case DataConverterBase.namePropertyKey: - case BindablePropertyStringBase.propertyValuePropertyKey: - case TextValueRunBase.textPropertyKey: - case CustomPropertyStringBase.propertyValuePropertyKey: - case AssetBase.namePropertyKey: - case FileAssetBase.cdnBaseUrlPropertyKey: - return stringType; - case ViewModelInstanceNumberBase.propertyValuePropertyKey: - case CustomPropertyNumberBase.propertyValuePropertyKey: - case ConstraintBase.strengthPropertyKey: - case DistanceConstraintBase.distancePropertyKey: - case TransformComponentConstraintBase.copyFactorPropertyKey: - case TransformComponentConstraintBase.minValuePropertyKey: - case TransformComponentConstraintBase.maxValuePropertyKey: - case TransformComponentConstraintYBase.copyFactorYPropertyKey: - case TransformComponentConstraintYBase.minValueYPropertyKey: - case TransformComponentConstraintYBase.maxValueYPropertyKey: - case FollowPathConstraintBase.distancePropertyKey: - case TransformConstraintBase.originXPropertyKey: - case TransformConstraintBase.originYPropertyKey: - case WorldTransformComponentBase.opacityPropertyKey: - case TransformComponentBase.rotationPropertyKey: - case TransformComponentBase.scaleXPropertyKey: - case TransformComponentBase.scaleYPropertyKey: - case NodeBase.xPropertyKey: - case NodeBase.yPropertyKey: - case LayoutComponentStyleBase.gapHorizontalPropertyKey: - case LayoutComponentStyleBase.gapVerticalPropertyKey: - case LayoutComponentStyleBase.maxWidthPropertyKey: - case LayoutComponentStyleBase.maxHeightPropertyKey: - case LayoutComponentStyleBase.minWidthPropertyKey: - case LayoutComponentStyleBase.minHeightPropertyKey: - case LayoutComponentStyleBase.borderLeftPropertyKey: - case LayoutComponentStyleBase.borderRightPropertyKey: - case LayoutComponentStyleBase.borderTopPropertyKey: - case LayoutComponentStyleBase.borderBottomPropertyKey: - case LayoutComponentStyleBase.marginLeftPropertyKey: - case LayoutComponentStyleBase.marginRightPropertyKey: - case LayoutComponentStyleBase.marginTopPropertyKey: - case LayoutComponentStyleBase.marginBottomPropertyKey: - case LayoutComponentStyleBase.paddingLeftPropertyKey: - case LayoutComponentStyleBase.paddingRightPropertyKey: - case LayoutComponentStyleBase.paddingTopPropertyKey: - case LayoutComponentStyleBase.paddingBottomPropertyKey: - case LayoutComponentStyleBase.positionLeftPropertyKey: - case LayoutComponentStyleBase.positionRightPropertyKey: - case LayoutComponentStyleBase.positionTopPropertyKey: - case LayoutComponentStyleBase.positionBottomPropertyKey: - case LayoutComponentStyleBase.flexPropertyKey: - case LayoutComponentStyleBase.flexGrowPropertyKey: - case LayoutComponentStyleBase.flexShrinkPropertyKey: - case LayoutComponentStyleBase.flexBasisPropertyKey: - case LayoutComponentStyleBase.aspectRatioPropertyKey: - case LayoutComponentStyleBase.interpolationTimePropertyKey: - case LinearAnimationBase.speedPropertyKey: - case NestedLinearAnimationBase.mixPropertyKey: - case NestedSimpleAnimationBase.speedPropertyKey: - case AdvanceableStateBase.speedPropertyKey: - case BlendAnimationDirectBase.mixValuePropertyKey: - case StateMachineNumberBase.valuePropertyKey: - case CubicInterpolatorBase.x1PropertyKey: - case CubicInterpolatorBase.y1PropertyKey: - case CubicInterpolatorBase.x2PropertyKey: - case CubicInterpolatorBase.y2PropertyKey: - case TransitionNumberConditionBase.valuePropertyKey: - case CubicInterpolatorComponentBase.x1PropertyKey: - case CubicInterpolatorComponentBase.y1PropertyKey: - case CubicInterpolatorComponentBase.x2PropertyKey: - case CubicInterpolatorComponentBase.y2PropertyKey: - case ListenerNumberChangeBase.valuePropertyKey: - case KeyFrameDoubleBase.valuePropertyKey: - case TransitionValueNumberComparatorBase.valuePropertyKey: - case ElasticInterpolatorBase.amplitudePropertyKey: - case ElasticInterpolatorBase.periodPropertyKey: - case NestedNumberBase.nestedValuePropertyKey: - case BlendAnimation1DBase.valuePropertyKey: - case NestedRemapAnimationBase.timePropertyKey: - case LinearGradientBase.startXPropertyKey: - case LinearGradientBase.startYPropertyKey: - case LinearGradientBase.endXPropertyKey: - case LinearGradientBase.endYPropertyKey: - case LinearGradientBase.opacityPropertyKey: - case StrokeBase.thicknessPropertyKey: - case GradientStopBase.positionPropertyKey: - case TrimPathBase.startPropertyKey: - case TrimPathBase.endPropertyKey: - case TrimPathBase.offsetPropertyKey: - case VertexBase.xPropertyKey: - case VertexBase.yPropertyKey: - case MeshVertexBase.uPropertyKey: - case MeshVertexBase.vPropertyKey: - case StraightVertexBase.radiusPropertyKey: - case CubicAsymmetricVertexBase.rotationPropertyKey: - case CubicAsymmetricVertexBase.inDistancePropertyKey: - case CubicAsymmetricVertexBase.outDistancePropertyKey: - case ParametricPathBase.widthPropertyKey: - case ParametricPathBase.heightPropertyKey: - case ParametricPathBase.originXPropertyKey: - case ParametricPathBase.originYPropertyKey: - case RectangleBase.cornerRadiusTLPropertyKey: - case RectangleBase.cornerRadiusTRPropertyKey: - case RectangleBase.cornerRadiusBLPropertyKey: - case RectangleBase.cornerRadiusBRPropertyKey: - case CubicMirroredVertexBase.rotationPropertyKey: - case CubicMirroredVertexBase.distancePropertyKey: - case PolygonBase.cornerRadiusPropertyKey: - case StarBase.innerRadiusPropertyKey: - case ImageBase.originXPropertyKey: - case ImageBase.originYPropertyKey: - case CubicDetachedVertexBase.inRotationPropertyKey: - case CubicDetachedVertexBase.inDistancePropertyKey: - case CubicDetachedVertexBase.outRotationPropertyKey: - case CubicDetachedVertexBase.outDistancePropertyKey: - case LayoutComponentBase.widthPropertyKey: - case LayoutComponentBase.heightPropertyKey: - case ArtboardBase.xPropertyKey: - case ArtboardBase.yPropertyKey: - case ArtboardBase.originXPropertyKey: - case ArtboardBase.originYPropertyKey: - case JoystickBase.xPropertyKey: - case JoystickBase.yPropertyKey: - case JoystickBase.posXPropertyKey: - case JoystickBase.posYPropertyKey: - case JoystickBase.originXPropertyKey: - case JoystickBase.originYPropertyKey: - case JoystickBase.widthPropertyKey: - case JoystickBase.heightPropertyKey: - case BindablePropertyNumberBase.propertyValuePropertyKey: - case BoneBase.lengthPropertyKey: - case RootBoneBase.xPropertyKey: - case RootBoneBase.yPropertyKey: - case SkinBase.xxPropertyKey: - case SkinBase.yxPropertyKey: - case SkinBase.xyPropertyKey: - case SkinBase.yyPropertyKey: - case SkinBase.txPropertyKey: - case SkinBase.tyPropertyKey: - case TendonBase.xxPropertyKey: - case TendonBase.yxPropertyKey: - case TendonBase.xyPropertyKey: - case TendonBase.yyPropertyKey: - case TendonBase.txPropertyKey: - case TendonBase.tyPropertyKey: - case TextModifierRangeBase.modifyFromPropertyKey: - case TextModifierRangeBase.modifyToPropertyKey: - case TextModifierRangeBase.strengthPropertyKey: - case TextModifierRangeBase.falloffFromPropertyKey: - case TextModifierRangeBase.falloffToPropertyKey: - case TextModifierRangeBase.offsetPropertyKey: - case TextVariationModifierBase.axisValuePropertyKey: - case TextModifierGroupBase.originXPropertyKey: - case TextModifierGroupBase.originYPropertyKey: - case TextModifierGroupBase.opacityPropertyKey: - case TextModifierGroupBase.xPropertyKey: - case TextModifierGroupBase.yPropertyKey: - case TextModifierGroupBase.rotationPropertyKey: - case TextModifierGroupBase.scaleXPropertyKey: - case TextModifierGroupBase.scaleYPropertyKey: - case TextStyleBase.fontSizePropertyKey: - case TextStyleBase.lineHeightPropertyKey: - case TextStyleBase.letterSpacingPropertyKey: - case TextStyleAxisBase.axisValuePropertyKey: - case TextBase.widthPropertyKey: - case TextBase.heightPropertyKey: - case TextBase.originXPropertyKey: - case TextBase.originYPropertyKey: - case TextBase.paragraphSpacingPropertyKey: - case ExportAudioBase.volumePropertyKey: - case DrawableAssetBase.heightPropertyKey: - case DrawableAssetBase.widthPropertyKey: - return doubleType; - case NestedArtboardBase.dataBindPathIdsPropertyKey: - case MeshBase.triangleIndexBytesPropertyKey: - case DataBindContextBase.sourcePathIdsPropertyKey: - case FileAssetBase.cdnUuidPropertyKey: - case FileAssetContentsBase.bytesPropertyKey: - return bytesType; - case NestedTriggerBase.firePropertyKey: - case EventBase.triggerPropertyKey: - return callbackType; - default: - return null; - } - } - - static bool isCallback(int propertyKey) { - switch (propertyKey) { - case NestedTriggerBase.firePropertyKey: - case EventBase.triggerPropertyKey: - return true; - default: - return false; - } - } - - static bool getBool(Core object, int propertyKey) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.useLinkedArtboardPropertyKey: - return (object as ViewModelInstanceListItemBase).useLinkedArtboard; - case ViewModelInstanceBooleanBase.propertyValuePropertyKey: - return (object as ViewModelInstanceBooleanBase).propertyValue; - case TransformComponentConstraintBase.offsetPropertyKey: - return (object as TransformComponentConstraintBase).offset; - case TransformComponentConstraintBase.doesCopyPropertyKey: - return (object as TransformComponentConstraintBase).doesCopy; - case TransformComponentConstraintBase.minPropertyKey: - return (object as TransformComponentConstraintBase).min; - case TransformComponentConstraintBase.maxPropertyKey: - return (object as TransformComponentConstraintBase).max; - case TransformComponentConstraintYBase.doesCopyYPropertyKey: - return (object as TransformComponentConstraintYBase).doesCopyY; - case TransformComponentConstraintYBase.minYPropertyKey: - return (object as TransformComponentConstraintYBase).minY; - case TransformComponentConstraintYBase.maxYPropertyKey: - return (object as TransformComponentConstraintYBase).maxY; - case IKConstraintBase.invertDirectionPropertyKey: - return (object as IKConstraintBase).invertDirection; - case FollowPathConstraintBase.orientPropertyKey: - return (object as FollowPathConstraintBase).orient; - case FollowPathConstraintBase.offsetPropertyKey: - return (object as FollowPathConstraintBase).offset; - case LayoutComponentStyleBase.intrinsicallySizedValuePropertyKey: - return (object as LayoutComponentStyleBase).intrinsicallySizedValue; - case LinearAnimationBase.enableWorkAreaPropertyKey: - return (object as LinearAnimationBase).enableWorkArea; - case LinearAnimationBase.quantizePropertyKey: - return (object as LinearAnimationBase).quantize; - case NestedSimpleAnimationBase.isPlayingPropertyKey: - return (object as NestedSimpleAnimationBase).isPlaying; - case KeyFrameBoolBase.valuePropertyKey: - return (object as KeyFrameBoolBase).value; - case ListenerAlignTargetBase.preserveOffsetPropertyKey: - return (object as ListenerAlignTargetBase).preserveOffset; - case TransitionValueBooleanComparatorBase.valuePropertyKey: - return (object as TransitionValueBooleanComparatorBase).value; - case NestedBoolBase.nestedValuePropertyKey: - return (object as NestedBoolBase).nestedValue; - case StateMachineBoolBase.valuePropertyKey: - return (object as StateMachineBoolBase).value; - case ShapePaintBase.isVisiblePropertyKey: - return (object as ShapePaintBase).isVisible; - case StrokeBase.transformAffectsStrokePropertyKey: - return (object as StrokeBase).transformAffectsStroke; - case PointsPathBase.isClosedPropertyKey: - return (object as PointsPathBase).isClosed; - case RectangleBase.linkCornerRadiusPropertyKey: - return (object as RectangleBase).linkCornerRadius; - case ClippingShapeBase.isVisiblePropertyKey: - return (object as ClippingShapeBase).isVisible; - case CustomPropertyBooleanBase.propertyValuePropertyKey: - return (object as CustomPropertyBooleanBase).propertyValue; - case LayoutComponentBase.clipPropertyKey: - return (object as LayoutComponentBase).clip; - case BindablePropertyBooleanBase.propertyValuePropertyKey: - return (object as BindablePropertyBooleanBase).propertyValue; - case TextModifierRangeBase.clampPropertyKey: - return (object as TextModifierRangeBase).clamp; - case TextBase.fitFromBaselinePropertyKey: - return (object as TextBase).fitFromBaseline; - } - return false; - } - - static int getUint(Core object, int propertyKey) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.viewModelIdPropertyKey: - return (object as ViewModelInstanceListItemBase).viewModelId; - case ViewModelInstanceListItemBase.viewModelInstanceIdPropertyKey: - return (object as ViewModelInstanceListItemBase).viewModelInstanceId; - case ViewModelInstanceListItemBase.artboardIdPropertyKey: - return (object as ViewModelInstanceListItemBase).artboardId; - case ViewModelInstanceValueBase.viewModelPropertyIdPropertyKey: - return (object as ViewModelInstanceValueBase).viewModelPropertyId; - case ViewModelInstanceEnumBase.propertyValuePropertyKey: - return (object as ViewModelInstanceEnumBase).propertyValue; - case ViewModelBase.defaultInstanceIdPropertyKey: - return (object as ViewModelBase).defaultInstanceId; - case ViewModelPropertyViewModelBase.viewModelReferenceIdPropertyKey: - return (object as ViewModelPropertyViewModelBase).viewModelReferenceId; - case ComponentBase.parentIdPropertyKey: - return (object as ComponentBase).parentId; - case ViewModelInstanceBase.viewModelIdPropertyKey: - return (object as ViewModelInstanceBase).viewModelId; - case ViewModelPropertyEnumBase.enumIdPropertyKey: - return (object as ViewModelPropertyEnumBase).enumId; - case ViewModelInstanceViewModelBase.propertyValuePropertyKey: - return (object as ViewModelInstanceViewModelBase).propertyValue; - case DrawTargetBase.drawableIdPropertyKey: - return (object as DrawTargetBase).drawableId; - case DrawTargetBase.placementValuePropertyKey: - return (object as DrawTargetBase).placementValue; - case TargetedConstraintBase.targetIdPropertyKey: - return (object as TargetedConstraintBase).targetId; - case DistanceConstraintBase.modeValuePropertyKey: - return (object as DistanceConstraintBase).modeValue; - case TransformSpaceConstraintBase.sourceSpaceValuePropertyKey: - return (object as TransformSpaceConstraintBase).sourceSpaceValue; - case TransformSpaceConstraintBase.destSpaceValuePropertyKey: - return (object as TransformSpaceConstraintBase).destSpaceValue; - case TransformComponentConstraintBase.minMaxSpaceValuePropertyKey: - return (object as TransformComponentConstraintBase).minMaxSpaceValue; - case IKConstraintBase.parentBoneCountPropertyKey: - return (object as IKConstraintBase).parentBoneCount; - case DrawableBase.blendModeValuePropertyKey: - return (object as DrawableBase).blendModeValue; - case DrawableBase.drawableFlagsPropertyKey: - return (object as DrawableBase).drawableFlags; - case NestedArtboardBase.artboardIdPropertyKey: - return (object as NestedArtboardBase).artboardId; - case NestedArtboardBase.fitPropertyKey: - return (object as NestedArtboardBase).fit; - case NestedArtboardBase.alignmentPropertyKey: - return (object as NestedArtboardBase).alignment; - case NestedAnimationBase.animationIdPropertyKey: - return (object as NestedAnimationBase).animationId; - case SoloBase.activeComponentIdPropertyKey: - return (object as SoloBase).activeComponentId; - case LayoutComponentStyleBase.scaleTypePropertyKey: - return (object as LayoutComponentStyleBase).scaleType; - case LayoutComponentStyleBase.layoutAlignmentTypePropertyKey: - return (object as LayoutComponentStyleBase).layoutAlignmentType; - case LayoutComponentStyleBase.animationStyleTypePropertyKey: - return (object as LayoutComponentStyleBase).animationStyleType; - case LayoutComponentStyleBase.interpolationTypePropertyKey: - return (object as LayoutComponentStyleBase).interpolationType; - case LayoutComponentStyleBase.interpolatorIdPropertyKey: - return (object as LayoutComponentStyleBase).interpolatorId; - case LayoutComponentStyleBase.displayValuePropertyKey: - return (object as LayoutComponentStyleBase).displayValue; - case LayoutComponentStyleBase.positionTypeValuePropertyKey: - return (object as LayoutComponentStyleBase).positionTypeValue; - case LayoutComponentStyleBase.flexDirectionValuePropertyKey: - return (object as LayoutComponentStyleBase).flexDirectionValue; - case LayoutComponentStyleBase.directionValuePropertyKey: - return (object as LayoutComponentStyleBase).directionValue; - case LayoutComponentStyleBase.alignContentValuePropertyKey: - return (object as LayoutComponentStyleBase).alignContentValue; - case LayoutComponentStyleBase.alignItemsValuePropertyKey: - return (object as LayoutComponentStyleBase).alignItemsValue; - case LayoutComponentStyleBase.alignSelfValuePropertyKey: - return (object as LayoutComponentStyleBase).alignSelfValue; - case LayoutComponentStyleBase.justifyContentValuePropertyKey: - return (object as LayoutComponentStyleBase).justifyContentValue; - case LayoutComponentStyleBase.flexWrapValuePropertyKey: - return (object as LayoutComponentStyleBase).flexWrapValue; - case LayoutComponentStyleBase.overflowValuePropertyKey: - return (object as LayoutComponentStyleBase).overflowValue; - case LayoutComponentStyleBase.widthUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).widthUnitsValue; - case LayoutComponentStyleBase.heightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).heightUnitsValue; - case LayoutComponentStyleBase.borderLeftUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).borderLeftUnitsValue; - case LayoutComponentStyleBase.borderRightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).borderRightUnitsValue; - case LayoutComponentStyleBase.borderTopUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).borderTopUnitsValue; - case LayoutComponentStyleBase.borderBottomUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).borderBottomUnitsValue; - case LayoutComponentStyleBase.marginLeftUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).marginLeftUnitsValue; - case LayoutComponentStyleBase.marginRightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).marginRightUnitsValue; - case LayoutComponentStyleBase.marginTopUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).marginTopUnitsValue; - case LayoutComponentStyleBase.marginBottomUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).marginBottomUnitsValue; - case LayoutComponentStyleBase.paddingLeftUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).paddingLeftUnitsValue; - case LayoutComponentStyleBase.paddingRightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).paddingRightUnitsValue; - case LayoutComponentStyleBase.paddingTopUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).paddingTopUnitsValue; - case LayoutComponentStyleBase.paddingBottomUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).paddingBottomUnitsValue; - case LayoutComponentStyleBase.positionLeftUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).positionLeftUnitsValue; - case LayoutComponentStyleBase.positionRightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).positionRightUnitsValue; - case LayoutComponentStyleBase.positionTopUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).positionTopUnitsValue; - case LayoutComponentStyleBase.positionBottomUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).positionBottomUnitsValue; - case LayoutComponentStyleBase.gapHorizontalUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).gapHorizontalUnitsValue; - case LayoutComponentStyleBase.gapVerticalUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).gapVerticalUnitsValue; - case LayoutComponentStyleBase.minWidthUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).minWidthUnitsValue; - case LayoutComponentStyleBase.minHeightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).minHeightUnitsValue; - case LayoutComponentStyleBase.maxWidthUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).maxWidthUnitsValue; - case LayoutComponentStyleBase.maxHeightUnitsValuePropertyKey: - return (object as LayoutComponentStyleBase).maxHeightUnitsValue; - case ListenerFireEventBase.eventIdPropertyKey: - return (object as ListenerFireEventBase).eventId; - case LayerStateBase.flagsPropertyKey: - return (object as LayerStateBase).flags; - case KeyFrameBase.framePropertyKey: - return (object as KeyFrameBase).frame; - case InterpolatingKeyFrameBase.interpolationTypePropertyKey: - return (object as InterpolatingKeyFrameBase).interpolationType; - case InterpolatingKeyFrameBase.interpolatorIdPropertyKey: - return (object as InterpolatingKeyFrameBase).interpolatorId; - case KeyFrameUintBase.valuePropertyKey: - return (object as KeyFrameUintBase).value; - case LinearAnimationBase.fpsPropertyKey: - return (object as LinearAnimationBase).fps; - case LinearAnimationBase.durationPropertyKey: - return (object as LinearAnimationBase).duration; - case LinearAnimationBase.loopValuePropertyKey: - return (object as LinearAnimationBase).loopValue; - case LinearAnimationBase.workStartPropertyKey: - return (object as LinearAnimationBase).workStart; - case LinearAnimationBase.workEndPropertyKey: - return (object as LinearAnimationBase).workEnd; - case ListenerInputChangeBase.inputIdPropertyKey: - return (object as ListenerInputChangeBase).inputId; - case ListenerInputChangeBase.nestedInputIdPropertyKey: - return (object as ListenerInputChangeBase).nestedInputId; - case AnimationStateBase.animationIdPropertyKey: - return (object as AnimationStateBase).animationId; - case NestedInputBase.inputIdPropertyKey: - return (object as NestedInputBase).inputId; - case KeyedObjectBase.objectIdPropertyKey: - return (object as KeyedObjectBase).objectId; - case BlendAnimationBase.animationIdPropertyKey: - return (object as BlendAnimationBase).animationId; - case BlendAnimationDirectBase.inputIdPropertyKey: - return (object as BlendAnimationDirectBase).inputId; - case BlendAnimationDirectBase.blendSourcePropertyKey: - return (object as BlendAnimationDirectBase).blendSource; - case TransitionInputConditionBase.inputIdPropertyKey: - return (object as TransitionInputConditionBase).inputId; - case KeyedPropertyBase.propertyKeyPropertyKey: - return (object as KeyedPropertyBase).propertyKey; - case StateMachineListenerBase.targetIdPropertyKey: - return (object as StateMachineListenerBase).targetId; - case StateMachineListenerBase.listenerTypeValuePropertyKey: - return (object as StateMachineListenerBase).listenerTypeValue; - case StateMachineListenerBase.eventIdPropertyKey: - return (object as StateMachineListenerBase).eventId; - case KeyFrameIdBase.valuePropertyKey: - return (object as KeyFrameIdBase).value; - case ListenerBoolChangeBase.valuePropertyKey: - return (object as ListenerBoolChangeBase).value; - case ListenerAlignTargetBase.targetIdPropertyKey: - return (object as ListenerAlignTargetBase).targetId; - case TransitionValueConditionBase.opValuePropertyKey: - return (object as TransitionValueConditionBase).opValue; - case TransitionViewModelConditionBase.leftComparatorIdPropertyKey: - return (object as TransitionViewModelConditionBase).leftComparatorId; - case TransitionViewModelConditionBase.rightComparatorIdPropertyKey: - return (object as TransitionViewModelConditionBase).rightComparatorId; - case TransitionViewModelConditionBase.opValuePropertyKey: - return (object as TransitionViewModelConditionBase).opValue; - case StateTransitionBase.stateToIdPropertyKey: - return (object as StateTransitionBase).stateToId; - case StateTransitionBase.flagsPropertyKey: - return (object as StateTransitionBase).flags; - case StateTransitionBase.durationPropertyKey: - return (object as StateTransitionBase).duration; - case StateTransitionBase.exitTimePropertyKey: - return (object as StateTransitionBase).exitTime; - case StateTransitionBase.interpolationTypePropertyKey: - return (object as StateTransitionBase).interpolationType; - case StateTransitionBase.interpolatorIdPropertyKey: - return (object as StateTransitionBase).interpolatorId; - case StateTransitionBase.randomWeightPropertyKey: - return (object as StateTransitionBase).randomWeight; - case StateMachineFireEventBase.eventIdPropertyKey: - return (object as StateMachineFireEventBase).eventId; - case StateMachineFireEventBase.occursValuePropertyKey: - return (object as StateMachineFireEventBase).occursValue; - case ElasticInterpolatorBase.easingValuePropertyKey: - return (object as ElasticInterpolatorBase).easingValue; - case BlendState1DBase.inputIdPropertyKey: - return (object as BlendState1DBase).inputId; - case TransitionValueEnumComparatorBase.valuePropertyKey: - return (object as TransitionValueEnumComparatorBase).value; - case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey: - return (object as BlendStateTransitionBase).exitBlendAnimationId; - case StrokeBase.capPropertyKey: - return (object as StrokeBase).cap; - case StrokeBase.joinPropertyKey: - return (object as StrokeBase).join; - case TrimPathBase.modeValuePropertyKey: - return (object as TrimPathBase).modeValue; - case FillBase.fillRulePropertyKey: - return (object as FillBase).fillRule; - case PathBase.pathFlagsPropertyKey: - return (object as PathBase).pathFlags; - case WeightBase.valuesPropertyKey: - return (object as WeightBase).values; - case WeightBase.indicesPropertyKey: - return (object as WeightBase).indices; - case CubicWeightBase.inValuesPropertyKey: - return (object as CubicWeightBase).inValues; - case CubicWeightBase.inIndicesPropertyKey: - return (object as CubicWeightBase).inIndices; - case CubicWeightBase.outValuesPropertyKey: - return (object as CubicWeightBase).outValues; - case CubicWeightBase.outIndicesPropertyKey: - return (object as CubicWeightBase).outIndices; - case ClippingShapeBase.sourceIdPropertyKey: - return (object as ClippingShapeBase).sourceId; - case ClippingShapeBase.fillRulePropertyKey: - return (object as ClippingShapeBase).fillRule; - case PolygonBase.pointsPropertyKey: - return (object as PolygonBase).points; - case ImageBase.assetIdPropertyKey: - return (object as ImageBase).assetId; - case DrawRulesBase.drawTargetIdPropertyKey: - return (object as DrawRulesBase).drawTargetId; - case LayoutComponentBase.styleIdPropertyKey: - return (object as LayoutComponentBase).styleId; - case ArtboardBase.defaultStateMachineIdPropertyKey: - return (object as ArtboardBase).defaultStateMachineId; - case ArtboardBase.viewModelIdPropertyKey: - return (object as ArtboardBase).viewModelId; - case JoystickBase.xIdPropertyKey: - return (object as JoystickBase).xId; - case JoystickBase.yIdPropertyKey: - return (object as JoystickBase).yId; - case JoystickBase.joystickFlagsPropertyKey: - return (object as JoystickBase).joystickFlags; - case JoystickBase.handleSourceIdPropertyKey: - return (object as JoystickBase).handleSourceId; - case OpenUrlEventBase.targetValuePropertyKey: - return (object as OpenUrlEventBase).targetValue; - case DataBindBase.propertyKeyPropertyKey: - return (object as DataBindBase).propertyKey; - case DataBindBase.flagsPropertyKey: - return (object as DataBindBase).flags; - case DataBindBase.converterIdPropertyKey: - return (object as DataBindBase).converterId; - case BindablePropertyEnumBase.propertyValuePropertyKey: - return (object as BindablePropertyEnumBase).propertyValue; - case TendonBase.boneIdPropertyKey: - return (object as TendonBase).boneId; - case TextModifierRangeBase.unitsValuePropertyKey: - return (object as TextModifierRangeBase).unitsValue; - case TextModifierRangeBase.typeValuePropertyKey: - return (object as TextModifierRangeBase).typeValue; - case TextModifierRangeBase.modeValuePropertyKey: - return (object as TextModifierRangeBase).modeValue; - case TextModifierRangeBase.runIdPropertyKey: - return (object as TextModifierRangeBase).runId; - case TextStyleFeatureBase.tagPropertyKey: - return (object as TextStyleFeatureBase).tag; - case TextStyleFeatureBase.featureValuePropertyKey: - return (object as TextStyleFeatureBase).featureValue; - case TextVariationModifierBase.axisTagPropertyKey: - return (object as TextVariationModifierBase).axisTag; - case TextModifierGroupBase.modifierFlagsPropertyKey: - return (object as TextModifierGroupBase).modifierFlags; - case TextStyleBase.fontAssetIdPropertyKey: - return (object as TextStyleBase).fontAssetId; - case TextStyleAxisBase.tagPropertyKey: - return (object as TextStyleAxisBase).tag; - case TextBase.alignValuePropertyKey: - return (object as TextBase).alignValue; - case TextBase.sizingValuePropertyKey: - return (object as TextBase).sizingValue; - case TextBase.overflowValuePropertyKey: - return (object as TextBase).overflowValue; - case TextBase.originValuePropertyKey: - return (object as TextBase).originValue; - case TextBase.wrapValuePropertyKey: - return (object as TextBase).wrapValue; - case TextBase.verticalAlignValuePropertyKey: - return (object as TextBase).verticalAlignValue; - case TextValueRunBase.styleIdPropertyKey: - return (object as TextValueRunBase).styleId; - case FileAssetBase.assetIdPropertyKey: - return (object as FileAssetBase).assetId; - case AudioEventBase.assetIdPropertyKey: - return (object as AudioEventBase).assetId; - } - return 0; - } - - static int getColor(Core object, int propertyKey) { - switch (propertyKey) { - case ViewModelInstanceColorBase.propertyValuePropertyKey: - return (object as ViewModelInstanceColorBase).propertyValue; - case KeyFrameColorBase.valuePropertyKey: - return (object as KeyFrameColorBase).value; - case TransitionValueColorComparatorBase.valuePropertyKey: - return (object as TransitionValueColorComparatorBase).value; - case SolidColorBase.colorValuePropertyKey: - return (object as SolidColorBase).colorValue; - case GradientStopBase.colorValuePropertyKey: - return (object as GradientStopBase).colorValue; - case BindablePropertyColorBase.propertyValuePropertyKey: - return (object as BindablePropertyColorBase).propertyValue; - } - return 0; - } - - static String getString(Core object, int propertyKey) { - switch (propertyKey) { - case ViewModelComponentBase.namePropertyKey: - return (object as ViewModelComponentBase).name; - case ViewModelInstanceStringBase.propertyValuePropertyKey: - return (object as ViewModelInstanceStringBase).propertyValue; - case ComponentBase.namePropertyKey: - return (object as ComponentBase).name; - case DataEnumValueBase.keyPropertyKey: - return (object as DataEnumValueBase).key; - case DataEnumValueBase.valuePropertyKey: - return (object as DataEnumValueBase).value; - case AnimationBase.namePropertyKey: - return (object as AnimationBase).name; - case StateMachineComponentBase.namePropertyKey: - return (object as StateMachineComponentBase).name; - case KeyFrameStringBase.valuePropertyKey: - return (object as KeyFrameStringBase).value; - case TransitionValueStringComparatorBase.valuePropertyKey: - return (object as TransitionValueStringComparatorBase).value; - case OpenUrlEventBase.urlPropertyKey: - return (object as OpenUrlEventBase).url; - case DataConverterBase.namePropertyKey: - return (object as DataConverterBase).name; - case BindablePropertyStringBase.propertyValuePropertyKey: - return (object as BindablePropertyStringBase).propertyValue; - case TextValueRunBase.textPropertyKey: - return (object as TextValueRunBase).text; - case CustomPropertyStringBase.propertyValuePropertyKey: - return (object as CustomPropertyStringBase).propertyValue; - case AssetBase.namePropertyKey: - return (object as AssetBase).name; - case FileAssetBase.cdnBaseUrlPropertyKey: - return (object as FileAssetBase).cdnBaseUrl; - } - return ''; - } - - static double getDouble(Core object, int propertyKey) { - switch (propertyKey) { - case ViewModelInstanceNumberBase.propertyValuePropertyKey: - return (object as ViewModelInstanceNumberBase).propertyValue; - case CustomPropertyNumberBase.propertyValuePropertyKey: - return (object as CustomPropertyNumberBase).propertyValue; - case ConstraintBase.strengthPropertyKey: - return (object as ConstraintBase).strength; - case DistanceConstraintBase.distancePropertyKey: - return (object as DistanceConstraintBase).distance; - case TransformComponentConstraintBase.copyFactorPropertyKey: - return (object as TransformComponentConstraintBase).copyFactor; - case TransformComponentConstraintBase.minValuePropertyKey: - return (object as TransformComponentConstraintBase).minValue; - case TransformComponentConstraintBase.maxValuePropertyKey: - return (object as TransformComponentConstraintBase).maxValue; - case TransformComponentConstraintYBase.copyFactorYPropertyKey: - return (object as TransformComponentConstraintYBase).copyFactorY; - case TransformComponentConstraintYBase.minValueYPropertyKey: - return (object as TransformComponentConstraintYBase).minValueY; - case TransformComponentConstraintYBase.maxValueYPropertyKey: - return (object as TransformComponentConstraintYBase).maxValueY; - case FollowPathConstraintBase.distancePropertyKey: - return (object as FollowPathConstraintBase).distance; - case TransformConstraintBase.originXPropertyKey: - return (object as TransformConstraintBase).originX; - case TransformConstraintBase.originYPropertyKey: - return (object as TransformConstraintBase).originY; - case WorldTransformComponentBase.opacityPropertyKey: - return (object as WorldTransformComponentBase).opacity; - case TransformComponentBase.rotationPropertyKey: - return (object as TransformComponentBase).rotation; - case TransformComponentBase.scaleXPropertyKey: - return (object as TransformComponentBase).scaleX; - case TransformComponentBase.scaleYPropertyKey: - return (object as TransformComponentBase).scaleY; - case NodeBase.xPropertyKey: - return (object as NodeBase).x; - case NodeBase.yPropertyKey: - return (object as NodeBase).y; - case LayoutComponentStyleBase.gapHorizontalPropertyKey: - return (object as LayoutComponentStyleBase).gapHorizontal; - case LayoutComponentStyleBase.gapVerticalPropertyKey: - return (object as LayoutComponentStyleBase).gapVertical; - case LayoutComponentStyleBase.maxWidthPropertyKey: - return (object as LayoutComponentStyleBase).maxWidth; - case LayoutComponentStyleBase.maxHeightPropertyKey: - return (object as LayoutComponentStyleBase).maxHeight; - case LayoutComponentStyleBase.minWidthPropertyKey: - return (object as LayoutComponentStyleBase).minWidth; - case LayoutComponentStyleBase.minHeightPropertyKey: - return (object as LayoutComponentStyleBase).minHeight; - case LayoutComponentStyleBase.borderLeftPropertyKey: - return (object as LayoutComponentStyleBase).borderLeft; - case LayoutComponentStyleBase.borderRightPropertyKey: - return (object as LayoutComponentStyleBase).borderRight; - case LayoutComponentStyleBase.borderTopPropertyKey: - return (object as LayoutComponentStyleBase).borderTop; - case LayoutComponentStyleBase.borderBottomPropertyKey: - return (object as LayoutComponentStyleBase).borderBottom; - case LayoutComponentStyleBase.marginLeftPropertyKey: - return (object as LayoutComponentStyleBase).marginLeft; - case LayoutComponentStyleBase.marginRightPropertyKey: - return (object as LayoutComponentStyleBase).marginRight; - case LayoutComponentStyleBase.marginTopPropertyKey: - return (object as LayoutComponentStyleBase).marginTop; - case LayoutComponentStyleBase.marginBottomPropertyKey: - return (object as LayoutComponentStyleBase).marginBottom; - case LayoutComponentStyleBase.paddingLeftPropertyKey: - return (object as LayoutComponentStyleBase).paddingLeft; - case LayoutComponentStyleBase.paddingRightPropertyKey: - return (object as LayoutComponentStyleBase).paddingRight; - case LayoutComponentStyleBase.paddingTopPropertyKey: - return (object as LayoutComponentStyleBase).paddingTop; - case LayoutComponentStyleBase.paddingBottomPropertyKey: - return (object as LayoutComponentStyleBase).paddingBottom; - case LayoutComponentStyleBase.positionLeftPropertyKey: - return (object as LayoutComponentStyleBase).positionLeft; - case LayoutComponentStyleBase.positionRightPropertyKey: - return (object as LayoutComponentStyleBase).positionRight; - case LayoutComponentStyleBase.positionTopPropertyKey: - return (object as LayoutComponentStyleBase).positionTop; - case LayoutComponentStyleBase.positionBottomPropertyKey: - return (object as LayoutComponentStyleBase).positionBottom; - case LayoutComponentStyleBase.flexPropertyKey: - return (object as LayoutComponentStyleBase).flex; - case LayoutComponentStyleBase.flexGrowPropertyKey: - return (object as LayoutComponentStyleBase).flexGrow; - case LayoutComponentStyleBase.flexShrinkPropertyKey: - return (object as LayoutComponentStyleBase).flexShrink; - case LayoutComponentStyleBase.flexBasisPropertyKey: - return (object as LayoutComponentStyleBase).flexBasis; - case LayoutComponentStyleBase.aspectRatioPropertyKey: - return (object as LayoutComponentStyleBase).aspectRatio; - case LayoutComponentStyleBase.interpolationTimePropertyKey: - return (object as LayoutComponentStyleBase).interpolationTime; - case LinearAnimationBase.speedPropertyKey: - return (object as LinearAnimationBase).speed; - case NestedLinearAnimationBase.mixPropertyKey: - return (object as NestedLinearAnimationBase).mix; - case NestedSimpleAnimationBase.speedPropertyKey: - return (object as NestedSimpleAnimationBase).speed; - case AdvanceableStateBase.speedPropertyKey: - return (object as AdvanceableStateBase).speed; - case BlendAnimationDirectBase.mixValuePropertyKey: - return (object as BlendAnimationDirectBase).mixValue; - case StateMachineNumberBase.valuePropertyKey: - return (object as StateMachineNumberBase).value; - case CubicInterpolatorBase.x1PropertyKey: - return (object as CubicInterpolatorBase).x1; - case CubicInterpolatorBase.y1PropertyKey: - return (object as CubicInterpolatorBase).y1; - case CubicInterpolatorBase.x2PropertyKey: - return (object as CubicInterpolatorBase).x2; - case CubicInterpolatorBase.y2PropertyKey: - return (object as CubicInterpolatorBase).y2; - case TransitionNumberConditionBase.valuePropertyKey: - return (object as TransitionNumberConditionBase).value; - case CubicInterpolatorComponentBase.x1PropertyKey: - return (object as CubicInterpolatorComponentBase).x1; - case CubicInterpolatorComponentBase.y1PropertyKey: - return (object as CubicInterpolatorComponentBase).y1; - case CubicInterpolatorComponentBase.x2PropertyKey: - return (object as CubicInterpolatorComponentBase).x2; - case CubicInterpolatorComponentBase.y2PropertyKey: - return (object as CubicInterpolatorComponentBase).y2; - case ListenerNumberChangeBase.valuePropertyKey: - return (object as ListenerNumberChangeBase).value; - case KeyFrameDoubleBase.valuePropertyKey: - return (object as KeyFrameDoubleBase).value; - case TransitionValueNumberComparatorBase.valuePropertyKey: - return (object as TransitionValueNumberComparatorBase).value; - case ElasticInterpolatorBase.amplitudePropertyKey: - return (object as ElasticInterpolatorBase).amplitude; - case ElasticInterpolatorBase.periodPropertyKey: - return (object as ElasticInterpolatorBase).period; - case NestedNumberBase.nestedValuePropertyKey: - return (object as NestedNumberBase).nestedValue; - case BlendAnimation1DBase.valuePropertyKey: - return (object as BlendAnimation1DBase).value; - case NestedRemapAnimationBase.timePropertyKey: - return (object as NestedRemapAnimationBase).time; - case LinearGradientBase.startXPropertyKey: - return (object as LinearGradientBase).startX; - case LinearGradientBase.startYPropertyKey: - return (object as LinearGradientBase).startY; - case LinearGradientBase.endXPropertyKey: - return (object as LinearGradientBase).endX; - case LinearGradientBase.endYPropertyKey: - return (object as LinearGradientBase).endY; - case LinearGradientBase.opacityPropertyKey: - return (object as LinearGradientBase).opacity; - case StrokeBase.thicknessPropertyKey: - return (object as StrokeBase).thickness; - case GradientStopBase.positionPropertyKey: - return (object as GradientStopBase).position; - case TrimPathBase.startPropertyKey: - return (object as TrimPathBase).start; - case TrimPathBase.endPropertyKey: - return (object as TrimPathBase).end; - case TrimPathBase.offsetPropertyKey: - return (object as TrimPathBase).offset; - case VertexBase.xPropertyKey: - return (object as VertexBase).x; - case VertexBase.yPropertyKey: - return (object as VertexBase).y; - case MeshVertexBase.uPropertyKey: - return (object as MeshVertexBase).u; - case MeshVertexBase.vPropertyKey: - return (object as MeshVertexBase).v; - case StraightVertexBase.radiusPropertyKey: - return (object as StraightVertexBase).radius; - case CubicAsymmetricVertexBase.rotationPropertyKey: - return (object as CubicAsymmetricVertexBase).rotation; - case CubicAsymmetricVertexBase.inDistancePropertyKey: - return (object as CubicAsymmetricVertexBase).inDistance; - case CubicAsymmetricVertexBase.outDistancePropertyKey: - return (object as CubicAsymmetricVertexBase).outDistance; - case ParametricPathBase.widthPropertyKey: - return (object as ParametricPathBase).width; - case ParametricPathBase.heightPropertyKey: - return (object as ParametricPathBase).height; - case ParametricPathBase.originXPropertyKey: - return (object as ParametricPathBase).originX; - case ParametricPathBase.originYPropertyKey: - return (object as ParametricPathBase).originY; - case RectangleBase.cornerRadiusTLPropertyKey: - return (object as RectangleBase).cornerRadiusTL; - case RectangleBase.cornerRadiusTRPropertyKey: - return (object as RectangleBase).cornerRadiusTR; - case RectangleBase.cornerRadiusBLPropertyKey: - return (object as RectangleBase).cornerRadiusBL; - case RectangleBase.cornerRadiusBRPropertyKey: - return (object as RectangleBase).cornerRadiusBR; - case CubicMirroredVertexBase.rotationPropertyKey: - return (object as CubicMirroredVertexBase).rotation; - case CubicMirroredVertexBase.distancePropertyKey: - return (object as CubicMirroredVertexBase).distance; - case PolygonBase.cornerRadiusPropertyKey: - return (object as PolygonBase).cornerRadius; - case StarBase.innerRadiusPropertyKey: - return (object as StarBase).innerRadius; - case ImageBase.originXPropertyKey: - return (object as ImageBase).originX; - case ImageBase.originYPropertyKey: - return (object as ImageBase).originY; - case CubicDetachedVertexBase.inRotationPropertyKey: - return (object as CubicDetachedVertexBase).inRotation; - case CubicDetachedVertexBase.inDistancePropertyKey: - return (object as CubicDetachedVertexBase).inDistance; - case CubicDetachedVertexBase.outRotationPropertyKey: - return (object as CubicDetachedVertexBase).outRotation; - case CubicDetachedVertexBase.outDistancePropertyKey: - return (object as CubicDetachedVertexBase).outDistance; - case LayoutComponentBase.widthPropertyKey: - return (object as LayoutComponentBase).width; - case LayoutComponentBase.heightPropertyKey: - return (object as LayoutComponentBase).height; - case ArtboardBase.xPropertyKey: - return (object as ArtboardBase).x; - case ArtboardBase.yPropertyKey: - return (object as ArtboardBase).y; - case ArtboardBase.originXPropertyKey: - return (object as ArtboardBase).originX; - case ArtboardBase.originYPropertyKey: - return (object as ArtboardBase).originY; - case JoystickBase.xPropertyKey: - return (object as JoystickBase).x; - case JoystickBase.yPropertyKey: - return (object as JoystickBase).y; - case JoystickBase.posXPropertyKey: - return (object as JoystickBase).posX; - case JoystickBase.posYPropertyKey: - return (object as JoystickBase).posY; - case JoystickBase.originXPropertyKey: - return (object as JoystickBase).originX; - case JoystickBase.originYPropertyKey: - return (object as JoystickBase).originY; - case JoystickBase.widthPropertyKey: - return (object as JoystickBase).width; - case JoystickBase.heightPropertyKey: - return (object as JoystickBase).height; - case BindablePropertyNumberBase.propertyValuePropertyKey: - return (object as BindablePropertyNumberBase).propertyValue; - case BoneBase.lengthPropertyKey: - return (object as BoneBase).length; - case RootBoneBase.xPropertyKey: - return (object as RootBoneBase).x; - case RootBoneBase.yPropertyKey: - return (object as RootBoneBase).y; - case SkinBase.xxPropertyKey: - return (object as SkinBase).xx; - case SkinBase.yxPropertyKey: - return (object as SkinBase).yx; - case SkinBase.xyPropertyKey: - return (object as SkinBase).xy; - case SkinBase.yyPropertyKey: - return (object as SkinBase).yy; - case SkinBase.txPropertyKey: - return (object as SkinBase).tx; - case SkinBase.tyPropertyKey: - return (object as SkinBase).ty; - case TendonBase.xxPropertyKey: - return (object as TendonBase).xx; - case TendonBase.yxPropertyKey: - return (object as TendonBase).yx; - case TendonBase.xyPropertyKey: - return (object as TendonBase).xy; - case TendonBase.yyPropertyKey: - return (object as TendonBase).yy; - case TendonBase.txPropertyKey: - return (object as TendonBase).tx; - case TendonBase.tyPropertyKey: - return (object as TendonBase).ty; - case TextModifierRangeBase.modifyFromPropertyKey: - return (object as TextModifierRangeBase).modifyFrom; - case TextModifierRangeBase.modifyToPropertyKey: - return (object as TextModifierRangeBase).modifyTo; - case TextModifierRangeBase.strengthPropertyKey: - return (object as TextModifierRangeBase).strength; - case TextModifierRangeBase.falloffFromPropertyKey: - return (object as TextModifierRangeBase).falloffFrom; - case TextModifierRangeBase.falloffToPropertyKey: - return (object as TextModifierRangeBase).falloffTo; - case TextModifierRangeBase.offsetPropertyKey: - return (object as TextModifierRangeBase).offset; - case TextVariationModifierBase.axisValuePropertyKey: - return (object as TextVariationModifierBase).axisValue; - case TextModifierGroupBase.originXPropertyKey: - return (object as TextModifierGroupBase).originX; - case TextModifierGroupBase.originYPropertyKey: - return (object as TextModifierGroupBase).originY; - case TextModifierGroupBase.opacityPropertyKey: - return (object as TextModifierGroupBase).opacity; - case TextModifierGroupBase.xPropertyKey: - return (object as TextModifierGroupBase).x; - case TextModifierGroupBase.yPropertyKey: - return (object as TextModifierGroupBase).y; - case TextModifierGroupBase.rotationPropertyKey: - return (object as TextModifierGroupBase).rotation; - case TextModifierGroupBase.scaleXPropertyKey: - return (object as TextModifierGroupBase).scaleX; - case TextModifierGroupBase.scaleYPropertyKey: - return (object as TextModifierGroupBase).scaleY; - case TextStyleBase.fontSizePropertyKey: - return (object as TextStyleBase).fontSize; - case TextStyleBase.lineHeightPropertyKey: - return (object as TextStyleBase).lineHeight; - case TextStyleBase.letterSpacingPropertyKey: - return (object as TextStyleBase).letterSpacing; - case TextStyleAxisBase.axisValuePropertyKey: - return (object as TextStyleAxisBase).axisValue; - case TextBase.widthPropertyKey: - return (object as TextBase).width; - case TextBase.heightPropertyKey: - return (object as TextBase).height; - case TextBase.originXPropertyKey: - return (object as TextBase).originX; - case TextBase.originYPropertyKey: - return (object as TextBase).originY; - case TextBase.paragraphSpacingPropertyKey: - return (object as TextBase).paragraphSpacing; - case ExportAudioBase.volumePropertyKey: - return (object as ExportAudioBase).volume; - case DrawableAssetBase.heightPropertyKey: - return (object as DrawableAssetBase).height; - case DrawableAssetBase.widthPropertyKey: - return (object as DrawableAssetBase).width; - } - return 0.0; - } - - static Uint8List getBytes(Core object, int propertyKey) { - switch (propertyKey) { - case NestedArtboardBase.dataBindPathIdsPropertyKey: - return (object as NestedArtboardBase).dataBindPathIds; - case MeshBase.triangleIndexBytesPropertyKey: - return (object as MeshBase).triangleIndexBytes; - case DataBindContextBase.sourcePathIdsPropertyKey: - return (object as DataBindContextBase).sourcePathIds; - case FileAssetBase.cdnUuidPropertyKey: - return (object as FileAssetBase).cdnUuid; - case FileAssetContentsBase.bytesPropertyKey: - return (object as FileAssetContentsBase).bytes; - } - return Uint8List(0); - } - - static void setBool(Core object, int propertyKey, bool value) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.useLinkedArtboardPropertyKey: - if (object is ViewModelInstanceListItemBase) { - object.useLinkedArtboard = value; - } - break; - case ViewModelInstanceBooleanBase.propertyValuePropertyKey: - if (object is ViewModelInstanceBooleanBase) { - object.propertyValue = value; - } - break; - case TransformComponentConstraintBase.offsetPropertyKey: - if (object is TransformComponentConstraintBase) { - object.offset = value; - } - break; - case TransformComponentConstraintBase.doesCopyPropertyKey: - if (object is TransformComponentConstraintBase) { - object.doesCopy = value; - } - break; - case TransformComponentConstraintBase.minPropertyKey: - if (object is TransformComponentConstraintBase) { - object.min = value; - } - break; - case TransformComponentConstraintBase.maxPropertyKey: - if (object is TransformComponentConstraintBase) { - object.max = value; - } - break; - case TransformComponentConstraintYBase.doesCopyYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.doesCopyY = value; - } - break; - case TransformComponentConstraintYBase.minYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.minY = value; - } - break; - case TransformComponentConstraintYBase.maxYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.maxY = value; - } - break; - case IKConstraintBase.invertDirectionPropertyKey: - if (object is IKConstraintBase) { - object.invertDirection = value; - } - break; - case FollowPathConstraintBase.orientPropertyKey: - if (object is FollowPathConstraintBase) { - object.orient = value; - } - break; - case FollowPathConstraintBase.offsetPropertyKey: - if (object is FollowPathConstraintBase) { - object.offset = value; - } - break; - case LayoutComponentStyleBase.intrinsicallySizedValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.intrinsicallySizedValue = value; - } - break; - case LinearAnimationBase.enableWorkAreaPropertyKey: - if (object is LinearAnimationBase) { - object.enableWorkArea = value; - } - break; - case LinearAnimationBase.quantizePropertyKey: - if (object is LinearAnimationBase) { - object.quantize = value; - } - break; - case NestedSimpleAnimationBase.isPlayingPropertyKey: - if (object is NestedSimpleAnimationBase) { - object.isPlaying = value; - } - break; - case KeyFrameBoolBase.valuePropertyKey: - if (object is KeyFrameBoolBase) { - object.value = value; - } - break; - case ListenerAlignTargetBase.preserveOffsetPropertyKey: - if (object is ListenerAlignTargetBase) { - object.preserveOffset = value; - } - break; - case TransitionValueBooleanComparatorBase.valuePropertyKey: - if (object is TransitionValueBooleanComparatorBase) { - object.value = value; - } - break; - case NestedBoolBase.nestedValuePropertyKey: - if (object is NestedBoolBase) { - object.nestedValue = value; - } - break; - case StateMachineBoolBase.valuePropertyKey: - if (object is StateMachineBoolBase) { - object.value = value; - } - break; - case ShapePaintBase.isVisiblePropertyKey: - if (object is ShapePaintBase) { - object.isVisible = value; - } - break; - case StrokeBase.transformAffectsStrokePropertyKey: - if (object is StrokeBase) { - object.transformAffectsStroke = value; - } - break; - case PointsPathBase.isClosedPropertyKey: - if (object is PointsPathBase) { - object.isClosed = value; - } - break; - case RectangleBase.linkCornerRadiusPropertyKey: - if (object is RectangleBase) { - object.linkCornerRadius = value; - } - break; - case ClippingShapeBase.isVisiblePropertyKey: - if (object is ClippingShapeBase) { - object.isVisible = value; - } - break; - case CustomPropertyBooleanBase.propertyValuePropertyKey: - if (object is CustomPropertyBooleanBase) { - object.propertyValue = value; - } - break; - case LayoutComponentBase.clipPropertyKey: - if (object is LayoutComponentBase) { - object.clip = value; - } - break; - case BindablePropertyBooleanBase.propertyValuePropertyKey: - if (object is BindablePropertyBooleanBase) { - object.propertyValue = value; - } - break; - case TextModifierRangeBase.clampPropertyKey: - if (object is TextModifierRangeBase) { - object.clamp = value; - } - break; - case TextBase.fitFromBaselinePropertyKey: - if (object is TextBase) { - object.fitFromBaseline = value; - } - break; - } - } - - static void setUint(Core object, int propertyKey, int value) { - switch (propertyKey) { - case ViewModelInstanceListItemBase.viewModelIdPropertyKey: - if (object is ViewModelInstanceListItemBase) { - object.viewModelId = value; - } - break; - case ViewModelInstanceListItemBase.viewModelInstanceIdPropertyKey: - if (object is ViewModelInstanceListItemBase) { - object.viewModelInstanceId = value; - } - break; - case ViewModelInstanceListItemBase.artboardIdPropertyKey: - if (object is ViewModelInstanceListItemBase) { - object.artboardId = value; - } - break; - case ViewModelInstanceValueBase.viewModelPropertyIdPropertyKey: - if (object is ViewModelInstanceValueBase) { - object.viewModelPropertyId = value; - } - break; - case ViewModelInstanceEnumBase.propertyValuePropertyKey: - if (object is ViewModelInstanceEnumBase) { - object.propertyValue = value; - } - break; - case ViewModelBase.defaultInstanceIdPropertyKey: - if (object is ViewModelBase) { - object.defaultInstanceId = value; - } - break; - case ViewModelPropertyViewModelBase.viewModelReferenceIdPropertyKey: - if (object is ViewModelPropertyViewModelBase) { - object.viewModelReferenceId = value; - } - break; - case ComponentBase.parentIdPropertyKey: - if (object is ComponentBase) { - object.parentId = value; - } - break; - case ViewModelInstanceBase.viewModelIdPropertyKey: - if (object is ViewModelInstanceBase) { - object.viewModelId = value; - } - break; - case ViewModelPropertyEnumBase.enumIdPropertyKey: - if (object is ViewModelPropertyEnumBase) { - object.enumId = value; - } - break; - case ViewModelInstanceViewModelBase.propertyValuePropertyKey: - if (object is ViewModelInstanceViewModelBase) { - object.propertyValue = value; - } - break; - case DrawTargetBase.drawableIdPropertyKey: - if (object is DrawTargetBase) { - object.drawableId = value; - } - break; - case DrawTargetBase.placementValuePropertyKey: - if (object is DrawTargetBase) { - object.placementValue = value; - } - break; - case TargetedConstraintBase.targetIdPropertyKey: - if (object is TargetedConstraintBase) { - object.targetId = value; - } - break; - case DistanceConstraintBase.modeValuePropertyKey: - if (object is DistanceConstraintBase) { - object.modeValue = value; - } - break; - case TransformSpaceConstraintBase.sourceSpaceValuePropertyKey: - if (object is TransformSpaceConstraintBase) { - object.sourceSpaceValue = value; - } - break; - case TransformSpaceConstraintBase.destSpaceValuePropertyKey: - if (object is TransformSpaceConstraintBase) { - object.destSpaceValue = value; - } - break; - case TransformComponentConstraintBase.minMaxSpaceValuePropertyKey: - if (object is TransformComponentConstraintBase) { - object.minMaxSpaceValue = value; - } - break; - case IKConstraintBase.parentBoneCountPropertyKey: - if (object is IKConstraintBase) { - object.parentBoneCount = value; - } - break; - case DrawableBase.blendModeValuePropertyKey: - if (object is DrawableBase) { - object.blendModeValue = value; - } - break; - case DrawableBase.drawableFlagsPropertyKey: - if (object is DrawableBase) { - object.drawableFlags = value; - } - break; - case NestedArtboardBase.artboardIdPropertyKey: - if (object is NestedArtboardBase) { - object.artboardId = value; - } - break; - case NestedArtboardBase.fitPropertyKey: - if (object is NestedArtboardBase) { - object.fit = value; - } - break; - case NestedArtboardBase.alignmentPropertyKey: - if (object is NestedArtboardBase) { - object.alignment = value; - } - break; - case NestedAnimationBase.animationIdPropertyKey: - if (object is NestedAnimationBase) { - object.animationId = value; - } - break; - case SoloBase.activeComponentIdPropertyKey: - if (object is SoloBase) { - object.activeComponentId = value; - } - break; - case LayoutComponentStyleBase.scaleTypePropertyKey: - if (object is LayoutComponentStyleBase) { - object.scaleType = value; - } - break; - case LayoutComponentStyleBase.layoutAlignmentTypePropertyKey: - if (object is LayoutComponentStyleBase) { - object.layoutAlignmentType = value; - } - break; - case LayoutComponentStyleBase.animationStyleTypePropertyKey: - if (object is LayoutComponentStyleBase) { - object.animationStyleType = value; - } - break; - case LayoutComponentStyleBase.interpolationTypePropertyKey: - if (object is LayoutComponentStyleBase) { - object.interpolationType = value; - } - break; - case LayoutComponentStyleBase.interpolatorIdPropertyKey: - if (object is LayoutComponentStyleBase) { - object.interpolatorId = value; - } - break; - case LayoutComponentStyleBase.displayValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.displayValue = value; - } - break; - case LayoutComponentStyleBase.positionTypeValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionTypeValue = value; - } - break; - case LayoutComponentStyleBase.flexDirectionValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.flexDirectionValue = value; - } - break; - case LayoutComponentStyleBase.directionValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.directionValue = value; - } - break; - case LayoutComponentStyleBase.alignContentValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.alignContentValue = value; - } - break; - case LayoutComponentStyleBase.alignItemsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.alignItemsValue = value; - } - break; - case LayoutComponentStyleBase.alignSelfValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.alignSelfValue = value; - } - break; - case LayoutComponentStyleBase.justifyContentValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.justifyContentValue = value; - } - break; - case LayoutComponentStyleBase.flexWrapValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.flexWrapValue = value; - } - break; - case LayoutComponentStyleBase.overflowValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.overflowValue = value; - } - break; - case LayoutComponentStyleBase.widthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.widthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.heightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.heightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.borderBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.marginBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.paddingBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionLeftUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionLeftUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionRightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionRightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionTopUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionTopUnitsValue = value; - } - break; - case LayoutComponentStyleBase.positionBottomUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionBottomUnitsValue = value; - } - break; - case LayoutComponentStyleBase.gapHorizontalUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.gapHorizontalUnitsValue = value; - } - break; - case LayoutComponentStyleBase.gapVerticalUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.gapVerticalUnitsValue = value; - } - break; - case LayoutComponentStyleBase.minWidthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.minWidthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.minHeightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.minHeightUnitsValue = value; - } - break; - case LayoutComponentStyleBase.maxWidthUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.maxWidthUnitsValue = value; - } - break; - case LayoutComponentStyleBase.maxHeightUnitsValuePropertyKey: - if (object is LayoutComponentStyleBase) { - object.maxHeightUnitsValue = value; - } - break; - case ListenerFireEventBase.eventIdPropertyKey: - if (object is ListenerFireEventBase) { - object.eventId = value; - } - break; - case LayerStateBase.flagsPropertyKey: - if (object is LayerStateBase) { - object.flags = value; - } - break; - case KeyFrameBase.framePropertyKey: - if (object is KeyFrameBase) { - object.frame = value; - } - break; - case InterpolatingKeyFrameBase.interpolationTypePropertyKey: - if (object is InterpolatingKeyFrameBase) { - object.interpolationType = value; - } - break; - case InterpolatingKeyFrameBase.interpolatorIdPropertyKey: - if (object is InterpolatingKeyFrameBase) { - object.interpolatorId = value; - } - break; - case KeyFrameUintBase.valuePropertyKey: - if (object is KeyFrameUintBase) { - object.value = value; - } - break; - case LinearAnimationBase.fpsPropertyKey: - if (object is LinearAnimationBase) { - object.fps = value; - } - break; - case LinearAnimationBase.durationPropertyKey: - if (object is LinearAnimationBase) { - object.duration = value; - } - break; - case LinearAnimationBase.loopValuePropertyKey: - if (object is LinearAnimationBase) { - object.loopValue = value; - } - break; - case LinearAnimationBase.workStartPropertyKey: - if (object is LinearAnimationBase) { - object.workStart = value; - } - break; - case LinearAnimationBase.workEndPropertyKey: - if (object is LinearAnimationBase) { - object.workEnd = value; - } - break; - case ListenerInputChangeBase.inputIdPropertyKey: - if (object is ListenerInputChangeBase) { - object.inputId = value; - } - break; - case ListenerInputChangeBase.nestedInputIdPropertyKey: - if (object is ListenerInputChangeBase) { - object.nestedInputId = value; - } - break; - case AnimationStateBase.animationIdPropertyKey: - if (object is AnimationStateBase) { - object.animationId = value; - } - break; - case NestedInputBase.inputIdPropertyKey: - if (object is NestedInputBase) { - object.inputId = value; - } - break; - case KeyedObjectBase.objectIdPropertyKey: - if (object is KeyedObjectBase) { - object.objectId = value; - } - break; - case BlendAnimationBase.animationIdPropertyKey: - if (object is BlendAnimationBase) { - object.animationId = value; - } - break; - case BlendAnimationDirectBase.inputIdPropertyKey: - if (object is BlendAnimationDirectBase) { - object.inputId = value; - } - break; - case BlendAnimationDirectBase.blendSourcePropertyKey: - if (object is BlendAnimationDirectBase) { - object.blendSource = value; - } - break; - case TransitionInputConditionBase.inputIdPropertyKey: - if (object is TransitionInputConditionBase) { - object.inputId = value; - } - break; - case KeyedPropertyBase.propertyKeyPropertyKey: - if (object is KeyedPropertyBase) { - object.propertyKey = value; - } - break; - case StateMachineListenerBase.targetIdPropertyKey: - if (object is StateMachineListenerBase) { - object.targetId = value; - } - break; - case StateMachineListenerBase.listenerTypeValuePropertyKey: - if (object is StateMachineListenerBase) { - object.listenerTypeValue = value; - } - break; - case StateMachineListenerBase.eventIdPropertyKey: - if (object is StateMachineListenerBase) { - object.eventId = value; - } - break; - case KeyFrameIdBase.valuePropertyKey: - if (object is KeyFrameIdBase) { - object.value = value; - } - break; - case ListenerBoolChangeBase.valuePropertyKey: - if (object is ListenerBoolChangeBase) { - object.value = value; - } - break; - case ListenerAlignTargetBase.targetIdPropertyKey: - if (object is ListenerAlignTargetBase) { - object.targetId = value; - } - break; - case TransitionValueConditionBase.opValuePropertyKey: - if (object is TransitionValueConditionBase) { - object.opValue = value; - } - break; - case TransitionViewModelConditionBase.leftComparatorIdPropertyKey: - if (object is TransitionViewModelConditionBase) { - object.leftComparatorId = value; - } - break; - case TransitionViewModelConditionBase.rightComparatorIdPropertyKey: - if (object is TransitionViewModelConditionBase) { - object.rightComparatorId = value; - } - break; - case TransitionViewModelConditionBase.opValuePropertyKey: - if (object is TransitionViewModelConditionBase) { - object.opValue = value; - } - break; - case StateTransitionBase.stateToIdPropertyKey: - if (object is StateTransitionBase) { - object.stateToId = value; - } - break; - case StateTransitionBase.flagsPropertyKey: - if (object is StateTransitionBase) { - object.flags = value; - } - break; - case StateTransitionBase.durationPropertyKey: - if (object is StateTransitionBase) { - object.duration = value; - } - break; - case StateTransitionBase.exitTimePropertyKey: - if (object is StateTransitionBase) { - object.exitTime = value; - } - break; - case StateTransitionBase.interpolationTypePropertyKey: - if (object is StateTransitionBase) { - object.interpolationType = value; - } - break; - case StateTransitionBase.interpolatorIdPropertyKey: - if (object is StateTransitionBase) { - object.interpolatorId = value; - } - break; - case StateTransitionBase.randomWeightPropertyKey: - if (object is StateTransitionBase) { - object.randomWeight = value; - } - break; - case StateMachineFireEventBase.eventIdPropertyKey: - if (object is StateMachineFireEventBase) { - object.eventId = value; - } - break; - case StateMachineFireEventBase.occursValuePropertyKey: - if (object is StateMachineFireEventBase) { - object.occursValue = value; - } - break; - case ElasticInterpolatorBase.easingValuePropertyKey: - if (object is ElasticInterpolatorBase) { - object.easingValue = value; - } - break; - case BlendState1DBase.inputIdPropertyKey: - if (object is BlendState1DBase) { - object.inputId = value; - } - break; - case TransitionValueEnumComparatorBase.valuePropertyKey: - if (object is TransitionValueEnumComparatorBase) { - object.value = value; - } - break; - case BlendStateTransitionBase.exitBlendAnimationIdPropertyKey: - if (object is BlendStateTransitionBase) { - object.exitBlendAnimationId = value; - } - break; - case StrokeBase.capPropertyKey: - if (object is StrokeBase) { - object.cap = value; - } - break; - case StrokeBase.joinPropertyKey: - if (object is StrokeBase) { - object.join = value; - } - break; - case TrimPathBase.modeValuePropertyKey: - if (object is TrimPathBase) { - object.modeValue = value; - } - break; - case FillBase.fillRulePropertyKey: - if (object is FillBase) { - object.fillRule = value; - } - break; - case PathBase.pathFlagsPropertyKey: - if (object is PathBase) { - object.pathFlags = value; - } - break; - case WeightBase.valuesPropertyKey: - if (object is WeightBase) { - object.values = value; - } - break; - case WeightBase.indicesPropertyKey: - if (object is WeightBase) { - object.indices = value; - } - break; - case CubicWeightBase.inValuesPropertyKey: - if (object is CubicWeightBase) { - object.inValues = value; - } - break; - case CubicWeightBase.inIndicesPropertyKey: - if (object is CubicWeightBase) { - object.inIndices = value; - } - break; - case CubicWeightBase.outValuesPropertyKey: - if (object is CubicWeightBase) { - object.outValues = value; - } - break; - case CubicWeightBase.outIndicesPropertyKey: - if (object is CubicWeightBase) { - object.outIndices = value; - } - break; - case ClippingShapeBase.sourceIdPropertyKey: - if (object is ClippingShapeBase) { - object.sourceId = value; - } - break; - case ClippingShapeBase.fillRulePropertyKey: - if (object is ClippingShapeBase) { - object.fillRule = value; - } - break; - case PolygonBase.pointsPropertyKey: - if (object is PolygonBase) { - object.points = value; - } - break; - case ImageBase.assetIdPropertyKey: - if (object is ImageBase) { - object.assetId = value; - } - break; - case DrawRulesBase.drawTargetIdPropertyKey: - if (object is DrawRulesBase) { - object.drawTargetId = value; - } - break; - case LayoutComponentBase.styleIdPropertyKey: - if (object is LayoutComponentBase) { - object.styleId = value; - } - break; - case ArtboardBase.defaultStateMachineIdPropertyKey: - if (object is ArtboardBase) { - object.defaultStateMachineId = value; - } - break; - case ArtboardBase.viewModelIdPropertyKey: - if (object is ArtboardBase) { - object.viewModelId = value; - } - break; - case JoystickBase.xIdPropertyKey: - if (object is JoystickBase) { - object.xId = value; - } - break; - case JoystickBase.yIdPropertyKey: - if (object is JoystickBase) { - object.yId = value; - } - break; - case JoystickBase.joystickFlagsPropertyKey: - if (object is JoystickBase) { - object.joystickFlags = value; - } - break; - case JoystickBase.handleSourceIdPropertyKey: - if (object is JoystickBase) { - object.handleSourceId = value; - } - break; - case OpenUrlEventBase.targetValuePropertyKey: - if (object is OpenUrlEventBase) { - object.targetValue = value; - } - break; - case DataBindBase.propertyKeyPropertyKey: - if (object is DataBindBase) { - object.propertyKey = value; - } - break; - case DataBindBase.flagsPropertyKey: - if (object is DataBindBase) { - object.flags = value; - } - break; - case DataBindBase.converterIdPropertyKey: - if (object is DataBindBase) { - object.converterId = value; - } - break; - case BindablePropertyEnumBase.propertyValuePropertyKey: - if (object is BindablePropertyEnumBase) { - object.propertyValue = value; - } - break; - case TendonBase.boneIdPropertyKey: - if (object is TendonBase) { - object.boneId = value; - } - break; - case TextModifierRangeBase.unitsValuePropertyKey: - if (object is TextModifierRangeBase) { - object.unitsValue = value; - } - break; - case TextModifierRangeBase.typeValuePropertyKey: - if (object is TextModifierRangeBase) { - object.typeValue = value; - } - break; - case TextModifierRangeBase.modeValuePropertyKey: - if (object is TextModifierRangeBase) { - object.modeValue = value; - } - break; - case TextModifierRangeBase.runIdPropertyKey: - if (object is TextModifierRangeBase) { - object.runId = value; - } - break; - case TextStyleFeatureBase.tagPropertyKey: - if (object is TextStyleFeatureBase) { - object.tag = value; - } - break; - case TextStyleFeatureBase.featureValuePropertyKey: - if (object is TextStyleFeatureBase) { - object.featureValue = value; - } - break; - case TextVariationModifierBase.axisTagPropertyKey: - if (object is TextVariationModifierBase) { - object.axisTag = value; - } - break; - case TextModifierGroupBase.modifierFlagsPropertyKey: - if (object is TextModifierGroupBase) { - object.modifierFlags = value; - } - break; - case TextStyleBase.fontAssetIdPropertyKey: - if (object is TextStyleBase) { - object.fontAssetId = value; - } - break; - case TextStyleAxisBase.tagPropertyKey: - if (object is TextStyleAxisBase) { - object.tag = value; - } - break; - case TextBase.alignValuePropertyKey: - if (object is TextBase) { - object.alignValue = value; - } - break; - case TextBase.sizingValuePropertyKey: - if (object is TextBase) { - object.sizingValue = value; - } - break; - case TextBase.overflowValuePropertyKey: - if (object is TextBase) { - object.overflowValue = value; - } - break; - case TextBase.originValuePropertyKey: - if (object is TextBase) { - object.originValue = value; - } - break; - case TextBase.wrapValuePropertyKey: - if (object is TextBase) { - object.wrapValue = value; - } - break; - case TextBase.verticalAlignValuePropertyKey: - if (object is TextBase) { - object.verticalAlignValue = value; - } - break; - case TextValueRunBase.styleIdPropertyKey: - if (object is TextValueRunBase) { - object.styleId = value; - } - break; - case FileAssetBase.assetIdPropertyKey: - if (object is FileAssetBase) { - object.assetId = value; - } - break; - case AudioEventBase.assetIdPropertyKey: - if (object is AudioEventBase) { - object.assetId = value; - } - break; - } - } - - static void setColor(Core object, int propertyKey, int value) { - switch (propertyKey) { - case ViewModelInstanceColorBase.propertyValuePropertyKey: - if (object is ViewModelInstanceColorBase) { - object.propertyValue = value; - } - break; - case KeyFrameColorBase.valuePropertyKey: - if (object is KeyFrameColorBase) { - object.value = value; - } - break; - case TransitionValueColorComparatorBase.valuePropertyKey: - if (object is TransitionValueColorComparatorBase) { - object.value = value; - } - break; - case SolidColorBase.colorValuePropertyKey: - if (object is SolidColorBase) { - object.colorValue = value; - } - break; - case GradientStopBase.colorValuePropertyKey: - if (object is GradientStopBase) { - object.colorValue = value; - } - break; - case BindablePropertyColorBase.propertyValuePropertyKey: - if (object is BindablePropertyColorBase) { - object.propertyValue = value; - } - break; - } - } - - static void setString(Core object, int propertyKey, String value) { - switch (propertyKey) { - case ViewModelComponentBase.namePropertyKey: - if (object is ViewModelComponentBase) { - object.name = value; - } - break; - case ViewModelInstanceStringBase.propertyValuePropertyKey: - if (object is ViewModelInstanceStringBase) { - object.propertyValue = value; - } - break; - case ComponentBase.namePropertyKey: - if (object is ComponentBase) { - object.name = value; - } - break; - case DataEnumValueBase.keyPropertyKey: - if (object is DataEnumValueBase) { - object.key = value; - } - break; - case DataEnumValueBase.valuePropertyKey: - if (object is DataEnumValueBase) { - object.value = value; - } - break; - case AnimationBase.namePropertyKey: - if (object is AnimationBase) { - object.name = value; - } - break; - case StateMachineComponentBase.namePropertyKey: - if (object is StateMachineComponentBase) { - object.name = value; - } - break; - case KeyFrameStringBase.valuePropertyKey: - if (object is KeyFrameStringBase) { - object.value = value; - } - break; - case TransitionValueStringComparatorBase.valuePropertyKey: - if (object is TransitionValueStringComparatorBase) { - object.value = value; - } - break; - case OpenUrlEventBase.urlPropertyKey: - if (object is OpenUrlEventBase) { - object.url = value; - } - break; - case DataConverterBase.namePropertyKey: - if (object is DataConverterBase) { - object.name = value; - } - break; - case BindablePropertyStringBase.propertyValuePropertyKey: - if (object is BindablePropertyStringBase) { - object.propertyValue = value; - } - break; - case TextValueRunBase.textPropertyKey: - if (object is TextValueRunBase) { - object.text = value; - } - break; - case CustomPropertyStringBase.propertyValuePropertyKey: - if (object is CustomPropertyStringBase) { - object.propertyValue = value; - } - break; - case AssetBase.namePropertyKey: - if (object is AssetBase) { - object.name = value; - } - break; - case FileAssetBase.cdnBaseUrlPropertyKey: - if (object is FileAssetBase) { - object.cdnBaseUrl = value; - } - break; - } - } - - static void setDouble(Core object, int propertyKey, double value) { - switch (propertyKey) { - case ViewModelInstanceNumberBase.propertyValuePropertyKey: - if (object is ViewModelInstanceNumberBase) { - object.propertyValue = value; - } - break; - case CustomPropertyNumberBase.propertyValuePropertyKey: - if (object is CustomPropertyNumberBase) { - object.propertyValue = value; - } - break; - case ConstraintBase.strengthPropertyKey: - if (object is ConstraintBase) { - object.strength = value; - } - break; - case DistanceConstraintBase.distancePropertyKey: - if (object is DistanceConstraintBase) { - object.distance = value; - } - break; - case TransformComponentConstraintBase.copyFactorPropertyKey: - if (object is TransformComponentConstraintBase) { - object.copyFactor = value; - } - break; - case TransformComponentConstraintBase.minValuePropertyKey: - if (object is TransformComponentConstraintBase) { - object.minValue = value; - } - break; - case TransformComponentConstraintBase.maxValuePropertyKey: - if (object is TransformComponentConstraintBase) { - object.maxValue = value; - } - break; - case TransformComponentConstraintYBase.copyFactorYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.copyFactorY = value; - } - break; - case TransformComponentConstraintYBase.minValueYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.minValueY = value; - } - break; - case TransformComponentConstraintYBase.maxValueYPropertyKey: - if (object is TransformComponentConstraintYBase) { - object.maxValueY = value; - } - break; - case FollowPathConstraintBase.distancePropertyKey: - if (object is FollowPathConstraintBase) { - object.distance = value; - } - break; - case TransformConstraintBase.originXPropertyKey: - if (object is TransformConstraintBase) { - object.originX = value; - } - break; - case TransformConstraintBase.originYPropertyKey: - if (object is TransformConstraintBase) { - object.originY = value; - } - break; - case WorldTransformComponentBase.opacityPropertyKey: - if (object is WorldTransformComponentBase) { - object.opacity = value; - } - break; - case TransformComponentBase.rotationPropertyKey: - if (object is TransformComponentBase) { - object.rotation = value; - } - break; - case TransformComponentBase.scaleXPropertyKey: - if (object is TransformComponentBase) { - object.scaleX = value; - } - break; - case TransformComponentBase.scaleYPropertyKey: - if (object is TransformComponentBase) { - object.scaleY = value; - } - break; - case NodeBase.xPropertyKey: - if (object is NodeBase) { - object.x = value; - } - break; - case NodeBase.yPropertyKey: - if (object is NodeBase) { - object.y = value; - } - break; - case LayoutComponentStyleBase.gapHorizontalPropertyKey: - if (object is LayoutComponentStyleBase) { - object.gapHorizontal = value; - } - break; - case LayoutComponentStyleBase.gapVerticalPropertyKey: - if (object is LayoutComponentStyleBase) { - object.gapVertical = value; - } - break; - case LayoutComponentStyleBase.maxWidthPropertyKey: - if (object is LayoutComponentStyleBase) { - object.maxWidth = value; - } - break; - case LayoutComponentStyleBase.maxHeightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.maxHeight = value; - } - break; - case LayoutComponentStyleBase.minWidthPropertyKey: - if (object is LayoutComponentStyleBase) { - object.minWidth = value; - } - break; - case LayoutComponentStyleBase.minHeightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.minHeight = value; - } - break; - case LayoutComponentStyleBase.borderLeftPropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderLeft = value; - } - break; - case LayoutComponentStyleBase.borderRightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderRight = value; - } - break; - case LayoutComponentStyleBase.borderTopPropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderTop = value; - } - break; - case LayoutComponentStyleBase.borderBottomPropertyKey: - if (object is LayoutComponentStyleBase) { - object.borderBottom = value; - } - break; - case LayoutComponentStyleBase.marginLeftPropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginLeft = value; - } - break; - case LayoutComponentStyleBase.marginRightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginRight = value; - } - break; - case LayoutComponentStyleBase.marginTopPropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginTop = value; - } - break; - case LayoutComponentStyleBase.marginBottomPropertyKey: - if (object is LayoutComponentStyleBase) { - object.marginBottom = value; - } - break; - case LayoutComponentStyleBase.paddingLeftPropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingLeft = value; - } - break; - case LayoutComponentStyleBase.paddingRightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingRight = value; - } - break; - case LayoutComponentStyleBase.paddingTopPropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingTop = value; - } - break; - case LayoutComponentStyleBase.paddingBottomPropertyKey: - if (object is LayoutComponentStyleBase) { - object.paddingBottom = value; - } - break; - case LayoutComponentStyleBase.positionLeftPropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionLeft = value; - } - break; - case LayoutComponentStyleBase.positionRightPropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionRight = value; - } - break; - case LayoutComponentStyleBase.positionTopPropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionTop = value; - } - break; - case LayoutComponentStyleBase.positionBottomPropertyKey: - if (object is LayoutComponentStyleBase) { - object.positionBottom = value; - } - break; - case LayoutComponentStyleBase.flexPropertyKey: - if (object is LayoutComponentStyleBase) { - object.flex = value; - } - break; - case LayoutComponentStyleBase.flexGrowPropertyKey: - if (object is LayoutComponentStyleBase) { - object.flexGrow = value; - } - break; - case LayoutComponentStyleBase.flexShrinkPropertyKey: - if (object is LayoutComponentStyleBase) { - object.flexShrink = value; - } - break; - case LayoutComponentStyleBase.flexBasisPropertyKey: - if (object is LayoutComponentStyleBase) { - object.flexBasis = value; - } - break; - case LayoutComponentStyleBase.aspectRatioPropertyKey: - if (object is LayoutComponentStyleBase) { - object.aspectRatio = value; - } - break; - case LayoutComponentStyleBase.interpolationTimePropertyKey: - if (object is LayoutComponentStyleBase) { - object.interpolationTime = value; - } - break; - case LinearAnimationBase.speedPropertyKey: - if (object is LinearAnimationBase) { - object.speed = value; - } - break; - case NestedLinearAnimationBase.mixPropertyKey: - if (object is NestedLinearAnimationBase) { - object.mix = value; - } - break; - case NestedSimpleAnimationBase.speedPropertyKey: - if (object is NestedSimpleAnimationBase) { - object.speed = value; - } - break; - case AdvanceableStateBase.speedPropertyKey: - if (object is AdvanceableStateBase) { - object.speed = value; - } - break; - case BlendAnimationDirectBase.mixValuePropertyKey: - if (object is BlendAnimationDirectBase) { - object.mixValue = value; - } - break; - case StateMachineNumberBase.valuePropertyKey: - if (object is StateMachineNumberBase) { - object.value = value; - } - break; - case CubicInterpolatorBase.x1PropertyKey: - if (object is CubicInterpolatorBase) { - object.x1 = value; - } - break; - case CubicInterpolatorBase.y1PropertyKey: - if (object is CubicInterpolatorBase) { - object.y1 = value; - } - break; - case CubicInterpolatorBase.x2PropertyKey: - if (object is CubicInterpolatorBase) { - object.x2 = value; - } - break; - case CubicInterpolatorBase.y2PropertyKey: - if (object is CubicInterpolatorBase) { - object.y2 = value; - } - break; - case TransitionNumberConditionBase.valuePropertyKey: - if (object is TransitionNumberConditionBase) { - object.value = value; - } - break; - case CubicInterpolatorComponentBase.x1PropertyKey: - if (object is CubicInterpolatorComponentBase) { - object.x1 = value; - } - break; - case CubicInterpolatorComponentBase.y1PropertyKey: - if (object is CubicInterpolatorComponentBase) { - object.y1 = value; - } - break; - case CubicInterpolatorComponentBase.x2PropertyKey: - if (object is CubicInterpolatorComponentBase) { - object.x2 = value; - } - break; - case CubicInterpolatorComponentBase.y2PropertyKey: - if (object is CubicInterpolatorComponentBase) { - object.y2 = value; - } - break; - case ListenerNumberChangeBase.valuePropertyKey: - if (object is ListenerNumberChangeBase) { - object.value = value; - } - break; - case KeyFrameDoubleBase.valuePropertyKey: - if (object is KeyFrameDoubleBase) { - object.value = value; - } - break; - case TransitionValueNumberComparatorBase.valuePropertyKey: - if (object is TransitionValueNumberComparatorBase) { - object.value = value; - } - break; - case ElasticInterpolatorBase.amplitudePropertyKey: - if (object is ElasticInterpolatorBase) { - object.amplitude = value; - } - break; - case ElasticInterpolatorBase.periodPropertyKey: - if (object is ElasticInterpolatorBase) { - object.period = value; - } - break; - case NestedNumberBase.nestedValuePropertyKey: - if (object is NestedNumberBase) { - object.nestedValue = value; - } - break; - case BlendAnimation1DBase.valuePropertyKey: - if (object is BlendAnimation1DBase) { - object.value = value; - } - break; - case NestedRemapAnimationBase.timePropertyKey: - if (object is NestedRemapAnimationBase) { - object.time = value; - } - break; - case LinearGradientBase.startXPropertyKey: - if (object is LinearGradientBase) { - object.startX = value; - } - break; - case LinearGradientBase.startYPropertyKey: - if (object is LinearGradientBase) { - object.startY = value; - } - break; - case LinearGradientBase.endXPropertyKey: - if (object is LinearGradientBase) { - object.endX = value; - } - break; - case LinearGradientBase.endYPropertyKey: - if (object is LinearGradientBase) { - object.endY = value; - } - break; - case LinearGradientBase.opacityPropertyKey: - if (object is LinearGradientBase) { - object.opacity = value; - } - break; - case StrokeBase.thicknessPropertyKey: - if (object is StrokeBase) { - object.thickness = value; - } - break; - case GradientStopBase.positionPropertyKey: - if (object is GradientStopBase) { - object.position = value; - } - break; - case TrimPathBase.startPropertyKey: - if (object is TrimPathBase) { - object.start = value; - } - break; - case TrimPathBase.endPropertyKey: - if (object is TrimPathBase) { - object.end = value; - } - break; - case TrimPathBase.offsetPropertyKey: - if (object is TrimPathBase) { - object.offset = value; - } - break; - case VertexBase.xPropertyKey: - if (object is VertexBase) { - object.x = value; - } - break; - case VertexBase.yPropertyKey: - if (object is VertexBase) { - object.y = value; - } - break; - case MeshVertexBase.uPropertyKey: - if (object is MeshVertexBase) { - object.u = value; - } - break; - case MeshVertexBase.vPropertyKey: - if (object is MeshVertexBase) { - object.v = value; - } - break; - case StraightVertexBase.radiusPropertyKey: - if (object is StraightVertexBase) { - object.radius = value; - } - break; - case CubicAsymmetricVertexBase.rotationPropertyKey: - if (object is CubicAsymmetricVertexBase) { - object.rotation = value; - } - break; - case CubicAsymmetricVertexBase.inDistancePropertyKey: - if (object is CubicAsymmetricVertexBase) { - object.inDistance = value; - } - break; - case CubicAsymmetricVertexBase.outDistancePropertyKey: - if (object is CubicAsymmetricVertexBase) { - object.outDistance = value; - } - break; - case ParametricPathBase.widthPropertyKey: - if (object is ParametricPathBase) { - object.width = value; - } - break; - case ParametricPathBase.heightPropertyKey: - if (object is ParametricPathBase) { - object.height = value; - } - break; - case ParametricPathBase.originXPropertyKey: - if (object is ParametricPathBase) { - object.originX = value; - } - break; - case ParametricPathBase.originYPropertyKey: - if (object is ParametricPathBase) { - object.originY = value; - } - break; - case RectangleBase.cornerRadiusTLPropertyKey: - if (object is RectangleBase) { - object.cornerRadiusTL = value; - } - break; - case RectangleBase.cornerRadiusTRPropertyKey: - if (object is RectangleBase) { - object.cornerRadiusTR = value; - } - break; - case RectangleBase.cornerRadiusBLPropertyKey: - if (object is RectangleBase) { - object.cornerRadiusBL = value; - } - break; - case RectangleBase.cornerRadiusBRPropertyKey: - if (object is RectangleBase) { - object.cornerRadiusBR = value; - } - break; - case CubicMirroredVertexBase.rotationPropertyKey: - if (object is CubicMirroredVertexBase) { - object.rotation = value; - } - break; - case CubicMirroredVertexBase.distancePropertyKey: - if (object is CubicMirroredVertexBase) { - object.distance = value; - } - break; - case PolygonBase.cornerRadiusPropertyKey: - if (object is PolygonBase) { - object.cornerRadius = value; - } - break; - case StarBase.innerRadiusPropertyKey: - if (object is StarBase) { - object.innerRadius = value; - } - break; - case ImageBase.originXPropertyKey: - if (object is ImageBase) { - object.originX = value; - } - break; - case ImageBase.originYPropertyKey: - if (object is ImageBase) { - object.originY = value; - } - break; - case CubicDetachedVertexBase.inRotationPropertyKey: - if (object is CubicDetachedVertexBase) { - object.inRotation = value; - } - break; - case CubicDetachedVertexBase.inDistancePropertyKey: - if (object is CubicDetachedVertexBase) { - object.inDistance = value; - } - break; - case CubicDetachedVertexBase.outRotationPropertyKey: - if (object is CubicDetachedVertexBase) { - object.outRotation = value; - } - break; - case CubicDetachedVertexBase.outDistancePropertyKey: - if (object is CubicDetachedVertexBase) { - object.outDistance = value; - } - break; - case LayoutComponentBase.widthPropertyKey: - if (object is LayoutComponentBase) { - object.width = value; - } - break; - case LayoutComponentBase.heightPropertyKey: - if (object is LayoutComponentBase) { - object.height = value; - } - break; - case ArtboardBase.xPropertyKey: - if (object is ArtboardBase) { - object.x = value; - } - break; - case ArtboardBase.yPropertyKey: - if (object is ArtboardBase) { - object.y = value; - } - break; - case ArtboardBase.originXPropertyKey: - if (object is ArtboardBase) { - object.originX = value; - } - break; - case ArtboardBase.originYPropertyKey: - if (object is ArtboardBase) { - object.originY = value; - } - break; - case JoystickBase.xPropertyKey: - if (object is JoystickBase) { - object.x = value; - } - break; - case JoystickBase.yPropertyKey: - if (object is JoystickBase) { - object.y = value; - } - break; - case JoystickBase.posXPropertyKey: - if (object is JoystickBase) { - object.posX = value; - } - break; - case JoystickBase.posYPropertyKey: - if (object is JoystickBase) { - object.posY = value; - } - break; - case JoystickBase.originXPropertyKey: - if (object is JoystickBase) { - object.originX = value; - } - break; - case JoystickBase.originYPropertyKey: - if (object is JoystickBase) { - object.originY = value; - } - break; - case JoystickBase.widthPropertyKey: - if (object is JoystickBase) { - object.width = value; - } - break; - case JoystickBase.heightPropertyKey: - if (object is JoystickBase) { - object.height = value; - } - break; - case BindablePropertyNumberBase.propertyValuePropertyKey: - if (object is BindablePropertyNumberBase) { - object.propertyValue = value; - } - break; - case BoneBase.lengthPropertyKey: - if (object is BoneBase) { - object.length = value; - } - break; - case RootBoneBase.xPropertyKey: - if (object is RootBoneBase) { - object.x = value; - } - break; - case RootBoneBase.yPropertyKey: - if (object is RootBoneBase) { - object.y = value; - } - break; - case SkinBase.xxPropertyKey: - if (object is SkinBase) { - object.xx = value; - } - break; - case SkinBase.yxPropertyKey: - if (object is SkinBase) { - object.yx = value; - } - break; - case SkinBase.xyPropertyKey: - if (object is SkinBase) { - object.xy = value; - } - break; - case SkinBase.yyPropertyKey: - if (object is SkinBase) { - object.yy = value; - } - break; - case SkinBase.txPropertyKey: - if (object is SkinBase) { - object.tx = value; - } - break; - case SkinBase.tyPropertyKey: - if (object is SkinBase) { - object.ty = value; - } - break; - case TendonBase.xxPropertyKey: - if (object is TendonBase) { - object.xx = value; - } - break; - case TendonBase.yxPropertyKey: - if (object is TendonBase) { - object.yx = value; - } - break; - case TendonBase.xyPropertyKey: - if (object is TendonBase) { - object.xy = value; - } - break; - case TendonBase.yyPropertyKey: - if (object is TendonBase) { - object.yy = value; - } - break; - case TendonBase.txPropertyKey: - if (object is TendonBase) { - object.tx = value; - } - break; - case TendonBase.tyPropertyKey: - if (object is TendonBase) { - object.ty = value; - } - break; - case TextModifierRangeBase.modifyFromPropertyKey: - if (object is TextModifierRangeBase) { - object.modifyFrom = value; - } - break; - case TextModifierRangeBase.modifyToPropertyKey: - if (object is TextModifierRangeBase) { - object.modifyTo = value; - } - break; - case TextModifierRangeBase.strengthPropertyKey: - if (object is TextModifierRangeBase) { - object.strength = value; - } - break; - case TextModifierRangeBase.falloffFromPropertyKey: - if (object is TextModifierRangeBase) { - object.falloffFrom = value; - } - break; - case TextModifierRangeBase.falloffToPropertyKey: - if (object is TextModifierRangeBase) { - object.falloffTo = value; - } - break; - case TextModifierRangeBase.offsetPropertyKey: - if (object is TextModifierRangeBase) { - object.offset = value; - } - break; - case TextVariationModifierBase.axisValuePropertyKey: - if (object is TextVariationModifierBase) { - object.axisValue = value; - } - break; - case TextModifierGroupBase.originXPropertyKey: - if (object is TextModifierGroupBase) { - object.originX = value; - } - break; - case TextModifierGroupBase.originYPropertyKey: - if (object is TextModifierGroupBase) { - object.originY = value; - } - break; - case TextModifierGroupBase.opacityPropertyKey: - if (object is TextModifierGroupBase) { - object.opacity = value; - } - break; - case TextModifierGroupBase.xPropertyKey: - if (object is TextModifierGroupBase) { - object.x = value; - } - break; - case TextModifierGroupBase.yPropertyKey: - if (object is TextModifierGroupBase) { - object.y = value; - } - break; - case TextModifierGroupBase.rotationPropertyKey: - if (object is TextModifierGroupBase) { - object.rotation = value; - } - break; - case TextModifierGroupBase.scaleXPropertyKey: - if (object is TextModifierGroupBase) { - object.scaleX = value; - } - break; - case TextModifierGroupBase.scaleYPropertyKey: - if (object is TextModifierGroupBase) { - object.scaleY = value; - } - break; - case TextStyleBase.fontSizePropertyKey: - if (object is TextStyleBase) { - object.fontSize = value; - } - break; - case TextStyleBase.lineHeightPropertyKey: - if (object is TextStyleBase) { - object.lineHeight = value; - } - break; - case TextStyleBase.letterSpacingPropertyKey: - if (object is TextStyleBase) { - object.letterSpacing = value; - } - break; - case TextStyleAxisBase.axisValuePropertyKey: - if (object is TextStyleAxisBase) { - object.axisValue = value; - } - break; - case TextBase.widthPropertyKey: - if (object is TextBase) { - object.width = value; - } - break; - case TextBase.heightPropertyKey: - if (object is TextBase) { - object.height = value; - } - break; - case TextBase.originXPropertyKey: - if (object is TextBase) { - object.originX = value; - } - break; - case TextBase.originYPropertyKey: - if (object is TextBase) { - object.originY = value; - } - break; - case TextBase.paragraphSpacingPropertyKey: - if (object is TextBase) { - object.paragraphSpacing = value; - } - break; - case ExportAudioBase.volumePropertyKey: - if (object is ExportAudioBase) { - object.volume = value; - } - break; - case DrawableAssetBase.heightPropertyKey: - if (object is DrawableAssetBase) { - object.height = value; - } - break; - case DrawableAssetBase.widthPropertyKey: - if (object is DrawableAssetBase) { - object.width = value; - } - break; - } - } - - static void setBytes(Core object, int propertyKey, Uint8List value) { - switch (propertyKey) { - case NestedArtboardBase.dataBindPathIdsPropertyKey: - if (object is NestedArtboardBase) { - object.dataBindPathIds = value; - } - break; - case MeshBase.triangleIndexBytesPropertyKey: - if (object is MeshBase) { - object.triangleIndexBytes = value; - } - break; - case DataBindContextBase.sourcePathIdsPropertyKey: - if (object is DataBindContextBase) { - object.sourcePathIds = value; - } - break; - case FileAssetBase.cdnUuidPropertyKey: - if (object is FileAssetBase) { - object.cdnUuid = value; - } - break; - case FileAssetContentsBase.bytesPropertyKey: - if (object is FileAssetContentsBase) { - object.bytes = value; - } - break; - } - } - - static void setCallback(Core object, int propertyKey, CallbackData value) { - switch (propertyKey) { - case NestedTriggerBase.firePropertyKey: - if (object is NestedTriggerBase) { - object.fire(value); - } - break; - case EventBase.triggerPropertyKey: - if (object is EventBase) { - object.trigger(value); - } - break; - } - } -} diff --git a/lib/src/generated/shapes/clipping_shape_base.dart b/lib/src/generated/shapes/clipping_shape_base.dart deleted file mode 100644 index 449adb0..0000000 --- a/lib/src/generated/shapes/clipping_shape_base.dart +++ /dev/null @@ -1,94 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/clipping_shape_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class ClippingShapeBase extends Component { - static const int typeKey = 42; - @override - int get coreType => ClippingShapeBase.typeKey; - @override - Set get coreTypes => {ClippingShapeBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// SourceId field with key 92. - static const int sourceIdPropertyKey = 92; - static const int sourceIdInitialValue = -1; - int _sourceId = sourceIdInitialValue; - - /// Identifier used to track the node to use as a clipping source. - int get sourceId => _sourceId; - - /// Change the [_sourceId] field value. - /// [sourceIdChanged] will be invoked only if the field's value has changed. - set sourceId(int value) { - if (_sourceId == value) { - return; - } - int from = _sourceId; - _sourceId = value; - if (hasValidated) { - sourceIdChanged(from, value); - } - } - - void sourceIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// FillRule field with key 93. - static const int fillRulePropertyKey = 93; - static const int fillRuleInitialValue = 0; - int _fillRule = fillRuleInitialValue; - - /// Backing enum value for the clipping fill rule (nonZero or evenOdd). - int get fillRule => _fillRule; - - /// Change the [_fillRule] field value. - /// [fillRuleChanged] will be invoked only if the field's value has changed. - set fillRule(int value) { - if (_fillRule == value) { - return; - } - int from = _fillRule; - _fillRule = value; - if (hasValidated) { - fillRuleChanged(from, value); - } - } - - void fillRuleChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// IsVisible field with key 94. - static const int isVisiblePropertyKey = 94; - static const bool isVisibleInitialValue = true; - bool _isVisible = isVisibleInitialValue; - bool get isVisible => _isVisible; - - /// Change the [_isVisible] field value. - /// [isVisibleChanged] will be invoked only if the field's value has changed. - set isVisible(bool value) { - if (_isVisible == value) { - return; - } - bool from = _isVisible; - _isVisible = value; - if (hasValidated) { - isVisibleChanged(from, value); - } - } - - void isVisibleChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ClippingShapeBase) { - _sourceId = source._sourceId; - _fillRule = source._fillRule; - _isVisible = source._isVisible; - } - } -} diff --git a/lib/src/generated/shapes/contour_mesh_vertex_base.dart b/lib/src/generated/shapes/contour_mesh_vertex_base.dart deleted file mode 100644 index 25a87f5..0000000 --- a/lib/src/generated/shapes/contour_mesh_vertex_base.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/contour_mesh_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/shapes/mesh_vertex.dart'; - -abstract class ContourMeshVertexBase extends MeshVertex { - static const int typeKey = 111; - @override - int get coreType => ContourMeshVertexBase.typeKey; - @override - Set get coreTypes => { - ContourMeshVertexBase.typeKey, - MeshVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart b/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart deleted file mode 100644 index 216364b..0000000 --- a/lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart +++ /dev/null @@ -1,108 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/cubic_asymmetric_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/path_vertex_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; - -abstract class CubicAsymmetricVertexBase extends CubicVertex { - static const int typeKey = 34; - @override - int get coreType => CubicAsymmetricVertexBase.typeKey; - @override - Set get coreTypes => { - CubicAsymmetricVertexBase.typeKey, - CubicVertexBase.typeKey, - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Rotation field with key 79. - static const int rotationPropertyKey = 79; - static const double rotationInitialValue = 0; - double _rotation = rotationInitialValue; - - /// The control points' angle. - double get rotation => _rotation; - - /// Change the [_rotation] field value. - /// [rotationChanged] will be invoked only if the field's value has changed. - set rotation(double value) { - if (_rotation == value) { - return; - } - double from = _rotation; - _rotation = value; - if (hasValidated) { - rotationChanged(from, value); - } - } - - void rotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// InDistance field with key 80. - static const int inDistancePropertyKey = 80; - static const double inDistanceInitialValue = 0; - double _inDistance = inDistanceInitialValue; - - /// The in point's distance from the translation of the point. - double get inDistance => _inDistance; - - /// Change the [_inDistance] field value. - /// [inDistanceChanged] will be invoked only if the field's value has changed. - set inDistance(double value) { - if (_inDistance == value) { - return; - } - double from = _inDistance; - _inDistance = value; - if (hasValidated) { - inDistanceChanged(from, value); - } - } - - void inDistanceChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OutDistance field with key 81. - static const int outDistancePropertyKey = 81; - static const double outDistanceInitialValue = 0; - double _outDistance = outDistanceInitialValue; - - /// The out point's distance from the translation of the point. - double get outDistance => _outDistance; - - /// Change the [_outDistance] field value. - /// [outDistanceChanged] will be invoked only if the field's value has - /// changed. - set outDistance(double value) { - if (_outDistance == value) { - return; - } - double from = _outDistance; - _outDistance = value; - if (hasValidated) { - outDistanceChanged(from, value); - } - } - - void outDistanceChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicAsymmetricVertexBase) { - _rotation = source._rotation; - _inDistance = source._inDistance; - _outDistance = source._outDistance; - } - } -} diff --git a/lib/src/generated/shapes/cubic_detached_vertex_base.dart b/lib/src/generated/shapes/cubic_detached_vertex_base.dart deleted file mode 100644 index 8e44fc9..0000000 --- a/lib/src/generated/shapes/cubic_detached_vertex_base.dart +++ /dev/null @@ -1,134 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/cubic_detached_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/path_vertex_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; - -abstract class CubicDetachedVertexBase extends CubicVertex { - static const int typeKey = 6; - @override - int get coreType => CubicDetachedVertexBase.typeKey; - @override - Set get coreTypes => { - CubicDetachedVertexBase.typeKey, - CubicVertexBase.typeKey, - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// InRotation field with key 84. - static const int inRotationPropertyKey = 84; - static const double inRotationInitialValue = 0; - double _inRotation = inRotationInitialValue; - - /// The in point's angle. - double get inRotation => _inRotation; - - /// Change the [_inRotation] field value. - /// [inRotationChanged] will be invoked only if the field's value has changed. - set inRotation(double value) { - if (_inRotation == value) { - return; - } - double from = _inRotation; - _inRotation = value; - if (hasValidated) { - inRotationChanged(from, value); - } - } - - void inRotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// InDistance field with key 85. - static const int inDistancePropertyKey = 85; - static const double inDistanceInitialValue = 0; - double _inDistance = inDistanceInitialValue; - - /// The in point's distance from the translation of the point. - double get inDistance => _inDistance; - - /// Change the [_inDistance] field value. - /// [inDistanceChanged] will be invoked only if the field's value has changed. - set inDistance(double value) { - if (_inDistance == value) { - return; - } - double from = _inDistance; - _inDistance = value; - if (hasValidated) { - inDistanceChanged(from, value); - } - } - - void inDistanceChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OutRotation field with key 86. - static const int outRotationPropertyKey = 86; - static const double outRotationInitialValue = 0; - double _outRotation = outRotationInitialValue; - - /// The out point's angle. - double get outRotation => _outRotation; - - /// Change the [_outRotation] field value. - /// [outRotationChanged] will be invoked only if the field's value has - /// changed. - set outRotation(double value) { - if (_outRotation == value) { - return; - } - double from = _outRotation; - _outRotation = value; - if (hasValidated) { - outRotationChanged(from, value); - } - } - - void outRotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OutDistance field with key 87. - static const int outDistancePropertyKey = 87; - static const double outDistanceInitialValue = 0; - double _outDistance = outDistanceInitialValue; - - /// The out point's distance from the translation of the point. - double get outDistance => _outDistance; - - /// Change the [_outDistance] field value. - /// [outDistanceChanged] will be invoked only if the field's value has - /// changed. - set outDistance(double value) { - if (_outDistance == value) { - return; - } - double from = _outDistance; - _outDistance = value; - if (hasValidated) { - outDistanceChanged(from, value); - } - } - - void outDistanceChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicDetachedVertexBase) { - _inRotation = source._inRotation; - _inDistance = source._inDistance; - _outRotation = source._outRotation; - _outDistance = source._outDistance; - } - } -} diff --git a/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart b/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart deleted file mode 100644 index 4a0b68c..0000000 --- a/lib/src/generated/shapes/cubic_mirrored_vertex_base.dart +++ /dev/null @@ -1,82 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/cubic_mirrored_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/path_vertex_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; - -abstract class CubicMirroredVertexBase extends CubicVertex { - static const int typeKey = 35; - @override - int get coreType => CubicMirroredVertexBase.typeKey; - @override - Set get coreTypes => { - CubicMirroredVertexBase.typeKey, - CubicVertexBase.typeKey, - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Rotation field with key 82. - static const int rotationPropertyKey = 82; - static const double rotationInitialValue = 0; - double _rotation = rotationInitialValue; - - /// The control points' angle. - double get rotation => _rotation; - - /// Change the [_rotation] field value. - /// [rotationChanged] will be invoked only if the field's value has changed. - set rotation(double value) { - if (_rotation == value) { - return; - } - double from = _rotation; - _rotation = value; - if (hasValidated) { - rotationChanged(from, value); - } - } - - void rotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Distance field with key 83. - static const int distancePropertyKey = 83; - static const double distanceInitialValue = 0; - double _distance = distanceInitialValue; - - /// The control points' distance from the translation of the point. - double get distance => _distance; - - /// Change the [_distance] field value. - /// [distanceChanged] will be invoked only if the field's value has changed. - set distance(double value) { - if (_distance == value) { - return; - } - double from = _distance; - _distance = value; - if (hasValidated) { - distanceChanged(from, value); - } - } - - void distanceChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is CubicMirroredVertexBase) { - _rotation = source._rotation; - _distance = source._distance; - } - } -} diff --git a/lib/src/generated/shapes/cubic_vertex_base.dart b/lib/src/generated/shapes/cubic_vertex_base.dart deleted file mode 100644 index eaf5f64..0000000 --- a/lib/src/generated/shapes/cubic_vertex_base.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/cubic_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/bones/cubic_weight.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; - -abstract class CubicVertexBase extends PathVertex { - static const int typeKey = 36; - @override - int get coreType => CubicVertexBase.typeKey; - @override - Set get coreTypes => { - CubicVertexBase.typeKey, - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/ellipse_base.dart b/lib/src/generated/shapes/ellipse_base.dart deleted file mode 100644 index d331625..0000000 --- a/lib/src/generated/shapes/ellipse_base.dart +++ /dev/null @@ -1,27 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/ellipse_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/parametric_path.dart'; - -abstract class EllipseBase extends ParametricPath { - static const int typeKey = 4; - @override - int get coreType => EllipseBase.typeKey; - @override - Set get coreTypes => { - EllipseBase.typeKey, - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/forced_edge_base.dart b/lib/src/generated/shapes/forced_edge_base.dart deleted file mode 100644 index b8a36c2..0000000 --- a/lib/src/generated/shapes/forced_edge_base.dart +++ /dev/null @@ -1,67 +0,0 @@ -/// Core automatically generated lib/src/generated/shapes/forced_edge_base.dart. -/// Do not modify manually. - -import 'package:rive/src/rive_core/component.dart'; - -abstract class ForcedEdgeBase extends Component { - static const int typeKey = 112; - @override - int get coreType => ForcedEdgeBase.typeKey; - @override - Set get coreTypes => {ForcedEdgeBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// FromId field with key 219. - static const int fromIdInitialValue = 0; - int _fromId = fromIdInitialValue; - static const int fromIdPropertyKey = 219; - - /// Identifier used to track MeshVertex the force edge extends from. - int get fromId => _fromId; - - /// Change the [_fromId] field value. - /// [fromIdChanged] will be invoked only if the field's value has changed. - set fromId(int value) { - if (_fromId == value) { - return; - } - int from = _fromId; - _fromId = value; - if (hasValidated) { - fromIdChanged(from, value); - } - } - - void fromIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ToId field with key 220. - static const int toIdInitialValue = 0; - int _toId = toIdInitialValue; - static const int toIdPropertyKey = 220; - - /// Identifier used to track MeshVertex the force edge extends to. - int get toId => _toId; - - /// Change the [_toId] field value. - /// [toIdChanged] will be invoked only if the field's value has changed. - set toId(int value) { - if (_toId == value) { - return; - } - int from = _toId; - _toId = value; - if (hasValidated) { - toIdChanged(from, value); - } - } - - void toIdChanged(int from, int to); - - @override - void copy(covariant ForcedEdgeBase source) { - super.copy(source); - _fromId = source._fromId; - _toId = source._toId; - } -} diff --git a/lib/src/generated/shapes/image_base.dart b/lib/src/generated/shapes/image_base.dart deleted file mode 100644 index d1fc617..0000000 --- a/lib/src/generated/shapes/image_base.dart +++ /dev/null @@ -1,108 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/image_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/drawable.dart'; - -abstract class ImageBase extends Drawable { - static const int typeKey = 100; - @override - int get coreType => ImageBase.typeKey; - @override - Set get coreTypes => { - ImageBase.typeKey, - DrawableBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AssetId field with key 206. - static const int assetIdPropertyKey = 206; - static const int assetIdInitialValue = -1; - int _assetId = assetIdInitialValue; - - /// Image drawable for an image asset - int get assetId => _assetId; - - /// Change the [_assetId] field value. - /// [assetIdChanged] will be invoked only if the field's value has changed. - set assetId(int value) { - if (_assetId == value) { - return; - } - int from = _assetId; - _assetId = value; - if (hasValidated) { - assetIdChanged(from, value); - } - } - - void assetIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 380. - static const int originXPropertyKey = 380; - static const double originXInitialValue = 0.5; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 381. - static const int originYPropertyKey = 381; - static const double originYInitialValue = 0.5; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ImageBase) { - _assetId = source._assetId; - _originX = source._originX; - _originY = source._originY; - } - } -} diff --git a/lib/src/generated/shapes/mesh_base.dart b/lib/src/generated/shapes/mesh_base.dart deleted file mode 100644 index e617989..0000000 --- a/lib/src/generated/shapes/mesh_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/mesh_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class MeshBase extends ContainerComponent { - static const int typeKey = 109; - @override - int get coreType => MeshBase.typeKey; - @override - Set get coreTypes => - {MeshBase.typeKey, ContainerComponentBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// TriangleIndexBytes field with key 223. - static const int triangleIndexBytesPropertyKey = 223; - static final Uint8List triangleIndexBytesInitialValue = Uint8List(0); - Uint8List _triangleIndexBytes = triangleIndexBytesInitialValue; - - /// Byte data for the triangle indices. - Uint8List get triangleIndexBytes => _triangleIndexBytes; - - /// Change the [_triangleIndexBytes] field value. - /// [triangleIndexBytesChanged] will be invoked only if the field's value has - /// changed. - set triangleIndexBytes(Uint8List value) { - if (listEquals(_triangleIndexBytes, value)) { - return; - } - Uint8List from = _triangleIndexBytes; - _triangleIndexBytes = value; - if (hasValidated) { - triangleIndexBytesChanged(from, value); - } - } - - void triangleIndexBytesChanged(Uint8List from, Uint8List to); - - @override - void copy(Core source) { - super.copy(source); - if (source is MeshBase) { - _triangleIndexBytes = source._triangleIndexBytes; - } - } -} diff --git a/lib/src/generated/shapes/mesh_vertex_base.dart b/lib/src/generated/shapes/mesh_vertex_base.dart deleted file mode 100644 index e149341..0000000 --- a/lib/src/generated/shapes/mesh_vertex_base.dart +++ /dev/null @@ -1,77 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/mesh_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/shapes/vertex.dart'; - -abstract class MeshVertexBase extends Vertex { - static const int typeKey = 108; - @override - int get coreType => MeshVertexBase.typeKey; - @override - Set get coreTypes => { - MeshVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// U field with key 215. - static const int uPropertyKey = 215; - static const double uInitialValue = 0; - double _u = uInitialValue; - - /// U value for the texture coordinate of the vertex. - double get u => _u; - - /// Change the [_u] field value. - /// [uChanged] will be invoked only if the field's value has changed. - set u(double value) { - if (_u == value) { - return; - } - double from = _u; - _u = value; - if (hasValidated) { - uChanged(from, value); - } - } - - void uChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// V field with key 216. - static const int vPropertyKey = 216; - static const double vInitialValue = 0; - double _v = vInitialValue; - - /// V value for the texture coordinate of the vertex. - double get v => _v; - - /// Change the [_v] field value. - /// [vChanged] will be invoked only if the field's value has changed. - set v(double value) { - if (_v == value) { - return; - } - double from = _v; - _v = value; - if (hasValidated) { - vChanged(from, value); - } - } - - void vChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is MeshVertexBase) { - _u = source._u; - _v = source._v; - } - } -} diff --git a/lib/src/generated/shapes/paint/fill_base.dart b/lib/src/generated/shapes/paint/fill_base.dart deleted file mode 100644 index 0a95199..0000000 --- a/lib/src/generated/shapes/paint/fill_base.dart +++ /dev/null @@ -1,50 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/paint/fill_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart'; - -abstract class FillBase extends ShapePaint { - static const int typeKey = 20; - @override - int get coreType => FillBase.typeKey; - @override - Set get coreTypes => { - FillBase.typeKey, - ShapePaintBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// FillRule field with key 40. - static const int fillRulePropertyKey = 40; - static const int fillRuleInitialValue = 0; - int _fillRule = fillRuleInitialValue; - int get fillRule => _fillRule; - - /// Change the [_fillRule] field value. - /// [fillRuleChanged] will be invoked only if the field's value has changed. - set fillRule(int value) { - if (_fillRule == value) { - return; - } - int from = _fillRule; - _fillRule = value; - if (hasValidated) { - fillRuleChanged(from, value); - } - } - - void fillRuleChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is FillBase) { - _fillRule = source._fillRule; - } - } -} diff --git a/lib/src/generated/shapes/paint/gradient_stop_base.dart b/lib/src/generated/shapes/paint/gradient_stop_base.dart deleted file mode 100644 index bf6117c..0000000 --- a/lib/src/generated/shapes/paint/gradient_stop_base.dart +++ /dev/null @@ -1,67 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/gradient_stop_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class GradientStopBase extends Component { - static const int typeKey = 19; - @override - int get coreType => GradientStopBase.typeKey; - @override - Set get coreTypes => {GradientStopBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// ColorValue field with key 38. - static const int colorValuePropertyKey = 38; - static const int colorValueInitialValue = 0xFFFFFFFF; - int _colorValue = colorValueInitialValue; - int get colorValue => _colorValue; - - /// Change the [_colorValue] field value. - /// [colorValueChanged] will be invoked only if the field's value has changed. - set colorValue(int value) { - if (_colorValue == value) { - return; - } - int from = _colorValue; - _colorValue = value; - if (hasValidated) { - colorValueChanged(from, value); - } - } - - void colorValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Position field with key 39. - static const int positionPropertyKey = 39; - static const double positionInitialValue = 0; - double _position = positionInitialValue; - double get position => _position; - - /// Change the [_position] field value. - /// [positionChanged] will be invoked only if the field's value has changed. - set position(double value) { - if (_position == value) { - return; - } - double from = _position; - _position = value; - if (hasValidated) { - positionChanged(from, value); - } - } - - void positionChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is GradientStopBase) { - _colorValue = source._colorValue; - _position = source._position; - } - } -} diff --git a/lib/src/generated/shapes/paint/linear_gradient_base.dart b/lib/src/generated/shapes/paint/linear_gradient_base.dart deleted file mode 100644 index 9b27442..0000000 --- a/lib/src/generated/shapes/paint/linear_gradient_base.dart +++ /dev/null @@ -1,141 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/linear_gradient_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class LinearGradientBase extends ContainerComponent { - static const int typeKey = 22; - @override - int get coreType => LinearGradientBase.typeKey; - @override - Set get coreTypes => { - LinearGradientBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// StartX field with key 42. - static const int startXPropertyKey = 42; - static const double startXInitialValue = 0; - double _startX = startXInitialValue; - double get startX => _startX; - - /// Change the [_startX] field value. - /// [startXChanged] will be invoked only if the field's value has changed. - set startX(double value) { - if (_startX == value) { - return; - } - double from = _startX; - _startX = value; - if (hasValidated) { - startXChanged(from, value); - } - } - - void startXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// StartY field with key 33. - static const int startYPropertyKey = 33; - static const double startYInitialValue = 0; - double _startY = startYInitialValue; - double get startY => _startY; - - /// Change the [_startY] field value. - /// [startYChanged] will be invoked only if the field's value has changed. - set startY(double value) { - if (_startY == value) { - return; - } - double from = _startY; - _startY = value; - if (hasValidated) { - startYChanged(from, value); - } - } - - void startYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// EndX field with key 34. - static const int endXPropertyKey = 34; - static const double endXInitialValue = 0; - double _endX = endXInitialValue; - double get endX => _endX; - - /// Change the [_endX] field value. - /// [endXChanged] will be invoked only if the field's value has changed. - set endX(double value) { - if (_endX == value) { - return; - } - double from = _endX; - _endX = value; - if (hasValidated) { - endXChanged(from, value); - } - } - - void endXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// EndY field with key 35. - static const int endYPropertyKey = 35; - static const double endYInitialValue = 0; - double _endY = endYInitialValue; - double get endY => _endY; - - /// Change the [_endY] field value. - /// [endYChanged] will be invoked only if the field's value has changed. - set endY(double value) { - if (_endY == value) { - return; - } - double from = _endY; - _endY = value; - if (hasValidated) { - endYChanged(from, value); - } - } - - void endYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Opacity field with key 46. - static const int opacityPropertyKey = 46; - static const double opacityInitialValue = 1; - double _opacity = opacityInitialValue; - double get opacity => _opacity; - - /// Change the [_opacity] field value. - /// [opacityChanged] will be invoked only if the field's value has changed. - set opacity(double value) { - if (_opacity == value) { - return; - } - double from = _opacity; - _opacity = value; - if (hasValidated) { - opacityChanged(from, value); - } - } - - void opacityChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is LinearGradientBase) { - _startX = source._startX; - _startY = source._startY; - _endX = source._endX; - _endY = source._endY; - _opacity = source._opacity; - } - } -} diff --git a/lib/src/generated/shapes/paint/radial_gradient_base.dart b/lib/src/generated/shapes/paint/radial_gradient_base.dart deleted file mode 100644 index 2f14d7d..0000000 --- a/lib/src/generated/shapes/paint/radial_gradient_base.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/radial_gradient_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart'; - -abstract class RadialGradientBase extends LinearGradient { - static const int typeKey = 17; - @override - int get coreType => RadialGradientBase.typeKey; - @override - Set get coreTypes => { - RadialGradientBase.typeKey, - LinearGradientBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/paint/shape_paint_base.dart b/lib/src/generated/shapes/paint/shape_paint_base.dart deleted file mode 100644 index 6b03235..0000000 --- a/lib/src/generated/shapes/paint/shape_paint_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/shape_paint_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class ShapePaintBase extends ContainerComponent { - static const int typeKey = 21; - @override - int get coreType => ShapePaintBase.typeKey; - @override - Set get coreTypes => { - ShapePaintBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// IsVisible field with key 41. - static const int isVisiblePropertyKey = 41; - static const bool isVisibleInitialValue = true; - bool _isVisible = isVisibleInitialValue; - bool get isVisible => _isVisible; - - /// Change the [_isVisible] field value. - /// [isVisibleChanged] will be invoked only if the field's value has changed. - set isVisible(bool value) { - if (_isVisible == value) { - return; - } - bool from = _isVisible; - _isVisible = value; - if (hasValidated) { - isVisibleChanged(from, value); - } - } - - void isVisibleChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ShapePaintBase) { - _isVisible = source._isVisible; - } - } -} diff --git a/lib/src/generated/shapes/paint/solid_color_base.dart b/lib/src/generated/shapes/paint/solid_color_base.dart deleted file mode 100644 index d4da4ac..0000000 --- a/lib/src/generated/shapes/paint/solid_color_base.dart +++ /dev/null @@ -1,44 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/solid_color_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class SolidColorBase extends Component { - static const int typeKey = 18; - @override - int get coreType => SolidColorBase.typeKey; - @override - Set get coreTypes => {SolidColorBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// ColorValue field with key 37. - static const int colorValuePropertyKey = 37; - static const int colorValueInitialValue = 0xFF747474; - int _colorValue = colorValueInitialValue; - int get colorValue => _colorValue; - - /// Change the [_colorValue] field value. - /// [colorValueChanged] will be invoked only if the field's value has changed. - set colorValue(int value) { - if (_colorValue == value) { - return; - } - int from = _colorValue; - _colorValue = value; - if (hasValidated) { - colorValueChanged(from, value); - } - } - - void colorValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is SolidColorBase) { - _colorValue = source._colorValue; - } - } -} diff --git a/lib/src/generated/shapes/paint/stroke_base.dart b/lib/src/generated/shapes/paint/stroke_base.dart deleted file mode 100644 index 91a83c4..0000000 --- a/lib/src/generated/shapes/paint/stroke_base.dart +++ /dev/null @@ -1,121 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/stroke_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart'; - -abstract class StrokeBase extends ShapePaint { - static const int typeKey = 24; - @override - int get coreType => StrokeBase.typeKey; - @override - Set get coreTypes => { - StrokeBase.typeKey, - ShapePaintBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Thickness field with key 47. - static const int thicknessPropertyKey = 47; - static const double thicknessInitialValue = 1; - double _thickness = thicknessInitialValue; - double get thickness => _thickness; - - /// Change the [_thickness] field value. - /// [thicknessChanged] will be invoked only if the field's value has changed. - set thickness(double value) { - if (_thickness == value) { - return; - } - double from = _thickness; - _thickness = value; - if (hasValidated) { - thicknessChanged(from, value); - } - } - - void thicknessChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Cap field with key 48. - static const int capPropertyKey = 48; - static const int capInitialValue = 0; - int _cap = capInitialValue; - int get cap => _cap; - - /// Change the [_cap] field value. - /// [capChanged] will be invoked only if the field's value has changed. - set cap(int value) { - if (_cap == value) { - return; - } - int from = _cap; - _cap = value; - if (hasValidated) { - capChanged(from, value); - } - } - - void capChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Join field with key 49. - static const int joinPropertyKey = 49; - static const int joinInitialValue = 0; - int _join = joinInitialValue; - int get join => _join; - - /// Change the [_join] field value. - /// [joinChanged] will be invoked only if the field's value has changed. - set join(int value) { - if (_join == value) { - return; - } - int from = _join; - _join = value; - if (hasValidated) { - joinChanged(from, value); - } - } - - void joinChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// TransformAffectsStroke field with key 50. - static const int transformAffectsStrokePropertyKey = 50; - static const bool transformAffectsStrokeInitialValue = true; - bool _transformAffectsStroke = transformAffectsStrokeInitialValue; - bool get transformAffectsStroke => _transformAffectsStroke; - - /// Change the [_transformAffectsStroke] field value. - /// [transformAffectsStrokeChanged] will be invoked only if the field's value - /// has changed. - set transformAffectsStroke(bool value) { - if (_transformAffectsStroke == value) { - return; - } - bool from = _transformAffectsStroke; - _transformAffectsStroke = value; - if (hasValidated) { - transformAffectsStrokeChanged(from, value); - } - } - - void transformAffectsStrokeChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StrokeBase) { - _thickness = source._thickness; - _cap = source._cap; - _join = source._join; - _transformAffectsStroke = source._transformAffectsStroke; - } - } -} diff --git a/lib/src/generated/shapes/paint/trim_path_base.dart b/lib/src/generated/shapes/paint/trim_path_base.dart deleted file mode 100644 index 25034c4..0000000 --- a/lib/src/generated/shapes/paint/trim_path_base.dart +++ /dev/null @@ -1,113 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/paint/trim_path_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TrimPathBase extends Component { - static const int typeKey = 47; - @override - int get coreType => TrimPathBase.typeKey; - @override - Set get coreTypes => {TrimPathBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Start field with key 114. - static const int startPropertyKey = 114; - static const double startInitialValue = 0; - double _start = startInitialValue; - double get start => _start; - - /// Change the [_start] field value. - /// [startChanged] will be invoked only if the field's value has changed. - set start(double value) { - if (_start == value) { - return; - } - double from = _start; - _start = value; - if (hasValidated) { - startChanged(from, value); - } - } - - void startChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// End field with key 115. - static const int endPropertyKey = 115; - static const double endInitialValue = 0; - double _end = endInitialValue; - double get end => _end; - - /// Change the [_end] field value. - /// [endChanged] will be invoked only if the field's value has changed. - set end(double value) { - if (_end == value) { - return; - } - double from = _end; - _end = value; - if (hasValidated) { - endChanged(from, value); - } - } - - void endChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Offset field with key 116. - static const int offsetPropertyKey = 116; - static const double offsetInitialValue = 0; - double _offset = offsetInitialValue; - double get offset => _offset; - - /// Change the [_offset] field value. - /// [offsetChanged] will be invoked only if the field's value has changed. - set offset(double value) { - if (_offset == value) { - return; - } - double from = _offset; - _offset = value; - if (hasValidated) { - offsetChanged(from, value); - } - } - - void offsetChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ModeValue field with key 117. - static const int modeValuePropertyKey = 117; - static const int modeValueInitialValue = 0; - int _modeValue = modeValueInitialValue; - int get modeValue => _modeValue; - - /// Change the [_modeValue] field value. - /// [modeValueChanged] will be invoked only if the field's value has changed. - set modeValue(int value) { - if (_modeValue == value) { - return; - } - int from = _modeValue; - _modeValue = value; - if (hasValidated) { - modeValueChanged(from, value); - } - } - - void modeValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TrimPathBase) { - _start = source._start; - _end = source._end; - _offset = source._offset; - _modeValue = source._modeValue; - } - } -} diff --git a/lib/src/generated/shapes/parametric_path_base.dart b/lib/src/generated/shapes/parametric_path_base.dart deleted file mode 100644 index 99e908a..0000000 --- a/lib/src/generated/shapes/parametric_path_base.dart +++ /dev/null @@ -1,134 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/parametric_path_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/path.dart'; - -abstract class ParametricPathBase extends Path { - static const int typeKey = 15; - @override - int get coreType => ParametricPathBase.typeKey; - @override - Set get coreTypes => { - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Width field with key 20. - static const int widthPropertyKey = 20; - static const double widthInitialValue = 0; - double _width = widthInitialValue; - - /// Width of the parametric path. - double get width => _width; - - /// Change the [_width] field value. - /// [widthChanged] will be invoked only if the field's value has changed. - set width(double value) { - if (_width == value) { - return; - } - double from = _width; - _width = value; - if (hasValidated) { - widthChanged(from, value); - } - } - - void widthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Height field with key 21. - static const int heightPropertyKey = 21; - static const double heightInitialValue = 0; - double _height = heightInitialValue; - - /// Height of the parametric path. - double get height => _height; - - /// Change the [_height] field value. - /// [heightChanged] will be invoked only if the field's value has changed. - set height(double value) { - if (_height == value) { - return; - } - double from = _height; - _height = value; - if (hasValidated) { - heightChanged(from, value); - } - } - - void heightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 123. - static const int originXPropertyKey = 123; - static const double originXInitialValue = 0.5; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 124. - static const int originYPropertyKey = 124; - static const double originYInitialValue = 0.5; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ParametricPathBase) { - _width = source._width; - _height = source._height; - _originX = source._originX; - _originY = source._originY; - } - } -} diff --git a/lib/src/generated/shapes/path_base.dart b/lib/src/generated/shapes/path_base.dart deleted file mode 100644 index b249f2f..0000000 --- a/lib/src/generated/shapes/path_base.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/path_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/node.dart'; - -abstract class PathBase extends Node { - static const int typeKey = 12; - @override - int get coreType => PathBase.typeKey; - @override - Set get coreTypes => { - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PathFlags field with key 128. - static const int pathFlagsPropertyKey = 128; - static const int pathFlagsInitialValue = 0; - int _pathFlags = pathFlagsInitialValue; - int get pathFlags => _pathFlags; - - /// Change the [_pathFlags] field value. - /// [pathFlagsChanged] will be invoked only if the field's value has changed. - set pathFlags(int value) { - if (_pathFlags == value) { - return; - } - int from = _pathFlags; - _pathFlags = value; - if (hasValidated) { - pathFlagsChanged(from, value); - } - } - - void pathFlagsChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is PathBase) { - _pathFlags = source._pathFlags; - } - } -} diff --git a/lib/src/generated/shapes/path_composer_base.dart b/lib/src/generated/shapes/path_composer_base.dart deleted file mode 100644 index 42e3b19..0000000 --- a/lib/src/generated/shapes/path_composer_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -/// Core automatically generated -/// lib/src/generated/shapes/path_composer_base.dart. -/// Do not modify manually. - -import 'package:rive/src/rive_core/component.dart'; - -abstract class PathComposerBase extends Component { - static const int typeKey = 9; - @override - int get coreType => PathComposerBase.typeKey; - @override - Set get coreTypes => {PathComposerBase.typeKey, ComponentBase.typeKey}; -} diff --git a/lib/src/generated/shapes/path_vertex_base.dart b/lib/src/generated/shapes/path_vertex_base.dart deleted file mode 100644 index bd8b42b..0000000 --- a/lib/src/generated/shapes/path_vertex_base.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/path_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/shapes/vertex.dart'; - -abstract class PathVertexBase extends Vertex { - static const int typeKey = 14; - @override - int get coreType => PathVertexBase.typeKey; - @override - Set get coreTypes => { - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/points_path_base.dart b/lib/src/generated/shapes/points_path_base.dart deleted file mode 100644 index ae1f294..0000000 --- a/lib/src/generated/shapes/points_path_base.dart +++ /dev/null @@ -1,59 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/points_path_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/path.dart'; - -abstract class PointsPathBase extends Path { - static const int typeKey = 16; - @override - int get coreType => PointsPathBase.typeKey; - @override - Set get coreTypes => { - PointsPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// IsClosed field with key 32. - static const int isClosedPropertyKey = 32; - static const bool isClosedInitialValue = false; - bool _isClosed = isClosedInitialValue; - - /// If the path should close back on its first vertex. - @override - bool get isClosed => _isClosed; - - /// Change the [_isClosed] field value. - /// [isClosedChanged] will be invoked only if the field's value has changed. - set isClosed(bool value) { - if (_isClosed == value) { - return; - } - bool from = _isClosed; - _isClosed = value; - if (hasValidated) { - isClosedChanged(from, value); - } - } - - void isClosedChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is PointsPathBase) { - _isClosed = source._isClosed; - } - } -} diff --git a/lib/src/generated/shapes/polygon_base.dart b/lib/src/generated/shapes/polygon_base.dart deleted file mode 100644 index 0401380..0000000 --- a/lib/src/generated/shapes/polygon_base.dart +++ /dev/null @@ -1,86 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/polygon_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/parametric_path.dart'; - -abstract class PolygonBase extends ParametricPath { - static const int typeKey = 51; - @override - int get coreType => PolygonBase.typeKey; - @override - Set get coreTypes => { - PolygonBase.typeKey, - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Points field with key 125. - static const int pointsPropertyKey = 125; - static const int pointsInitialValue = 5; - int _points = pointsInitialValue; - - /// The number of points for the polygon. - int get points => _points; - - /// Change the [_points] field value. - /// [pointsChanged] will be invoked only if the field's value has changed. - set points(int value) { - if (_points == value) { - return; - } - int from = _points; - _points = value; - if (hasValidated) { - pointsChanged(from, value); - } - } - - void pointsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// CornerRadius field with key 126. - static const int cornerRadiusPropertyKey = 126; - static const double cornerRadiusInitialValue = 0; - double _cornerRadius = cornerRadiusInitialValue; - - /// The corner radius. - double get cornerRadius => _cornerRadius; - - /// Change the [_cornerRadius] field value. - /// [cornerRadiusChanged] will be invoked only if the field's value has - /// changed. - set cornerRadius(double value) { - if (_cornerRadius == value) { - return; - } - double from = _cornerRadius; - _cornerRadius = value; - if (hasValidated) { - cornerRadiusChanged(from, value); - } - } - - void cornerRadiusChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is PolygonBase) { - _points = source._points; - _cornerRadius = source._cornerRadius; - } - } -} diff --git a/lib/src/generated/shapes/rectangle_base.dart b/lib/src/generated/shapes/rectangle_base.dart deleted file mode 100644 index 5b458c7..0000000 --- a/lib/src/generated/shapes/rectangle_base.dart +++ /dev/null @@ -1,165 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/rectangle_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/parametric_path.dart'; - -abstract class RectangleBase extends ParametricPath { - static const int typeKey = 7; - @override - int get coreType => RectangleBase.typeKey; - @override - Set get coreTypes => { - RectangleBase.typeKey, - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// LinkCornerRadius field with key 164. - static const int linkCornerRadiusPropertyKey = 164; - static const bool linkCornerRadiusInitialValue = true; - bool _linkCornerRadius = linkCornerRadiusInitialValue; - - /// Whether the TL corner radius defines all the radiuses - bool get linkCornerRadius => _linkCornerRadius; - - /// Change the [_linkCornerRadius] field value. - /// [linkCornerRadiusChanged] will be invoked only if the field's value has - /// changed. - set linkCornerRadius(bool value) { - if (_linkCornerRadius == value) { - return; - } - bool from = _linkCornerRadius; - _linkCornerRadius = value; - if (hasValidated) { - linkCornerRadiusChanged(from, value); - } - } - - void linkCornerRadiusChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// CornerRadiusTL field with key 31. - static const int cornerRadiusTLPropertyKey = 31; - static const double cornerRadiusTLInitialValue = 0; - double _cornerRadiusTL = cornerRadiusTLInitialValue; - - /// Top left radius of the corners of this rectangle - double get cornerRadiusTL => _cornerRadiusTL; - - /// Change the [_cornerRadiusTL] field value. - /// [cornerRadiusTLChanged] will be invoked only if the field's value has - /// changed. - set cornerRadiusTL(double value) { - if (_cornerRadiusTL == value) { - return; - } - double from = _cornerRadiusTL; - _cornerRadiusTL = value; - if (hasValidated) { - cornerRadiusTLChanged(from, value); - } - } - - void cornerRadiusTLChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// CornerRadiusTR field with key 161. - static const int cornerRadiusTRPropertyKey = 161; - static const double cornerRadiusTRInitialValue = 0; - double _cornerRadiusTR = cornerRadiusTRInitialValue; - - /// Top right radius of the corners of this rectangle - double get cornerRadiusTR => _cornerRadiusTR; - - /// Change the [_cornerRadiusTR] field value. - /// [cornerRadiusTRChanged] will be invoked only if the field's value has - /// changed. - set cornerRadiusTR(double value) { - if (_cornerRadiusTR == value) { - return; - } - double from = _cornerRadiusTR; - _cornerRadiusTR = value; - if (hasValidated) { - cornerRadiusTRChanged(from, value); - } - } - - void cornerRadiusTRChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// CornerRadiusBL field with key 162. - static const int cornerRadiusBLPropertyKey = 162; - static const double cornerRadiusBLInitialValue = 0; - double _cornerRadiusBL = cornerRadiusBLInitialValue; - - /// Bottom left radius of the corners of this rectangle - double get cornerRadiusBL => _cornerRadiusBL; - - /// Change the [_cornerRadiusBL] field value. - /// [cornerRadiusBLChanged] will be invoked only if the field's value has - /// changed. - set cornerRadiusBL(double value) { - if (_cornerRadiusBL == value) { - return; - } - double from = _cornerRadiusBL; - _cornerRadiusBL = value; - if (hasValidated) { - cornerRadiusBLChanged(from, value); - } - } - - void cornerRadiusBLChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// CornerRadiusBR field with key 163. - static const int cornerRadiusBRPropertyKey = 163; - static const double cornerRadiusBRInitialValue = 0; - double _cornerRadiusBR = cornerRadiusBRInitialValue; - - /// Bottom right radius of the corners of this rectangle - double get cornerRadiusBR => _cornerRadiusBR; - - /// Change the [_cornerRadiusBR] field value. - /// [cornerRadiusBRChanged] will be invoked only if the field's value has - /// changed. - set cornerRadiusBR(double value) { - if (_cornerRadiusBR == value) { - return; - } - double from = _cornerRadiusBR; - _cornerRadiusBR = value; - if (hasValidated) { - cornerRadiusBRChanged(from, value); - } - } - - void cornerRadiusBRChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is RectangleBase) { - _linkCornerRadius = source._linkCornerRadius; - _cornerRadiusTL = source._cornerRadiusTL; - _cornerRadiusTR = source._cornerRadiusTR; - _cornerRadiusBL = source._cornerRadiusBL; - _cornerRadiusBR = source._cornerRadiusBR; - } - } -} diff --git a/lib/src/generated/shapes/shape_base.dart b/lib/src/generated/shapes/shape_base.dart deleted file mode 100644 index 5095495..0000000 --- a/lib/src/generated/shapes/shape_base.dart +++ /dev/null @@ -1,25 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/shape_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/drawable.dart'; - -abstract class ShapeBase extends Drawable { - static const int typeKey = 3; - @override - int get coreType => ShapeBase.typeKey; - @override - Set get coreTypes => { - ShapeBase.typeKey, - DrawableBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/star_base.dart b/lib/src/generated/shapes/star_base.dart deleted file mode 100644 index 10ead6b..0000000 --- a/lib/src/generated/shapes/star_base.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/star_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/shapes/parametric_path_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/polygon.dart'; - -abstract class StarBase extends Polygon { - static const int typeKey = 52; - @override - int get coreType => StarBase.typeKey; - @override - Set get coreTypes => { - StarBase.typeKey, - PolygonBase.typeKey, - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// InnerRadius field with key 127. - static const int innerRadiusPropertyKey = 127; - static const double innerRadiusInitialValue = 0.5; - double _innerRadius = innerRadiusInitialValue; - - /// Percentage of width/height to project inner points of the star. - double get innerRadius => _innerRadius; - - /// Change the [_innerRadius] field value. - /// [innerRadiusChanged] will be invoked only if the field's value has - /// changed. - set innerRadius(double value) { - if (_innerRadius == value) { - return; - } - double from = _innerRadius; - _innerRadius = value; - if (hasValidated) { - innerRadiusChanged(from, value); - } - } - - void innerRadiusChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StarBase) { - _innerRadius = source._innerRadius; - } - } -} diff --git a/lib/src/generated/shapes/straight_vertex_base.dart b/lib/src/generated/shapes/straight_vertex_base.dart deleted file mode 100644 index 7f3b592..0000000 --- a/lib/src/generated/shapes/straight_vertex_base.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Core automatically generated -// lib/src/generated/shapes/straight_vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; - -abstract class StraightVertexBase extends PathVertex { - static const int typeKey = 5; - @override - int get coreType => StraightVertexBase.typeKey; - @override - Set get coreTypes => { - StraightVertexBase.typeKey, - PathVertexBase.typeKey, - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Radius field with key 26. - static const int radiusPropertyKey = 26; - static const double radiusInitialValue = 0; - double _radius = radiusInitialValue; - - /// Radius of the vertex - double get radius => _radius; - - /// Change the [_radius] field value. - /// [radiusChanged] will be invoked only if the field's value has changed. - set radius(double value) { - if (_radius == value) { - return; - } - double from = _radius; - _radius = value; - if (hasValidated) { - radiusChanged(from, value); - } - } - - void radiusChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is StraightVertexBase) { - _radius = source._radius; - } - } -} diff --git a/lib/src/generated/shapes/triangle_base.dart b/lib/src/generated/shapes/triangle_base.dart deleted file mode 100644 index 61ef027..0000000 --- a/lib/src/generated/shapes/triangle_base.dart +++ /dev/null @@ -1,27 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/triangle_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/shapes/parametric_path.dart'; - -abstract class TriangleBase extends ParametricPath { - static const int typeKey = 8; - @override - int get coreType => TriangleBase.typeKey; - @override - Set get coreTypes => { - TriangleBase.typeKey, - ParametricPathBase.typeKey, - PathBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/shapes/vertex_base.dart b/lib/src/generated/shapes/vertex_base.dart deleted file mode 100644 index 58fb327..0000000 --- a/lib/src/generated/shapes/vertex_base.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Core automatically generated lib/src/generated/shapes/vertex_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class VertexBase extends ContainerComponent { - static const int typeKey = 107; - @override - int get coreType => VertexBase.typeKey; - @override - Set get coreTypes => { - VertexBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// X field with key 24. - static const int xPropertyKey = 24; - static const double xInitialValue = 0; - double _x = xInitialValue; - - /// X value for the translation of the vertex. - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 25. - static const int yPropertyKey = 25; - static const double yInitialValue = 0; - double _y = yInitialValue; - - /// Y value for the translation of the vertex. - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is VertexBase) { - _x = source._x; - _y = source._y; - } - } -} diff --git a/lib/src/generated/solo_base.dart b/lib/src/generated/solo_base.dart deleted file mode 100644 index 1ef44bb..0000000 --- a/lib/src/generated/solo_base.dart +++ /dev/null @@ -1,57 +0,0 @@ -// Core automatically generated lib/src/generated/solo_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/node.dart'; - -abstract class SoloBase extends Node { - static const int typeKey = 147; - @override - int get coreType => SoloBase.typeKey; - @override - Set get coreTypes => { - SoloBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ActiveComponentId field with key 296. - static const int activeComponentIdPropertyKey = 296; - static const int activeComponentIdInitialValue = 0; - int _activeComponentId = activeComponentIdInitialValue; - - /// Identifier of the active child in the solo set. - int get activeComponentId => _activeComponentId; - - /// Change the [_activeComponentId] field value. - /// [activeComponentIdChanged] will be invoked only if the field's value has - /// changed. - set activeComponentId(int value) { - if (_activeComponentId == value) { - return; - } - int from = _activeComponentId; - _activeComponentId = value; - if (hasValidated) { - activeComponentIdChanged(from, value); - } - } - - void activeComponentIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is SoloBase) { - _activeComponentId = source._activeComponentId; - } - } -} diff --git a/lib/src/generated/text/text_base.dart b/lib/src/generated/text/text_base.dart deleted file mode 100644 index 2e547e0..0000000 --- a/lib/src/generated/text/text_base.dart +++ /dev/null @@ -1,329 +0,0 @@ -// Core automatically generated lib/src/generated/text/text_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/drawable.dart'; - -abstract class TextBase extends Drawable { - static const int typeKey = 134; - @override - int get coreType => TextBase.typeKey; - @override - Set get coreTypes => { - TextBase.typeKey, - DrawableBase.typeKey, - NodeBase.typeKey, - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AlignValue field with key 281. - static const int alignValuePropertyKey = 281; - static const int alignValueInitialValue = 0; - int _alignValue = alignValueInitialValue; - int get alignValue => _alignValue; - - /// Change the [_alignValue] field value. - /// [alignValueChanged] will be invoked only if the field's value has changed. - set alignValue(int value) { - if (_alignValue == value) { - return; - } - int from = _alignValue; - _alignValue = value; - if (hasValidated) { - alignValueChanged(from, value); - } - } - - void alignValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// SizingValue field with key 284. - static const int sizingValuePropertyKey = 284; - static const int sizingValueInitialValue = 0; - int _sizingValue = sizingValueInitialValue; - int get sizingValue => _sizingValue; - - /// Change the [_sizingValue] field value. - /// [sizingValueChanged] will be invoked only if the field's value has - /// changed. - set sizingValue(int value) { - if (_sizingValue == value) { - return; - } - int from = _sizingValue; - _sizingValue = value; - if (hasValidated) { - sizingValueChanged(from, value); - } - } - - void sizingValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OverflowValue field with key 287. - static const int overflowValuePropertyKey = 287; - static const int overflowValueInitialValue = 0; - int _overflowValue = overflowValueInitialValue; - - /// One of visible, hidden, clipped, ellipsis, fit. - int get overflowValue => _overflowValue; - - /// Change the [_overflowValue] field value. - /// [overflowValueChanged] will be invoked only if the field's value has - /// changed. - set overflowValue(int value) { - if (_overflowValue == value) { - return; - } - int from = _overflowValue; - _overflowValue = value; - if (hasValidated) { - overflowValueChanged(from, value); - } - } - - void overflowValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Width field with key 285. - static const int widthPropertyKey = 285; - static const double widthInitialValue = 0; - double _width = widthInitialValue; - - /// Width of the text object. - double get width => _width; - - /// Change the [_width] field value. - /// [widthChanged] will be invoked only if the field's value has changed. - set width(double value) { - if (_width == value) { - return; - } - double from = _width; - _width = value; - if (hasValidated) { - widthChanged(from, value); - } - } - - void widthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Height field with key 286. - static const int heightPropertyKey = 286; - static const double heightInitialValue = 0; - double _height = heightInitialValue; - - /// Height of the text object. - double get height => _height; - - /// Change the [_height] field value. - /// [heightChanged] will be invoked only if the field's value has changed. - set height(double value) { - if (_height == value) { - return; - } - double from = _height; - _height = value; - if (hasValidated) { - heightChanged(from, value); - } - } - - void heightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 366. - static const int originXPropertyKey = 366; - static const double originXInitialValue = 0.0; - double _originX = originXInitialValue; - - /// Origin x in normalized coordinates (0.5 = center, 0 = left, 1 = right). - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 367. - static const int originYPropertyKey = 367; - static const double originYInitialValue = 0.0; - double _originY = originYInitialValue; - - /// Origin y in normalized coordinates (0.5 = center, 0 = top, 1 = bottom). - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ParagraphSpacing field with key 371. - static const int paragraphSpacingPropertyKey = 371; - static const double paragraphSpacingInitialValue = 0.0; - double _paragraphSpacing = paragraphSpacingInitialValue; - double get paragraphSpacing => _paragraphSpacing; - - /// Change the [_paragraphSpacing] field value. - /// [paragraphSpacingChanged] will be invoked only if the field's value has - /// changed. - set paragraphSpacing(double value) { - if (_paragraphSpacing == value) { - return; - } - double from = _paragraphSpacing; - _paragraphSpacing = value; - if (hasValidated) { - paragraphSpacingChanged(from, value); - } - } - - void paragraphSpacingChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginValue field with key 377. - static const int originValuePropertyKey = 377; - static const int originValueInitialValue = 0; - int _originValue = originValueInitialValue; - - /// Logical starting location of origin. - int get originValue => _originValue; - - /// Change the [_originValue] field value. - /// [originValueChanged] will be invoked only if the field's value has - /// changed. - set originValue(int value) { - if (_originValue == value) { - return; - } - int from = _originValue; - _originValue = value; - if (hasValidated) { - originValueChanged(from, value); - } - } - - void originValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// WrapValue field with key 683. - static const int wrapValuePropertyKey = 683; - static const int wrapValueInitialValue = 0; - int _wrapValue = wrapValueInitialValue; - - /// One of wrap, noWrap - int get wrapValue => _wrapValue; - - /// Change the [_wrapValue] field value. - /// [wrapValueChanged] will be invoked only if the field's value has changed. - set wrapValue(int value) { - if (_wrapValue == value) { - return; - } - int from = _wrapValue; - _wrapValue = value; - if (hasValidated) { - wrapValueChanged(from, value); - } - } - - void wrapValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// VerticalAlignValue field with key 685. - static const int verticalAlignValuePropertyKey = 685; - static const int verticalAlignValueInitialValue = 0; - int _verticalAlignValue = verticalAlignValueInitialValue; - int get verticalAlignValue => _verticalAlignValue; - - /// Change the [_verticalAlignValue] field value. - /// [verticalAlignValueChanged] will be invoked only if the field's value has - /// changed. - set verticalAlignValue(int value) { - if (_verticalAlignValue == value) { - return; - } - int from = _verticalAlignValue; - _verticalAlignValue = value; - if (hasValidated) { - verticalAlignValueChanged(from, value); - } - } - - void verticalAlignValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// FitFromBaseline field with key 703. - static const int fitFromBaselinePropertyKey = 703; - static const bool fitFromBaselineInitialValue = true; - bool _fitFromBaseline = fitFromBaselineInitialValue; - bool get fitFromBaseline => _fitFromBaseline; - - /// Change the [_fitFromBaseline] field value. - /// [fitFromBaselineChanged] will be invoked only if the field's value has - /// changed. - set fitFromBaseline(bool value) { - if (_fitFromBaseline == value) { - return; - } - bool from = _fitFromBaseline; - _fitFromBaseline = value; - if (hasValidated) { - fitFromBaselineChanged(from, value); - } - } - - void fitFromBaselineChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextBase) { - _alignValue = source._alignValue; - _sizingValue = source._sizingValue; - _overflowValue = source._overflowValue; - _width = source._width; - _height = source._height; - _originX = source._originX; - _originY = source._originY; - _paragraphSpacing = source._paragraphSpacing; - _originValue = source._originValue; - _wrapValue = source._wrapValue; - _verticalAlignValue = source._verticalAlignValue; - _fitFromBaseline = source._fitFromBaseline; - } - } -} diff --git a/lib/src/generated/text/text_modifier_base.dart b/lib/src/generated/text/text_modifier_base.dart deleted file mode 100644 index 63780ed..0000000 --- a/lib/src/generated/text/text_modifier_base.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Core automatically generated lib/src/generated/text/text_modifier_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/component.dart'; - -abstract class TextModifierBase extends Component { - static const int typeKey = 160; - @override - int get coreType => TextModifierBase.typeKey; - @override - Set get coreTypes => {TextModifierBase.typeKey, ComponentBase.typeKey}; -} diff --git a/lib/src/generated/text/text_modifier_group_base.dart b/lib/src/generated/text/text_modifier_group_base.dart deleted file mode 100644 index 56bfbbc..0000000 --- a/lib/src/generated/text/text_modifier_group_base.dart +++ /dev/null @@ -1,234 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_modifier_group_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class TextModifierGroupBase extends ContainerComponent { - static const int typeKey = 159; - @override - int get coreType => TextModifierGroupBase.typeKey; - @override - Set get coreTypes => { - TextModifierGroupBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ModifierFlags field with key 335. - static const int modifierFlagsPropertyKey = 335; - static const int modifierFlagsInitialValue = 0; - int _modifierFlags = modifierFlagsInitialValue; - int get modifierFlags => _modifierFlags; - - /// Change the [_modifierFlags] field value. - /// [modifierFlagsChanged] will be invoked only if the field's value has - /// changed. - set modifierFlags(int value) { - if (_modifierFlags == value) { - return; - } - int from = _modifierFlags; - _modifierFlags = value; - if (hasValidated) { - modifierFlagsChanged(from, value); - } - } - - void modifierFlagsChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// OriginX field with key 328. - static const int originXPropertyKey = 328; - static const double originXInitialValue = 0; - double _originX = originXInitialValue; - double get originX => _originX; - - /// Change the [_originX] field value. - /// [originXChanged] will be invoked only if the field's value has changed. - set originX(double value) { - if (_originX == value) { - return; - } - double from = _originX; - _originX = value; - if (hasValidated) { - originXChanged(from, value); - } - } - - void originXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// OriginY field with key 329. - static const int originYPropertyKey = 329; - static const double originYInitialValue = 0; - double _originY = originYInitialValue; - double get originY => _originY; - - /// Change the [_originY] field value. - /// [originYChanged] will be invoked only if the field's value has changed. - set originY(double value) { - if (_originY == value) { - return; - } - double from = _originY; - _originY = value; - if (hasValidated) { - originYChanged(from, value); - } - } - - void originYChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Opacity field with key 324. - static const int opacityPropertyKey = 324; - static const double opacityInitialValue = 1; - double _opacity = opacityInitialValue; - double get opacity => _opacity; - - /// Change the [_opacity] field value. - /// [opacityChanged] will be invoked only if the field's value has changed. - set opacity(double value) { - if (_opacity == value) { - return; - } - double from = _opacity; - _opacity = value; - if (hasValidated) { - opacityChanged(from, value); - } - } - - void opacityChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// X field with key 322. - static const int xPropertyKey = 322; - static const double xInitialValue = 0; - double _x = xInitialValue; - double get x => _x; - - /// Change the [_x] field value. - /// [xChanged] will be invoked only if the field's value has changed. - set x(double value) { - if (_x == value) { - return; - } - double from = _x; - _x = value; - if (hasValidated) { - xChanged(from, value); - } - } - - void xChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Y field with key 323. - static const int yPropertyKey = 323; - static const double yInitialValue = 0; - double _y = yInitialValue; - double get y => _y; - - /// Change the [_y] field value. - /// [yChanged] will be invoked only if the field's value has changed. - set y(double value) { - if (_y == value) { - return; - } - double from = _y; - _y = value; - if (hasValidated) { - yChanged(from, value); - } - } - - void yChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Rotation field with key 332. - static const int rotationPropertyKey = 332; - static const double rotationInitialValue = 0; - double _rotation = rotationInitialValue; - double get rotation => _rotation; - - /// Change the [_rotation] field value. - /// [rotationChanged] will be invoked only if the field's value has changed. - set rotation(double value) { - if (_rotation == value) { - return; - } - double from = _rotation; - _rotation = value; - if (hasValidated) { - rotationChanged(from, value); - } - } - - void rotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ScaleX field with key 330. - static const int scaleXPropertyKey = 330; - static const double scaleXInitialValue = 1; - double _scaleX = scaleXInitialValue; - double get scaleX => _scaleX; - - /// Change the [_scaleX] field value. - /// [scaleXChanged] will be invoked only if the field's value has changed. - set scaleX(double value) { - if (_scaleX == value) { - return; - } - double from = _scaleX; - _scaleX = value; - if (hasValidated) { - scaleXChanged(from, value); - } - } - - void scaleXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ScaleY field with key 331. - static const int scaleYPropertyKey = 331; - static const double scaleYInitialValue = 1; - double _scaleY = scaleYInitialValue; - double get scaleY => _scaleY; - - /// Change the [_scaleY] field value. - /// [scaleYChanged] will be invoked only if the field's value has changed. - set scaleY(double value) { - if (_scaleY == value) { - return; - } - double from = _scaleY; - _scaleY = value; - if (hasValidated) { - scaleYChanged(from, value); - } - } - - void scaleYChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextModifierGroupBase) { - _modifierFlags = source._modifierFlags; - _originX = source._originX; - _originY = source._originY; - _opacity = source._opacity; - _x = source._x; - _y = source._y; - _rotation = source._rotation; - _scaleX = source._scaleX; - _scaleY = source._scaleY; - } - } -} diff --git a/lib/src/generated/text/text_modifier_range_base.dart b/lib/src/generated/text/text_modifier_range_base.dart deleted file mode 100644 index 6f26871..0000000 --- a/lib/src/generated/text/text_modifier_range_base.dart +++ /dev/null @@ -1,282 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_modifier_range_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class TextModifierRangeBase extends ContainerComponent { - static const int typeKey = 158; - @override - int get coreType => TextModifierRangeBase.typeKey; - @override - Set get coreTypes => { - TextModifierRangeBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ModifyFrom field with key 327. - static const int modifyFromPropertyKey = 327; - static const double modifyFromInitialValue = 0; - double _modifyFrom = modifyFromInitialValue; - double get modifyFrom => _modifyFrom; - - /// Change the [_modifyFrom] field value. - /// [modifyFromChanged] will be invoked only if the field's value has changed. - set modifyFrom(double value) { - if (_modifyFrom == value) { - return; - } - double from = _modifyFrom; - _modifyFrom = value; - if (hasValidated) { - modifyFromChanged(from, value); - } - } - - void modifyFromChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ModifyTo field with key 336. - static const int modifyToPropertyKey = 336; - static const double modifyToInitialValue = 1; - double _modifyTo = modifyToInitialValue; - double get modifyTo => _modifyTo; - - /// Change the [_modifyTo] field value. - /// [modifyToChanged] will be invoked only if the field's value has changed. - set modifyTo(double value) { - if (_modifyTo == value) { - return; - } - double from = _modifyTo; - _modifyTo = value; - if (hasValidated) { - modifyToChanged(from, value); - } - } - - void modifyToChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Strength field with key 334. - static const int strengthPropertyKey = 334; - static const double strengthInitialValue = 1; - double _strength = strengthInitialValue; - double get strength => _strength; - - /// Change the [_strength] field value. - /// [strengthChanged] will be invoked only if the field's value has changed. - set strength(double value) { - if (_strength == value) { - return; - } - double from = _strength; - _strength = value; - if (hasValidated) { - strengthChanged(from, value); - } - } - - void strengthChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// UnitsValue field with key 316. - static const int unitsValuePropertyKey = 316; - static const int unitsValueInitialValue = 0; - int _unitsValue = unitsValueInitialValue; - int get unitsValue => _unitsValue; - - /// Change the [_unitsValue] field value. - /// [unitsValueChanged] will be invoked only if the field's value has changed. - set unitsValue(int value) { - if (_unitsValue == value) { - return; - } - int from = _unitsValue; - _unitsValue = value; - if (hasValidated) { - unitsValueChanged(from, value); - } - } - - void unitsValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// TypeValue field with key 325. - static const int typeValuePropertyKey = 325; - static const int typeValueInitialValue = 0; - int _typeValue = typeValueInitialValue; - int get typeValue => _typeValue; - - /// Change the [_typeValue] field value. - /// [typeValueChanged] will be invoked only if the field's value has changed. - set typeValue(int value) { - if (_typeValue == value) { - return; - } - int from = _typeValue; - _typeValue = value; - if (hasValidated) { - typeValueChanged(from, value); - } - } - - void typeValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ModeValue field with key 326. - static const int modeValuePropertyKey = 326; - static const int modeValueInitialValue = 0; - int _modeValue = modeValueInitialValue; - int get modeValue => _modeValue; - - /// Change the [_modeValue] field value. - /// [modeValueChanged] will be invoked only if the field's value has changed. - set modeValue(int value) { - if (_modeValue == value) { - return; - } - int from = _modeValue; - _modeValue = value; - if (hasValidated) { - modeValueChanged(from, value); - } - } - - void modeValueChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Clamp field with key 333. - static const int clampPropertyKey = 333; - static const bool clampInitialValue = false; - bool _clamp = clampInitialValue; - bool get clamp => _clamp; - - /// Change the [_clamp] field value. - /// [clampChanged] will be invoked only if the field's value has changed. - set clamp(bool value) { - if (_clamp == value) { - return; - } - bool from = _clamp; - _clamp = value; - if (hasValidated) { - clampChanged(from, value); - } - } - - void clampChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// FalloffFrom field with key 317. - static const int falloffFromPropertyKey = 317; - static const double falloffFromInitialValue = 0; - double _falloffFrom = falloffFromInitialValue; - double get falloffFrom => _falloffFrom; - - /// Change the [_falloffFrom] field value. - /// [falloffFromChanged] will be invoked only if the field's value has - /// changed. - set falloffFrom(double value) { - if (_falloffFrom == value) { - return; - } - double from = _falloffFrom; - _falloffFrom = value; - if (hasValidated) { - falloffFromChanged(from, value); - } - } - - void falloffFromChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// FalloffTo field with key 318. - static const int falloffToPropertyKey = 318; - static const double falloffToInitialValue = 1; - double _falloffTo = falloffToInitialValue; - double get falloffTo => _falloffTo; - - /// Change the [_falloffTo] field value. - /// [falloffToChanged] will be invoked only if the field's value has changed. - set falloffTo(double value) { - if (_falloffTo == value) { - return; - } - double from = _falloffTo; - _falloffTo = value; - if (hasValidated) { - falloffToChanged(from, value); - } - } - - void falloffToChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// Offset field with key 319. - static const int offsetPropertyKey = 319; - static const double offsetInitialValue = 0; - double _offset = offsetInitialValue; - double get offset => _offset; - - /// Change the [_offset] field value. - /// [offsetChanged] will be invoked only if the field's value has changed. - set offset(double value) { - if (_offset == value) { - return; - } - double from = _offset; - _offset = value; - if (hasValidated) { - offsetChanged(from, value); - } - } - - void offsetChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// RunId field with key 378. - static const int runIdPropertyKey = 378; - static const int runIdInitialValue = -1; - int _runId = runIdInitialValue; - - /// Identifier used to which run should be targeted. - int get runId => _runId; - - /// Change the [_runId] field value. - /// [runIdChanged] will be invoked only if the field's value has changed. - set runId(int value) { - if (_runId == value) { - return; - } - int from = _runId; - _runId = value; - if (hasValidated) { - runIdChanged(from, value); - } - } - - void runIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextModifierRangeBase) { - _modifyFrom = source._modifyFrom; - _modifyTo = source._modifyTo; - _strength = source._strength; - _unitsValue = source._unitsValue; - _typeValue = source._typeValue; - _modeValue = source._modeValue; - _clamp = source._clamp; - _falloffFrom = source._falloffFrom; - _falloffTo = source._falloffTo; - _offset = source._offset; - _runId = source._runId; - } - } -} diff --git a/lib/src/generated/text/text_shape_modifier_base.dart b/lib/src/generated/text/text_shape_modifier_base.dart deleted file mode 100644 index 54d46ab..0000000 --- a/lib/src/generated/text/text_shape_modifier_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_shape_modifier_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/text/text_modifier.dart'; - -abstract class TextShapeModifierBase extends TextModifier { - static const int typeKey = 161; - @override - int get coreType => TextShapeModifierBase.typeKey; - @override - Set get coreTypes => { - TextShapeModifierBase.typeKey, - TextModifierBase.typeKey, - ComponentBase.typeKey - }; -} diff --git a/lib/src/generated/text/text_style_axis_base.dart b/lib/src/generated/text/text_style_axis_base.dart deleted file mode 100644 index 13ba4a4..0000000 --- a/lib/src/generated/text/text_style_axis_base.dart +++ /dev/null @@ -1,67 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_style_axis_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TextStyleAxisBase extends Component { - static const int typeKey = 144; - @override - int get coreType => TextStyleAxisBase.typeKey; - @override - Set get coreTypes => {TextStyleAxisBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Tag field with key 289. - static const int tagPropertyKey = 289; - static const int tagInitialValue = 0; - int _tag = tagInitialValue; - int get tag => _tag; - - /// Change the [_tag] field value. - /// [tagChanged] will be invoked only if the field's value has changed. - set tag(int value) { - if (_tag == value) { - return; - } - int from = _tag; - _tag = value; - if (hasValidated) { - tagChanged(from, value); - } - } - - void tagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AxisValue field with key 288. - static const int axisValuePropertyKey = 288; - static const double axisValueInitialValue = 0; - double _axisValue = axisValueInitialValue; - double get axisValue => _axisValue; - - /// Change the [_axisValue] field value. - /// [axisValueChanged] will be invoked only if the field's value has changed. - set axisValue(double value) { - if (_axisValue == value) { - return; - } - double from = _axisValue; - _axisValue = value; - if (hasValidated) { - axisValueChanged(from, value); - } - } - - void axisValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextStyleAxisBase) { - _tag = source._tag; - _axisValue = source._axisValue; - } - } -} diff --git a/lib/src/generated/text/text_style_base.dart b/lib/src/generated/text/text_style_base.dart deleted file mode 100644 index 4a2843a..0000000 --- a/lib/src/generated/text/text_style_base.dart +++ /dev/null @@ -1,119 +0,0 @@ -// Core automatically generated lib/src/generated/text/text_style_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class TextStyleBase extends ContainerComponent { - static const int typeKey = 137; - @override - int get coreType => TextStyleBase.typeKey; - @override - Set get coreTypes => { - TextStyleBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// FontSize field with key 274. - static const int fontSizePropertyKey = 274; - static const double fontSizeInitialValue = 12; - double _fontSize = fontSizeInitialValue; - double get fontSize => _fontSize; - - /// Change the [_fontSize] field value. - /// [fontSizeChanged] will be invoked only if the field's value has changed. - set fontSize(double value) { - if (_fontSize == value) { - return; - } - double from = _fontSize; - _fontSize = value; - if (hasValidated) { - fontSizeChanged(from, value); - } - } - - void fontSizeChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// LineHeight field with key 370. - static const int lineHeightPropertyKey = 370; - static const double lineHeightInitialValue = -1.0; - double _lineHeight = lineHeightInitialValue; - double get lineHeight => _lineHeight; - - /// Change the [_lineHeight] field value. - /// [lineHeightChanged] will be invoked only if the field's value has changed. - set lineHeight(double value) { - if (_lineHeight == value) { - return; - } - double from = _lineHeight; - _lineHeight = value; - if (hasValidated) { - lineHeightChanged(from, value); - } - } - - void lineHeightChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// LetterSpacing field with key 390. - static const int letterSpacingPropertyKey = 390; - static const double letterSpacingInitialValue = 0.0; - double _letterSpacing = letterSpacingInitialValue; - double get letterSpacing => _letterSpacing; - - /// Change the [_letterSpacing] field value. - /// [letterSpacingChanged] will be invoked only if the field's value has - /// changed. - set letterSpacing(double value) { - if (_letterSpacing == value) { - return; - } - double from = _letterSpacing; - _letterSpacing = value; - if (hasValidated) { - letterSpacingChanged(from, value); - } - } - - void letterSpacingChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// FontAssetId field with key 279. - static const int fontAssetIdPropertyKey = 279; - static const int fontAssetIdInitialValue = -1; - int _fontAssetId = fontAssetIdInitialValue; - int get fontAssetId => _fontAssetId; - - /// Change the [_fontAssetId] field value. - /// [fontAssetIdChanged] will be invoked only if the field's value has - /// changed. - set fontAssetId(int value) { - if (_fontAssetId == value) { - return; - } - int from = _fontAssetId; - _fontAssetId = value; - if (hasValidated) { - fontAssetIdChanged(from, value); - } - } - - void fontAssetIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextStyleBase) { - _fontSize = source._fontSize; - _lineHeight = source._lineHeight; - _letterSpacing = source._letterSpacing; - _fontAssetId = source._fontAssetId; - } - } -} diff --git a/lib/src/generated/text/text_style_feature_base.dart b/lib/src/generated/text/text_style_feature_base.dart deleted file mode 100644 index c434bd2..0000000 --- a/lib/src/generated/text/text_style_feature_base.dart +++ /dev/null @@ -1,69 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_style_feature_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TextStyleFeatureBase extends Component { - static const int typeKey = 164; - @override - int get coreType => TextStyleFeatureBase.typeKey; - @override - Set get coreTypes => - {TextStyleFeatureBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Tag field with key 356. - static const int tagPropertyKey = 356; - static const int tagInitialValue = 0; - int _tag = tagInitialValue; - int get tag => _tag; - - /// Change the [_tag] field value. - /// [tagChanged] will be invoked only if the field's value has changed. - set tag(int value) { - if (_tag == value) { - return; - } - int from = _tag; - _tag = value; - if (hasValidated) { - tagChanged(from, value); - } - } - - void tagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// FeatureValue field with key 357. - static const int featureValuePropertyKey = 357; - static const int featureValueInitialValue = 1; - int _featureValue = featureValueInitialValue; - int get featureValue => _featureValue; - - /// Change the [_featureValue] field value. - /// [featureValueChanged] will be invoked only if the field's value has - /// changed. - set featureValue(int value) { - if (_featureValue == value) { - return; - } - int from = _featureValue; - _featureValue = value; - if (hasValidated) { - featureValueChanged(from, value); - } - } - - void featureValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextStyleFeatureBase) { - _tag = source._tag; - _featureValue = source._featureValue; - } - } -} diff --git a/lib/src/generated/text/text_value_run_base.dart b/lib/src/generated/text/text_value_run_base.dart deleted file mode 100644 index 137d4ab..0000000 --- a/lib/src/generated/text/text_value_run_base.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_value_run_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class TextValueRunBase extends Component { - static const int typeKey = 135; - @override - int get coreType => TextValueRunBase.typeKey; - @override - Set get coreTypes => {TextValueRunBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// StyleId field with key 272. - static const int styleIdPropertyKey = 272; - static const int styleIdInitialValue = -1; - int _styleId = styleIdInitialValue; - - /// The id of the style to be applied to this run. - int get styleId => _styleId; - - /// Change the [_styleId] field value. - /// [styleIdChanged] will be invoked only if the field's value has changed. - set styleId(int value) { - if (_styleId == value) { - return; - } - int from = _styleId; - _styleId = value; - if (hasValidated) { - styleIdChanged(from, value); - } - } - - void styleIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// Text field with key 268. - static const int textPropertyKey = 268; - static const String textInitialValue = ''; - String _text = textInitialValue; - - /// The text string value. - String get text => _text; - - /// Change the [_text] field value. - /// [textChanged] will be invoked only if the field's value has changed. - set text(String value) { - if (_text == value) { - return; - } - String from = _text; - _text = value; - if (hasValidated) { - textChanged(from, value); - } - } - - void textChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextValueRunBase) { - _styleId = source._styleId; - _text = source._text; - } - } -} diff --git a/lib/src/generated/text/text_variation_modifier_base.dart b/lib/src/generated/text/text_variation_modifier_base.dart deleted file mode 100644 index b1f4254..0000000 --- a/lib/src/generated/text/text_variation_modifier_base.dart +++ /dev/null @@ -1,74 +0,0 @@ -// Core automatically generated -// lib/src/generated/text/text_variation_modifier_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/text/text_modifier_base.dart'; -import 'package:rive/src/rive_core/text/text_shape_modifier.dart'; - -abstract class TextVariationModifierBase extends TextShapeModifier { - static const int typeKey = 162; - @override - int get coreType => TextVariationModifierBase.typeKey; - @override - Set get coreTypes => { - TextVariationModifierBase.typeKey, - TextShapeModifierBase.typeKey, - TextModifierBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// AxisTag field with key 320. - static const int axisTagPropertyKey = 320; - static const int axisTagInitialValue = 0; - int _axisTag = axisTagInitialValue; - int get axisTag => _axisTag; - - /// Change the [_axisTag] field value. - /// [axisTagChanged] will be invoked only if the field's value has changed. - set axisTag(int value) { - if (_axisTag == value) { - return; - } - int from = _axisTag; - _axisTag = value; - if (hasValidated) { - axisTagChanged(from, value); - } - } - - void axisTagChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// AxisValue field with key 321. - static const int axisValuePropertyKey = 321; - static const double axisValueInitialValue = 0; - double _axisValue = axisValueInitialValue; - double get axisValue => _axisValue; - - /// Change the [_axisValue] field value. - /// [axisValueChanged] will be invoked only if the field's value has changed. - set axisValue(double value) { - if (_axisValue == value) { - return; - } - double from = _axisValue; - _axisValue = value; - if (hasValidated) { - axisValueChanged(from, value); - } - } - - void axisValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TextVariationModifierBase) { - _axisTag = source._axisTag; - _axisValue = source._axisValue; - } - } -} diff --git a/lib/src/generated/transform_component_base.dart b/lib/src/generated/transform_component_base.dart deleted file mode 100644 index f80dc18..0000000 --- a/lib/src/generated/transform_component_base.dart +++ /dev/null @@ -1,97 +0,0 @@ -// Core automatically generated -// lib/src/generated/transform_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; - -abstract class TransformComponentBase extends WorldTransformComponent { - static const int typeKey = 38; - @override - int get coreType => TransformComponentBase.typeKey; - @override - Set get coreTypes => { - TransformComponentBase.typeKey, - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Rotation field with key 15. - static const int rotationPropertyKey = 15; - static const double rotationInitialValue = 0; - double _rotation = rotationInitialValue; - double get rotation => _rotation; - - /// Change the [_rotation] field value. - /// [rotationChanged] will be invoked only if the field's value has changed. - set rotation(double value) { - if (_rotation == value) { - return; - } - double from = _rotation; - _rotation = value; - if (hasValidated) { - rotationChanged(from, value); - } - } - - void rotationChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ScaleX field with key 16. - static const int scaleXPropertyKey = 16; - static const double scaleXInitialValue = 1; - double _scaleX = scaleXInitialValue; - double get scaleX => _scaleX; - - /// Change the [_scaleX] field value. - /// [scaleXChanged] will be invoked only if the field's value has changed. - set scaleX(double value) { - if (_scaleX == value) { - return; - } - double from = _scaleX; - _scaleX = value; - if (hasValidated) { - scaleXChanged(from, value); - } - } - - void scaleXChanged(double from, double to); - - /// -------------------------------------------------------------------------- - /// ScaleY field with key 17. - static const int scaleYPropertyKey = 17; - static const double scaleYInitialValue = 1; - double _scaleY = scaleYInitialValue; - double get scaleY => _scaleY; - - /// Change the [_scaleY] field value. - /// [scaleYChanged] will be invoked only if the field's value has changed. - set scaleY(double value) { - if (_scaleY == value) { - return; - } - double from = _scaleY; - _scaleY = value; - if (hasValidated) { - scaleYChanged(from, value); - } - } - - void scaleYChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is TransformComponentBase) { - _rotation = source._rotation; - _scaleX = source._scaleX; - _scaleY = source._scaleY; - } - } -} diff --git a/lib/src/generated/viewmodel/data_enum_base.dart b/lib/src/generated/viewmodel/data_enum_base.dart deleted file mode 100644 index 55e054e..0000000 --- a/lib/src/generated/viewmodel/data_enum_base.dart +++ /dev/null @@ -1,13 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/data_enum_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class DataEnumBase extends Core { - static const int typeKey = 438; - @override - int get coreType => DataEnumBase.typeKey; - @override - Set get coreTypes => {DataEnumBase.typeKey}; -} diff --git a/lib/src/generated/viewmodel/data_enum_value_base.dart b/lib/src/generated/viewmodel/data_enum_value_base.dart deleted file mode 100644 index cc0fa62..0000000 --- a/lib/src/generated/viewmodel/data_enum_value_base.dart +++ /dev/null @@ -1,70 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/data_enum_value_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class DataEnumValueBase extends Core { - static const int typeKey = 445; - @override - int get coreType => DataEnumValueBase.typeKey; - @override - Set get coreTypes => {DataEnumValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Key field with key 578. - static const int keyPropertyKey = 578; - static const String keyInitialValue = ''; - String _key = keyInitialValue; - - /// The key of this key value enum pair. - String get key => _key; - - /// Change the [_key] field value. - /// [keyChanged] will be invoked only if the field's value has changed. - set key(String value) { - if (_key == value) { - return; - } - String from = _key; - _key = value; - if (hasValidated) { - keyChanged(from, value); - } - } - - void keyChanged(String from, String to); - - /// -------------------------------------------------------------------------- - /// Value field with key 579. - static const int valuePropertyKey = 579; - static const String valueInitialValue = ''; - String _value = valueInitialValue; - - /// The value of this key value enum pair. - String get value => _value; - - /// Change the [_value] field value. - /// [valueChanged] will be invoked only if the field's value has changed. - set value(String value) { - if (_value == value) { - return; - } - String from = _value; - _value = value; - if (hasValidated) { - valueChanged(from, value); - } - } - - void valueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is DataEnumValueBase) { - _key = source._key; - _value = source._value; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_base.dart b/lib/src/generated/viewmodel/viewmodel_base.dart deleted file mode 100644 index 4bbbdea..0000000 --- a/lib/src/generated/viewmodel/viewmodel_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_component.dart'; - -abstract class ViewModelBase extends ViewModelComponent { - static const int typeKey = 435; - @override - int get coreType => ViewModelBase.typeKey; - @override - Set get coreTypes => - {ViewModelBase.typeKey, ViewModelComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// DefaultInstanceId field with key 564. - static const int defaultInstanceIdPropertyKey = 564; - static const int defaultInstanceIdInitialValue = -1; - int _defaultInstanceId = defaultInstanceIdInitialValue; - - /// The default instance attached to the view model. - int get defaultInstanceId => _defaultInstanceId; - - /// Change the [_defaultInstanceId] field value. - /// [defaultInstanceIdChanged] will be invoked only if the field's value has - /// changed. - set defaultInstanceId(int value) { - if (_defaultInstanceId == value) { - return; - } - int from = _defaultInstanceId; - _defaultInstanceId = value; - if (hasValidated) { - defaultInstanceIdChanged(from, value); - } - } - - void defaultInstanceIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelBase) { - _defaultInstanceId = source._defaultInstanceId; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_component_base.dart b/lib/src/generated/viewmodel/viewmodel_component_base.dart deleted file mode 100644 index d88bd84..0000000 --- a/lib/src/generated/viewmodel/viewmodel_component_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class ViewModelComponentBase extends Core { - static const int typeKey = 429; - @override - int get coreType => ViewModelComponentBase.typeKey; - @override - Set get coreTypes => {ViewModelComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// Name field with key 557. - static const int namePropertyKey = 557; - static const String nameInitialValue = ''; - String _name = nameInitialValue; - - /// Non-unique identifier, used to give friendly names to any view model - /// component. - String get name => _name; - - /// Change the [_name] field value. - /// [nameChanged] will be invoked only if the field's value has changed. - set name(String value) { - if (_name == value) { - return; - } - String from = _name; - _name = value; - if (hasValidated) { - nameChanged(from, value); - } - } - - void nameChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelComponentBase) { - _name = source._name; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_base.dart deleted file mode 100644 index d764fc2..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_base.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; - -abstract class ViewModelInstanceBase extends Component { - static const int typeKey = 437; - @override - int get coreType => ViewModelInstanceBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceBase.typeKey, ComponentBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// ViewModelId field with key 566. - static const int viewModelIdPropertyKey = 566; - static const int viewModelIdInitialValue = 0; - int _viewModelId = viewModelIdInitialValue; - int get viewModelId => _viewModelId; - - /// Change the [_viewModelId] field value. - /// [viewModelIdChanged] will be invoked only if the field's value has - /// changed. - set viewModelId(int value) { - if (_viewModelId == value) { - return; - } - int from = _viewModelId; - _viewModelId = value; - if (hasValidated) { - viewModelIdChanged(from, value); - } - } - - void viewModelIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceBase) { - _viewModelId = source._viewModelId; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_boolean_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_boolean_base.dart deleted file mode 100644 index acd165a..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_boolean_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_boolean_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceBooleanBase extends ViewModelInstanceValue { - static const int typeKey = 449; - @override - int get coreType => ViewModelInstanceBooleanBase.typeKey; - @override - Set get coreTypes => { - ViewModelInstanceBooleanBase.typeKey, - ViewModelInstanceValueBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 593. - static const int propertyValuePropertyKey = 593; - static const bool propertyValueInitialValue = false; - bool _propertyValue = propertyValueInitialValue; - - /// The boolean value. - bool get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(bool value) { - if (_propertyValue == value) { - return; - } - bool from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(bool from, bool to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceBooleanBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_color_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_color_base.dart deleted file mode 100644 index 87e0d71..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_color_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_color_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceColorBase extends ViewModelInstanceValue { - static const int typeKey = 426; - @override - int get coreType => ViewModelInstanceColorBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceColorBase.typeKey, ViewModelInstanceValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 555. - static const int propertyValuePropertyKey = 555; - static const int propertyValueInitialValue = 0xFF1D1D1D; - int _propertyValue = propertyValueInitialValue; - - /// The color value - int get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(int value) { - if (_propertyValue == value) { - return; - } - int from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceColorBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_enum_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_enum_base.dart deleted file mode 100644 index daf7413..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_enum_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_enum_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceEnumBase extends ViewModelInstanceValue { - static const int typeKey = 432; - @override - int get coreType => ViewModelInstanceEnumBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceEnumBase.typeKey, ViewModelInstanceValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 560. - static const int propertyValuePropertyKey = 560; - static const int propertyValueInitialValue = 0; - int _propertyValue = propertyValueInitialValue; - - /// The id of the enum value. - int get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(int value) { - if (_propertyValue == value) { - return; - } - int from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceEnumBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_list_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_list_base.dart deleted file mode 100644 index 740bea4..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_list_base.dart +++ /dev/null @@ -1,15 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_list_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceListBase extends ViewModelInstanceValue { - static const int typeKey = 441; - @override - int get coreType => ViewModelInstanceListBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceListBase.typeKey, ViewModelInstanceValueBase.typeKey}; -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_list_item_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_list_item_base.dart deleted file mode 100644 index b363963..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_list_item_base.dart +++ /dev/null @@ -1,124 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_list_item_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class ViewModelInstanceListItemBase - extends Core { - static const int typeKey = 427; - @override - int get coreType => ViewModelInstanceListItemBase.typeKey; - @override - Set get coreTypes => {ViewModelInstanceListItemBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// UseLinkedArtboard field with key 547. - static const int useLinkedArtboardPropertyKey = 547; - static const bool useLinkedArtboardInitialValue = true; - bool _useLinkedArtboard = useLinkedArtboardInitialValue; - - /// Whether the artboard linked to the view model should be used. - bool get useLinkedArtboard => _useLinkedArtboard; - - /// Change the [_useLinkedArtboard] field value. - /// [useLinkedArtboardChanged] will be invoked only if the field's value has - /// changed. - set useLinkedArtboard(bool value) { - if (_useLinkedArtboard == value) { - return; - } - bool from = _useLinkedArtboard; - _useLinkedArtboard = value; - if (hasValidated) { - useLinkedArtboardChanged(from, value); - } - } - - void useLinkedArtboardChanged(bool from, bool to); - - /// -------------------------------------------------------------------------- - /// ViewModelId field with key 549. - static const int viewModelIdPropertyKey = 549; - static const int viewModelIdInitialValue = -1; - int _viewModelId = viewModelIdInitialValue; - - /// The view model id. - int get viewModelId => _viewModelId; - - /// Change the [_viewModelId] field value. - /// [viewModelIdChanged] will be invoked only if the field's value has - /// changed. - set viewModelId(int value) { - if (_viewModelId == value) { - return; - } - int from = _viewModelId; - _viewModelId = value; - if (hasValidated) { - viewModelIdChanged(from, value); - } - } - - void viewModelIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ViewModelInstanceId field with key 550. - static const int viewModelInstanceIdPropertyKey = 550; - static const int viewModelInstanceIdInitialValue = -1; - int _viewModelInstanceId = viewModelInstanceIdInitialValue; - - /// The view model instance id. - int get viewModelInstanceId => _viewModelInstanceId; - - /// Change the [_viewModelInstanceId] field value. - /// [viewModelInstanceIdChanged] will be invoked only if the field's value has - /// changed. - set viewModelInstanceId(int value) { - if (_viewModelInstanceId == value) { - return; - } - int from = _viewModelInstanceId; - _viewModelInstanceId = value; - if (hasValidated) { - viewModelInstanceIdChanged(from, value); - } - } - - void viewModelInstanceIdChanged(int from, int to); - - /// -------------------------------------------------------------------------- - /// ArtboardId field with key 551. - static const int artboardIdPropertyKey = 551; - static const int artboardIdInitialValue = -1; - int _artboardId = artboardIdInitialValue; - - /// The artboard id to link the viewmodel to if implicit is set to false. - int get artboardId => _artboardId; - - /// Change the [_artboardId] field value. - /// [artboardIdChanged] will be invoked only if the field's value has changed. - set artboardId(int value) { - if (_artboardId == value) { - return; - } - int from = _artboardId; - _artboardId = value; - if (hasValidated) { - artboardIdChanged(from, value); - } - } - - void artboardIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceListItemBase) { - _useLinkedArtboard = source._useLinkedArtboard; - _viewModelId = source._viewModelId; - _viewModelInstanceId = source._viewModelInstanceId; - _artboardId = source._artboardId; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_number_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_number_base.dart deleted file mode 100644 index efc31c3..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_number_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceNumberBase extends ViewModelInstanceValue { - static const int typeKey = 442; - @override - int get coreType => ViewModelInstanceNumberBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceNumberBase.typeKey, ViewModelInstanceValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 575. - static const int propertyValuePropertyKey = 575; - static const double propertyValueInitialValue = 0; - double _propertyValue = propertyValueInitialValue; - - /// The number value. - double get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(double value) { - if (_propertyValue == value) { - return; - } - double from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceNumberBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_string_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_string_base.dart deleted file mode 100644 index 6aa4e19..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_string_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_string_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceStringBase extends ViewModelInstanceValue { - static const int typeKey = 433; - @override - int get coreType => ViewModelInstanceStringBase.typeKey; - @override - Set get coreTypes => - {ViewModelInstanceStringBase.typeKey, ViewModelInstanceValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 561. - static const int propertyValuePropertyKey = 561; - static const String propertyValueInitialValue = ''; - String _propertyValue = propertyValueInitialValue; - - /// The string value. - String get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(String value) { - if (_propertyValue == value) { - return; - } - String from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(String from, String to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceStringBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_value_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_value_base.dart deleted file mode 100644 index ec92250..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_value_base.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_value_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; - -abstract class ViewModelInstanceValueBase - extends Core { - static const int typeKey = 428; - @override - int get coreType => ViewModelInstanceValueBase.typeKey; - @override - Set get coreTypes => {ViewModelInstanceValueBase.typeKey}; - - /// -------------------------------------------------------------------------- - /// ViewModelPropertyId field with key 554. - static const int viewModelPropertyIdPropertyKey = 554; - static const int viewModelPropertyIdInitialValue = 0; - int _viewModelPropertyId = viewModelPropertyIdInitialValue; - - /// Identifier of the property this value will provide data for. At runtime - /// these ids are normalized relative to the ViewModel itself. - int get viewModelPropertyId => _viewModelPropertyId; - - /// Change the [_viewModelPropertyId] field value. - /// [viewModelPropertyIdChanged] will be invoked only if the field's value has - /// changed. - set viewModelPropertyId(int value) { - if (_viewModelPropertyId == value) { - return; - } - int from = _viewModelPropertyId; - _viewModelPropertyId = value; - if (hasValidated) { - viewModelPropertyIdChanged(from, value); - } - } - - void viewModelPropertyIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceValueBase) { - _viewModelPropertyId = source._viewModelPropertyId; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart b/lib/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart deleted file mode 100644 index 797e52b..0000000 --- a/lib/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ViewModelInstanceViewModelBase extends ViewModelInstanceValue { - static const int typeKey = 444; - @override - int get coreType => ViewModelInstanceViewModelBase.typeKey; - @override - Set get coreTypes => { - ViewModelInstanceViewModelBase.typeKey, - ViewModelInstanceValueBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// PropertyValue field with key 577. - static const int propertyValuePropertyKey = 577; - static const int propertyValueInitialValue = 0; - int _propertyValue = propertyValueInitialValue; - - /// The id of the viewmodel instance. - int get propertyValue => _propertyValue; - - /// Change the [_propertyValue] field value. - /// [propertyValueChanged] will be invoked only if the field's value has - /// changed. - set propertyValue(int value) { - if (_propertyValue == value) { - return; - } - int from = _propertyValue; - _propertyValue = value; - if (hasValidated) { - propertyValueChanged(from, value); - } - } - - void propertyValueChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelInstanceViewModelBase) { - _propertyValue = source._propertyValue; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_base.dart b/lib/src/generated/viewmodel/viewmodel_property_base.dart deleted file mode 100644 index 59ae805..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_base.dart +++ /dev/null @@ -1,14 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_base.dart. -// Do not modify manually. - -import 'package:rive/src/rive_core/viewmodel/viewmodel_component.dart'; - -abstract class ViewModelPropertyBase extends ViewModelComponent { - static const int typeKey = 430; - @override - int get coreType => ViewModelPropertyBase.typeKey; - @override - Set get coreTypes => - {ViewModelPropertyBase.typeKey, ViewModelComponentBase.typeKey}; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_boolean_base.dart b/lib/src/generated/viewmodel/viewmodel_property_boolean_base.dart deleted file mode 100644 index 41b0414..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_boolean_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_boolean_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyBooleanBase extends ViewModelProperty { - static const int typeKey = 448; - @override - int get coreType => ViewModelPropertyBooleanBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyBooleanBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_color_base.dart b/lib/src/generated/viewmodel/viewmodel_property_color_base.dart deleted file mode 100644 index 35a3162..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_color_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_color_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyColorBase extends ViewModelProperty { - static const int typeKey = 440; - @override - int get coreType => ViewModelPropertyColorBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyColorBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_enum_base.dart b/lib/src/generated/viewmodel/viewmodel_property_enum_base.dart deleted file mode 100644 index 1953b02..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_enum_base.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_enum_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyEnumBase extends ViewModelProperty { - static const int typeKey = 439; - @override - int get coreType => ViewModelPropertyEnumBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyEnumBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// EnumId field with key 574. - static const int enumIdPropertyKey = 574; - static const int enumIdInitialValue = -1; - int _enumId = enumIdInitialValue; - - /// The id of the enum. - int get enumId => _enumId; - - /// Change the [_enumId] field value. - /// [enumIdChanged] will be invoked only if the field's value has changed. - set enumId(int value) { - if (_enumId == value) { - return; - } - int from = _enumId; - _enumId = value; - if (hasValidated) { - enumIdChanged(from, value); - } - } - - void enumIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelPropertyEnumBase) { - _enumId = source._enumId; - } - } -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_list_base.dart b/lib/src/generated/viewmodel/viewmodel_property_list_base.dart deleted file mode 100644 index 3104cc9..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_list_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_list_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyListBase extends ViewModelProperty { - static const int typeKey = 434; - @override - int get coreType => ViewModelPropertyListBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyListBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_number_base.dart b/lib/src/generated/viewmodel/viewmodel_property_number_base.dart deleted file mode 100644 index 5cc5b85..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_number_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_number_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyNumberBase extends ViewModelProperty { - static const int typeKey = 431; - @override - int get coreType => ViewModelPropertyNumberBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyNumberBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_string_base.dart b/lib/src/generated/viewmodel/viewmodel_property_string_base.dart deleted file mode 100644 index 3aaa149..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_string_base.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_string_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyStringBase extends ViewModelProperty { - static const int typeKey = 443; - @override - int get coreType => ViewModelPropertyStringBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyStringBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; -} diff --git a/lib/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart b/lib/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart deleted file mode 100644 index 8050154..0000000 --- a/lib/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Core automatically generated -// lib/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart. -// Do not modify manually. - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -abstract class ViewModelPropertyViewModelBase extends ViewModelProperty { - static const int typeKey = 436; - @override - int get coreType => ViewModelPropertyViewModelBase.typeKey; - @override - Set get coreTypes => { - ViewModelPropertyViewModelBase.typeKey, - ViewModelPropertyBase.typeKey, - ViewModelComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// ViewModelReferenceId field with key 565. - static const int viewModelReferenceIdPropertyKey = 565; - static const int viewModelReferenceIdInitialValue = 0; - int _viewModelReferenceId = viewModelReferenceIdInitialValue; - - /// Identifier used to track the viewmodel this property points to. - int get viewModelReferenceId => _viewModelReferenceId; - - /// Change the [_viewModelReferenceId] field value. - /// [viewModelReferenceIdChanged] will be invoked only if the field's value - /// has changed. - set viewModelReferenceId(int value) { - if (_viewModelReferenceId == value) { - return; - } - int from = _viewModelReferenceId; - _viewModelReferenceId = value; - if (hasValidated) { - viewModelReferenceIdChanged(from, value); - } - } - - void viewModelReferenceIdChanged(int from, int to); - - @override - void copy(Core source) { - super.copy(source); - if (source is ViewModelPropertyViewModelBase) { - _viewModelReferenceId = source._viewModelReferenceId; - } - } -} diff --git a/lib/src/generated/world_transform_component_base.dart b/lib/src/generated/world_transform_component_base.dart deleted file mode 100644 index cdcaf19..0000000 --- a/lib/src/generated/world_transform_component_base.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Core automatically generated -// lib/src/generated/world_transform_component_base.dart. -// Do not modify manually. - -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; - -abstract class WorldTransformComponentBase extends ContainerComponent { - static const int typeKey = 91; - @override - int get coreType => WorldTransformComponentBase.typeKey; - @override - Set get coreTypes => { - WorldTransformComponentBase.typeKey, - ContainerComponentBase.typeKey, - ComponentBase.typeKey - }; - - /// -------------------------------------------------------------------------- - /// Opacity field with key 18. - static const int opacityPropertyKey = 18; - static const double opacityInitialValue = 1; - double _opacity = opacityInitialValue; - double get opacity => _opacity; - - /// Change the [_opacity] field value. - /// [opacityChanged] will be invoked only if the field's value has changed. - set opacity(double value) { - if (_opacity == value) { - return; - } - double from = _opacity; - _opacity = value; - if (hasValidated) { - opacityChanged(from, value); - } - } - - void opacityChanged(double from, double to); - - @override - void copy(Core source) { - super.copy(source); - if (source is WorldTransformComponentBase) { - _opacity = source._opacity; - } - } -} diff --git a/lib/src/layer_component_events.dart b/lib/src/layer_component_events.dart deleted file mode 100644 index 2c39dc7..0000000 --- a/lib/src/layer_component_events.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/animation/state_machine_fire_event.dart'; - -class LayerComponentEvents extends ListBase { - final List _values = []; - List get values => - _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - StateMachineFireEvent operator [](int index) => _values[index]!; - - @override - void operator []=(int index, StateMachineFireEvent value) => - _values[index] = value; -} diff --git a/lib/src/listener_actions.dart b/lib/src/listener_actions.dart deleted file mode 100644 index eb4ec55..0000000 --- a/lib/src/listener_actions.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/animation/listener_action.dart'; - -class ListenerActions extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - ListenerAction operator [](int index) => _values[index]!; - - @override - void operator []=(int index, ListenerAction value) => _values[index] = value; -} diff --git a/lib/src/local_file_io.dart b/lib/src/local_file_io.dart deleted file mode 100644 index 93dc3ea..0000000 --- a/lib/src/local_file_io.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -/// Load a list of bytes from a file on the local filesystem at [path]. -Future localFileBytes(String path) => File(path).readAsBytes(); diff --git a/lib/src/local_file_web.dart b/lib/src/local_file_web.dart deleted file mode 100644 index 858eae6..0000000 --- a/lib/src/local_file_web.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'dart:typed_data'; - -/// Load a list of bytes from a file on the local filesystem at [path]. -Future localFileBytes(String path) => - throw UnsupportedError('Cannot load from a local file on the web.'); diff --git a/lib/src/models/artboard_selector.dart b/lib/src/models/artboard_selector.dart new file mode 100644 index 0000000..6c14b3b --- /dev/null +++ b/lib/src/models/artboard_selector.dart @@ -0,0 +1,69 @@ +/// A selector for an artboard in a Rive file. +sealed class ArtboardSelector { + const ArtboardSelector(); + + /// Selects the default artboard. + factory ArtboardSelector.byDefault() => const ArtboardDefault(); + + /// Selects the artboard with the given name. + factory ArtboardSelector.byName(String name) => ArtboardNamed(name); + + /// Selects the artboard at the given index. + factory ArtboardSelector.byIndex(int index) => ArtboardAtIndex(index); +} + +/// Selects the default artboard. +class ArtboardDefault extends ArtboardSelector { + const ArtboardDefault(); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ArtboardDefault && runtimeType == other.runtimeType; + + @override + int get hashCode => 0; + + @override + String toString() => 'ArtboardDefault()'; +} + +/// Selects the artboard with the given name. +class ArtboardNamed extends ArtboardSelector { + final String name; + + const ArtboardNamed(this.name); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ArtboardNamed && + runtimeType == other.runtimeType && + name == other.name; + + @override + int get hashCode => name.hashCode; + + @override + String toString() => 'ArtboardNamed(name: $name)'; +} + +/// Selects the artboard at the given index. +class ArtboardAtIndex extends ArtboardSelector { + final int index; + + const ArtboardAtIndex(this.index); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ArtboardAtIndex && + runtimeType == other.runtimeType && + index == other.index; + + @override + int get hashCode => index.hashCode; + + @override + String toString() => 'ArtboardAtIndex(index: $index)'; +} diff --git a/lib/src/models/data_bind.dart b/lib/src/models/data_bind.dart new file mode 100644 index 0000000..d738645 --- /dev/null +++ b/lib/src/models/data_bind.dart @@ -0,0 +1,114 @@ +import 'package:rive/rive.dart'; + +/// A data bind option for a Rive file. +sealed class DataBind { + const DataBind(); + + /// Auto-bind + static DataBind auto() => const AutoBind(); + + /// Bind by view model instance + static DataBind byInstance(ViewModelInstance viewModelInstance) => + BindByInstance(viewModelInstance); + + /// Bind by index + static DataBind byIndex(int value) => BindByIndex(value); + + /// Bind by name + static DataBind byName(String value) => BindByName(value); + + /// Empty binding + static DataBind empty() => const BindEmpty(); +} + +/// Auto-bind with a boolean value +class AutoBind extends DataBind { + const AutoBind(); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is AutoBind && runtimeType == other.runtimeType; + + @override + int get hashCode => 0; + + @override + String toString() => 'AutoBind()'; +} + +/// Bind by view model instance +class BindByInstance extends DataBind { + final ViewModelInstance viewModelInstance; + + const BindByInstance(this.viewModelInstance); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BindByInstance && + runtimeType == other.runtimeType && + viewModelInstance == other.viewModelInstance; + + @override + int get hashCode => viewModelInstance.hashCode; + + @override + String toString() => 'BindByInstance(viewModelInstance: $viewModelInstance)'; +} + +/// Bind by index with a number value +class BindByIndex extends DataBind { + final int index; + + const BindByIndex(this.index); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BindByIndex && + runtimeType == other.runtimeType && + index == other.index; + + @override + int get hashCode => index.hashCode; + + @override + String toString() => 'BindByIndex(value: $index)'; +} + +/// Bind by name with a string value +class BindByName extends DataBind { + final String name; + + const BindByName(this.name); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BindByName && + runtimeType == other.runtimeType && + name == other.name; + + @override + int get hashCode => name.hashCode; + + @override + String toString() => 'BindByName(value: $name)'; +} + +/// Empty binding +class BindEmpty extends DataBind { + const BindEmpty(); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is BindEmpty && runtimeType == other.runtimeType; + + @override + int get hashCode => 0; + + @override + String toString() => 'BindEmpty()'; +} diff --git a/lib/src/models/state_machine_selector.dart b/lib/src/models/state_machine_selector.dart new file mode 100644 index 0000000..0d749ba --- /dev/null +++ b/lib/src/models/state_machine_selector.dart @@ -0,0 +1,69 @@ +/// A selector for a state machine in a Rive file. +sealed class StateMachineSelector { + const StateMachineSelector(); + + /// Selects the default state machine. + factory StateMachineSelector.byDefault() => const StateMachineDefault(); + + /// Selects the state machine with the given name. + factory StateMachineSelector.byName(String name) => StateMachineNamed(name); + + /// Selects the state machine at the given index. + factory StateMachineSelector.byIndex(int index) => StateMachineAtIndex(index); +} + +/// Selects the default state machine. +class StateMachineDefault extends StateMachineSelector { + const StateMachineDefault(); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is StateMachineDefault && runtimeType == other.runtimeType; + + @override + int get hashCode => 0; + + @override + String toString() => 'StateMachineDefault()'; +} + +/// Selects the state machine with the given name. +class StateMachineNamed extends StateMachineSelector { + final String name; + + const StateMachineNamed(this.name); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is StateMachineNamed && + runtimeType == other.runtimeType && + name == other.name; + + @override + int get hashCode => name.hashCode; + + @override + String toString() => 'StateMachineNamed(name: $name)'; +} + +/// Selects the state machine at the given index. +class StateMachineAtIndex extends StateMachineSelector { + final int index; + + const StateMachineAtIndex(this.index); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is StateMachineAtIndex && + runtimeType == other.runtimeType && + index == other.index; + + @override + int get hashCode => index.hashCode; + + @override + String toString() => 'StateMachineAtIndex(index: $index)'; +} diff --git a/lib/src/painters/widget_controller.dart b/lib/src/painters/widget_controller.dart new file mode 100644 index 0000000..dd487a5 --- /dev/null +++ b/lib/src/painters/widget_controller.dart @@ -0,0 +1,183 @@ +import 'package:flutter/gestures.dart'; +import 'package:rive/rive.dart'; + +/// {@template rive_controller} +/// This controller builds on top of the concept of a Rive painter, but +/// provides a more convenient API for building Rive widgets. +/// +/// To be used with [RiveWidget] and [RiveWidgetBuilder] widgets. +/// {@endtemplate} +base class RiveWidgetController extends BasicArtboardPainter + with RivePointerEventMixin { + /// The Rive file to this controller is built from. + final File file; + + @override + + /// The artboard that the [RiveWidgetController] is painting. + late final Artboard artboard; + + /// The state machine that the [RiveWidgetController] is using. + late final StateMachine stateMachine; + + /// {@macro rive_controller} + /// - The [file] parameter is the Rive file to paint. + /// - The [artboardSelector] parameter specifies which artboard to use. + /// - The [stateMachineSelector] parameter specifies which state machine to use. + RiveWidgetController( + this.file, { + ArtboardSelector artboardSelector = const ArtboardDefault(), + StateMachineSelector stateMachineSelector = const StateMachineDefault(), + }) { + artboard = _createArtboard(file, artboardSelector); + stateMachine = _createStateMachine(artboard, stateMachineSelector); + } + + // TODO (Gordon): Remove this once we have polling or a general callback + // The editor uses this, and we're copying that behavior for now. + CallbackHandler? _inputCallbackHandler; + void _onInputChanged(int inputId) => notifyListeners(); + + Artboard _createArtboard(File file, ArtboardSelector artboardSelector) { + final artboard = switch (artboardSelector) { + ArtboardDefault() => file.defaultArtboard(), + ArtboardNamed(:final name) => file.artboard(name), + ArtboardAtIndex(:final index) => file.artboardAt(index), + }; + if (artboard == null) { + final message = switch (artboardSelector) { + ArtboardDefault() => 'Default artboard not found.', + ArtboardNamed(:final name) => 'Artboard with name "$name" not found.', + ArtboardAtIndex(:final index) => 'Artboard at index $index not found.', + }; + throw RiveArtboardException(message); + } + return artboard; + } + + StateMachine _createStateMachine( + Artboard artboard, StateMachineSelector stateMachineSelector) { + final stateMachine = switch (stateMachineSelector) { + StateMachineDefault() => artboard.defaultStateMachine(), + StateMachineNamed(:final name) => artboard.stateMachine(name), + StateMachineAtIndex(:final index) => artboard.stateMachineAt(index), + }; + if (stateMachine == null) { + final message = switch (stateMachineSelector) { + StateMachineDefault() => 'Default state machine not found.', + StateMachineNamed(:final name) => + 'State machine with name "$name" not found.', + StateMachineAtIndex(:final index) => + 'State machine at index $index not found.', + }; + throw RiveStateMachineException(message); + } + _inputCallbackHandler = stateMachine.onInputChanged(_onInputChanged); + return stateMachine; + } + + /// Whether this controller is active (painting and advancing). + bool _active = true; + bool get active => _active; + set active(bool value) { + _active = value; + notifyListeners(); + } + + /// Binds a [ViewModelInstance] to the [StateMachine]. + /// + /// - The [dataBind] parameter specifies which view model instance to bind to + /// the [StateMachine]. + /// + /// Returns the [ViewModelInstance] that was bound to the [StateMachine]. + /// + /// Throws a [RiveDataBindException] if the [ViewModelInstance] could not be + /// found. + ViewModelInstance dataBind(DataBind dataBind) { + final vmi = switch (dataBind) { + AutoBind() => file.createDefaultViewModelInstance(artboard), + BindByInstance() => dataBind.viewModelInstance, + BindByIndex() => _safeViewModel?.createInstanceByIndex(dataBind.index), + BindByName() => _safeViewModel?.createInstanceByName(dataBind.name), + BindEmpty() => _safeViewModel?.createInstance(), + }; + if (vmi == null) { + final message = switch (dataBind) { + AutoBind() => + 'Default view model instance not found. Make sure the instance is set to exported in the Rive Editor.', + BindByInstance() => 'Failed to use the provided view model instance.', + BindByIndex() => + 'View model instance by index `${dataBind.index}` not found.', + BindByName() => + 'View model instance by name `${dataBind.name}` not found.', + BindEmpty() => + 'Something went wrong. Could not create a view model instance.', + }; + throw RiveDataBindException(message); + } + stateMachine.bindViewModelInstance(vmi); + return vmi; + } + + ViewModel? get _safeViewModel => file.defaultArtboardViewModel(artboard); + + @override + void artboardChanged(Artboard artboard) { + // This painter builds the artboard as part of its constructor. + // Always use the constructor provided artboard. + super.artboardChanged(this.artboard); + } + + @override + bool hitTest(Offset position) { + final value = stateMachine.hitTest( + localToArtboard( + position: position, + artboardBounds: artboard.bounds, + fit: fit, + alignment: alignment, + size: lastSize / lastPaintPixelRatio, + scaleFactor: layoutScaleFactor, + ), + ); + return value; + } + + @override + pointerEvent(PointerEvent event, HitTestEntry entry) { + final stateMachine = this.stateMachine; + final position = localToArtboard( + position: event.localPosition, + artboardBounds: artboard.bounds, + fit: fit, + alignment: alignment, + size: lastSize / lastPaintPixelRatio, + scaleFactor: layoutScaleFactor, + ); + + if (event is PointerDownEvent) { + stateMachine.pointerDown(position); + } else if (event is PointerUpEvent) { + stateMachine.pointerUp(position); + } else if (event is PointerMoveEvent) { + stateMachine.pointerMove(position); + } else if (event is PointerHoverEvent) { + stateMachine.pointerMove(position); + } + } + + @override + bool advance(double elapsedSeconds) { + if (!active) return false; + return stateMachine.advanceAndApply(elapsedSeconds); + } + + @override + void dispose() { + artboard.dispose(); + stateMachine.dispose(); + _inputCallbackHandler?.dispose(); + _inputCallbackHandler = null; + super.dispose(); + } +} diff --git a/lib/src/platform.dart b/lib/src/platform.dart deleted file mode 100644 index 0c9c6a9..0000000 --- a/lib/src/platform.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'platform_native.dart' if (dart.library.js_interop) 'platform_web.dart'; - -abstract class Platform { - bool get isTesting; - static final Platform instance = makePlatform(); -} diff --git a/lib/src/platform_native.dart b/lib/src/platform_native.dart deleted file mode 100644 index 2adeb6d..0000000 --- a/lib/src/platform_native.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'dart:io' as io show Platform; - -import 'platform.dart'; - -Platform makePlatform() => PlatformNative(); - -class PlatformNative extends Platform { - @override - bool get isTesting => io.Platform.environment.containsKey('FLUTTER_TEST'); -} diff --git a/lib/src/platform_web.dart b/lib/src/platform_web.dart deleted file mode 100644 index 63c7cd3..0000000 --- a/lib/src/platform_web.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'platform.dart'; - -Platform makePlatform() => PlatformWeb(); - -class PlatformWeb extends Platform { - @override - bool get isTesting => false; -} diff --git a/lib/src/rive.dart b/lib/src/rive.dart deleted file mode 100644 index 0a8af09..0000000 --- a/lib/src/rive.dart +++ /dev/null @@ -1,402 +0,0 @@ -import 'package:flutter/gestures.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:rive/src/controllers/state_machine_controller.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart' - show HitResult; -import 'package:rive/src/rive_render_box.dart'; -import 'package:rive/src/runtime_artboard.dart'; -import 'package:rive_common/math.dart'; - -/// How to behave during hit tests on Rive Listeners (hit targets). -enum RiveHitTestBehavior { - /// The bounds of the Rive animation will consume all hits, even if there is - /// no animation listener (hit area) at the target point. Content - /// behind the animation will not receive hits. - opaque, - - /// Rive will only consume hits where there is a listener (hit area) at the - /// target point. Content behind the animation will only receive hits if - /// no animation listener was hit. - translucent, - - /// All hits will pass through the animation, regardless of whether a - /// a Rive listener was hit. Rive listeners will still receive hits. - transparent, -} - -class Rive extends LeafRenderObjectWidget { - /// Artboard used for drawing - final Artboard artboard; - - /// {@template Rive.useArtboardSize} - /// Determines whether to use the inherent size of the [artboard], i.e. the - /// absolute size defined by the artboard, or size the widget based on the - /// available constraints only (sized by parent). - /// - /// Defaults to `false`, i.e. defaults to sizing based on the available - /// constraints instead of the artboard size. - /// - /// When `true`, the artboard size is constrained by the parent constraints. - /// Using the artboard size has the benefit that the widget now has an - /// *intrinsic* size. - /// - /// When `false`, the intrinsic size is `(0, 0)` because - /// there is no size intrinsically - it only comes from the parent - /// constraints. Consequently, if you intend to use the widget in the subtree - /// of an [IntrinsicWidth] or [IntrinsicHeight] widget or intend to directly - /// obtain the [RenderBox.getMinIntrinsicWidth] et al., you will want to set - /// this to `true`. - /// {@endtemplate} - final bool useArtboardSize; - - /// Fit for the rendering artboard - final BoxFit fit; - - /// Alignment for the rendering artboard - final Alignment alignment; - - /// Enables/disables antialiasing - final bool antialiasing; - - /// Enable input listeners (such as hover, pointer down, etc.) on the - /// artboard. - /// - /// Default `false`. - final bool enablePointerEvents; - - /// The mouse cursor for mouse pointers that are hovering over the region. - /// - /// When a mouse enters the region, its cursor will be changed to the - /// [cursor]. When the mouse leaves the region, the cursor will be decided by - /// the region found at the new location. - /// - /// The [cursor] defaults to [MouseCursor.defer], deferring the choice of - /// cursor to the next region behind it in hit-test order. - final MouseCursor cursor; - - /// {@template Rive.behavior} - /// How to behave during hit testing to consider targets behind this - /// animation. - /// - /// Defaults to [RiveHitTestBehavior.opaque]. - /// - /// See [RiveHitTestBehavior] for the allowed values and their meanings. - /// {@endtemplate} - final RiveHitTestBehavior behavior; - - /// {@template Rive.clipRect} - /// Clip the artboard to this rect. - /// - /// If not supplied it'll default to the constraint size provided by the - /// parent widget. Unless the [Artboard] has clipping disabled, then no - /// clip will be applied. - /// {@endtemplate} - final Rect? clipRect; - - /// A multiplier for controlling the speed of the Rive animation playback. - /// - /// Default `1.0`. - final double speedMultiplier; - - /// For Rive Listeners, allows scrolling behavior to still occur on Rive - /// widgets when a touch/drag action is performed on touch-enabled devices. - /// Otherwise, scroll behavior may be prevented on touch/drag actions on the - /// widget by default. - /// - /// Default `false`. - final bool isTouchScrollEnabled; - - const Rive({ - required this.artboard, - super.key, - this.useArtboardSize = false, - this.antialiasing = true, - this.enablePointerEvents = false, - this.cursor = MouseCursor.defer, - this.behavior = RiveHitTestBehavior.opaque, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.clipRect, - this.speedMultiplier = 1.0, - this.isTouchScrollEnabled = false, - }); - - @override - RenderObject createRenderObject(BuildContext context) { - // Doing this here and not in constructor so it can remain const - artboard.antialiasing = antialiasing; - final tickerModeValue = TickerMode.of(context); - return RiveRenderObject(artboard as RuntimeArtboard) - ..fit = fit - ..alignment = alignment - ..artboardSize = Size(artboard.width, artboard.height) - ..useArtboardSize = useArtboardSize - ..clipRect = clipRect - ..tickerModeEnabled = tickerModeValue - ..enableHitTests = enablePointerEvents - ..cursor = cursor - ..behavior = behavior - ..speedMultiplier = speedMultiplier - ..isTouchScrollEnabled = isTouchScrollEnabled; - } - - @override - void updateRenderObject( - BuildContext context, covariant RiveRenderObject renderObject) { - final tickerModeValue = TickerMode.of(context); - artboard.antialiasing = antialiasing; - renderObject - ..artboard = artboard - ..fit = fit - ..alignment = alignment - ..artboardSize = Size(artboard.width, artboard.height) - ..useArtboardSize = useArtboardSize - ..clipRect = clipRect - ..tickerModeEnabled = tickerModeValue - ..enableHitTests = enablePointerEvents - ..cursor = cursor - ..behavior = behavior - ..speedMultiplier = speedMultiplier - ..isTouchScrollEnabled = isTouchScrollEnabled; - } -} - -class RiveRenderObject extends RiveRenderBox implements MouseTrackerAnnotation { - RuntimeArtboard _artboard; - double _speedMultiplier = 1; - RiveRenderObject( - this._artboard, { - this.behavior = RiveHitTestBehavior.opaque, - MouseCursor cursor = MouseCursor.defer, - bool validForMouseTracker = true, - }) : _cursor = cursor, - _validForMouseTracker = validForMouseTracker { - _artboard.redraw.addListener(scheduleRepaint); - } - - RuntimeArtboard get artboard => _artboard; - - set artboard(Artboard value) { - if (_artboard == value) { - return; - } - _artboard.redraw.removeListener(scheduleRepaint); - _artboard = value as RuntimeArtboard; - _artboard.redraw.addListener(scheduleRepaint); - markNeedsLayout(); - } - - double get speedMultiplier => _speedMultiplier; - - set speedMultiplier(double value) { - if (value != _speedMultiplier) { - _speedMultiplier = value; - } - } - - /// Local offset to global artboard position - Vec2D _toArtboard(Offset local) { - final globalCoordinates = localToGlobal(local); - return globalToArtboard(globalCoordinates); - } - - /// Helper to manage hit testing - void _hitHelper(PointerEvent event, - void Function(StateMachineController, Vec2D) callback) { - final artboardPosition = _toArtboard(event.localPosition); - final stateMachineControllers = - _artboard.animationControllers.whereType(); - for (final stateMachineController in stateMachineControllers) { - callback(stateMachineController, artboardPosition); - } - } - - @override - bool hitTest(BoxHitTestResult result, {required Offset position}) { - // super.hitTest(result, position: position) - bool hitTarget = false; - if (size.contains(position)) { - hitTarget = hitTestSelf(position); - if (hitTarget) { - // if hit add to results - result.add(BoxHitTestEntry(this, position)); - } - } - - // Let the hit continue to targets behind the animation. - if (behavior == RiveHitTestBehavior.transparent) { - return false; - } - - // Opaque will always return true, translucent will return true if we - // hit a Rive listener target. - return hitTarget; - } - - @override - bool hitTestSelf(Offset screenOffset) { - switch (behavior) { - case RiveHitTestBehavior.opaque: - return true; // Always hit - case RiveHitTestBehavior.translucent: - case RiveHitTestBehavior.transparent: - { - // test to see if any Rive animation listeners were hit - final artboardPosition = _toArtboard(screenOffset); - final stateMachineControllers = _artboard.animationControllers - .whereType(); - for (final stateMachineController in stateMachineControllers) { - if (stateMachineController.hitTest(artboardPosition)) { - return true; - } - } - } - } - return false; - } - - // TODO: A possible alternative to [isTouchScrollEnabled] is to allow - // users to set custom recognizers. Or for us to provide - // heuristics on whether a Rive graphic has certain gestures: - // - Pointer down/up - // - Drag - // - Scroll - // - etc. - // With this information we can better decide which recognizers to use, - // while optionally allowing end users to override it, or provide custom ones. - // Can be considered for `rive_native`. - // - // https://api.flutter.dev/flutter/gestures/GestureArenaManager-class.html - final _recognizer = ImmediateMultiDragGestureRecognizer(); - - @override - void handleEvent(PointerEvent event, HitTestEntry entry) { - assert(debugHandleEvent(event, entry)); - if (!enableHitTests || !attached) { - return; - } - if (event is PointerDownEvent) { - _hitHelper(event, (controller, artboardPosition) { - final hitResult = controller.pointerDown(artboardPosition, event); - - if (hitResult != HitResult.none && !isTouchScrollEnabled) { - _recognizer.addPointer(event); - } - }); - } - if (event is PointerUpEvent) { - _hitHelper( - event, - (controller, artboardPosition) => - controller.pointerUp(artboardPosition), - ); - } - if (event is PointerMoveEvent) { - _hitHelper( - event, - (controller, artboardPosition) => - controller.pointerMove(artboardPosition), - ); - } - if (event is PointerHoverEvent) { - _hitHelper( - event, - (controller, artboardPosition) => - controller.pointerMove(artboardPosition), - ); - } - } - - @override - PointerEnterEventListener? get onEnter => (event) { - if (!enableHitTests) return; - _hitHelper( - event, - (controller, artboardPosition) => - controller.pointerEnter(artboardPosition), - ); - }; - - @override - PointerExitEventListener? get onExit => (event) { - if (!enableHitTests) return; - _hitHelper( - event, - (controller, artboardPosition) => - controller.pointerExit(artboardPosition), - ); - }; - - @override - MouseCursor get cursor => _cursor; - MouseCursor _cursor; - set cursor(MouseCursor value) { - if (_cursor != value) { - _cursor = value; - // A repaint is needed in order to trigger a device update of - // [MouseTracker] so that this new value can be found. - markNeedsPaint(); - } - } - - @override - bool get validForMouseTracker => _validForMouseTracker; - bool _validForMouseTracker; - - /// {@macro Rive.behavior} - RiveHitTestBehavior behavior; - - @override - void attach(PipelineOwner owner) { - super.attach(owner); - _validForMouseTracker = true; - } - - @override - void detach() { - // It's possible that the renderObject be detached during mouse events - // dispatching, set the [MouseTrackerAnnotation.validForMouseTracker] false - // to prevent the callbacks from being called. - _validForMouseTracker = false; - super.detach(); - } - - @override - void dispose() { - _artboard.redraw.removeListener(scheduleRepaint); - _recognizer.dispose(); - super.dispose(); - } - - @override - AABB get aabb { - var width = _artboard.width; - var height = _artboard.height; - return AABB.fromValues(0, 0, width, height); - } - - @override - bool advance(double elapsedSeconds) => - _artboard.isPlaying && - _artboard.advance(elapsedSeconds * _speedMultiplier, nested: true); - - @override - void beforeDraw(Canvas canvas, Offset offset) { - // Apply clip rect if provided and return early - if (clipRect != null) { - return canvas.clipRect(clipRect!); - } - if (artboard.clip) { - canvas.clipRect(offset & size); - } - } - - @override - void draw(Canvas canvas, Mat2D viewTransform) { - canvas.transform(viewTransform.mat4); - artboard.draw(canvas); - } -} diff --git a/lib/src/rive_core/animation/advanceable_state.dart b/lib/src/rive_core/animation/advanceable_state.dart deleted file mode 100644 index 4936773..0000000 --- a/lib/src/rive_core/animation/advanceable_state.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/generated/animation/advanceable_state_base.dart'; -export 'package:rive/src/generated/animation/advanceable_state_base.dart'; - -abstract class AdvanceableState extends AdvanceableStateBase { - @override - void speedChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/animation/animation.dart b/lib/src/rive_core/animation/animation.dart deleted file mode 100644 index c2228da..0000000 --- a/lib/src/rive_core/animation/animation.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/animation_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/animation_base.dart'; - -class Animation extends AnimationBase { - Artboard? _artboard; - - Artboard? get artboard => _artboard; - set artboard(Artboard? value) { - if (_artboard == value) { - return; - } - - _artboard?.internalRemoveAnimation(this); - _artboard = value; - _artboard?.internalAddAnimation(this); - } - - @override - void onAddedDirty() {} - - @override - void onAdded() {} - - @override - bool validate() => super.validate() && _artboard != null; - - @override - void nameChanged(String from, String to) {} -} diff --git a/lib/src/rive_core/animation/animation_reset_factory.dart b/lib/src/rive_core/animation/animation_reset_factory.dart deleted file mode 100644 index 7840cad..0000000 --- a/lib/src/rive_core/animation/animation_reset_factory.dart +++ /dev/null @@ -1,284 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/animation_state.dart'; -import 'package:rive/src/rive_core/animation/blend_state.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; -import 'package:rive/src/rive_core/animation/keyframe_color.dart'; -import 'package:rive/src/rive_core/animation/keyframe_double.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive_common/utilities.dart'; - -bool _isDouble(int propertyKey, Core object) { - final coreType = RiveCoreContext.coreType(propertyKey); - return coreType == RiveCoreContext.doubleType; -} - -bool _isColor(int propertyKey, Core object) { - final coreType = RiveCoreContext.coreType(propertyKey); - return coreType == RiveCoreContext.colorType; -} - -class AnimationReset { - BinaryReader? _reader; - late final BinaryWriter _writer; - int _dataSize = 0; - - AnimationReset() { - _writer = BinaryWriter(endian: Endian.big); - } - - int get size { - return _writer.maxSize; - } - - void writeObjectId(int id) { - _writer.writeVarUint(id); - } - - void writeTotalProperties(int totalProperties) { - _writer.writeVarUint(totalProperties); - } - - void writePropertyKey(int propertyKey) { - _writer.writeVarUint(propertyKey); - } - - void writeColor(int value) { - _writer.writeInt32(value); - } - - void writeDouble(double value) { - _writer.writeFloat32(value); - } - - void clear() { - _writer.writeIndex = 0; - } - - void createReader() { - // We only need to regenerate the reader if its size is smaller than the - // writer size - _dataSize = _writer.size; - if (_reader == null || _reader!.size < _writer.size) { - _reader = BinaryReader(_writer.buffer, endian: Endian.big); - } - } - - int resolveId(int intId) { - return intId; - } - - void apply(CoreContext core) { - BinaryReader reader = _reader!; - reader.readIndex = 0; - while (reader.readIndex < _dataSize) { - // First we read the object's id - final objectIntId = reader.readVarUint(); - final objectId = resolveId(objectIntId); - final object = core.resolve(objectId); - // Second we read how many keyframed properties it has - final totalProperties = reader.readVarUint(); - int currentPropertyIndex = 0; - while (currentPropertyIndex < totalProperties) { - // Third we read the property key for each property - final propertyKey = reader.readVarUint(); - // Fourth we read the property value for each property - if (_isDouble(propertyKey, object!)) { - double value = reader.readFloat32(); - RiveCoreContext.setDouble(object, propertyKey, value); - } else if (_isColor(propertyKey, object)) { - int value = reader.readInt32(); - RiveCoreContext.setColor(object, propertyKey, value); - } - currentPropertyIndex += 1; - } - } - } -} - -class _KeyedProperty { - final KeyedProperty property; - final bool isBaseline; - _KeyedProperty(this.property, this.isBaseline); - bool readProperty() { - if (property.propertyKey == 1) { - return true; - } - return false; - } - - int get propertyKey { - return property.propertyKey; - } - - int get size { - return 1 + 4; // property id + float value - } -} - -class _KeyedObject { - final List<_KeyedProperty> properties = []; - final KeyedObject data; - final Set visitedProperties = {}; - _KeyedObject(this.data); - void addProperties( - List props, Core object, bool storeAsBaseline) { - for (final property in props) { - if (!visitedProperties.contains(property.propertyKey)) { - visitedProperties.add(property.propertyKey); - if (_isColor(property.propertyKey, object) || - _isDouble(property.propertyKey, object)) { - properties.add(_KeyedProperty(property, storeAsBaseline)); - } - } - } - } - - int get size { - if (properties.isEmpty) { - return 0; - } - int _size = 1 + 1; // object id + number of properties - for (final property in properties) { - _size += property.size; - } - return _size; - } -} - -class _AnimationsData { - int size = 0; - - List<_KeyedObject> keyedObjects = []; - Map visitedObjects = {}; - _AnimationsData(List animations, CoreContext core, - bool useFirstAsBaseline) { - bool isFirstAnimation = useFirstAsBaseline; - for (final animation in animations) { - animation.keyedObjects.forEach((keyedObject) { - final objectIntId = resolveId(keyedObject.objectId); - final object = core.resolve(keyedObject.objectId); - if (!visitedObjects.containsKey(objectIntId)) { - visitedObjects[objectIntId] = _KeyedObject(keyedObject); - keyedObjects.add(visitedObjects[objectIntId]!); - } - visitedObjects[objectIntId]!.addProperties( - keyedObject.keyedProperties.toList(), object!, isFirstAnimation); - }); - isFirstAnimation = false; - } - for (final object in keyedObjects) { - size += object.size; - } - } - - int resolveId(int intId) { - return intId; - } - - void writeObjects(AnimationReset animationReset, CoreContext core) { - keyedObjects.forEach((keyedObject) { - // We might have added keyed objects but no properties need resetting - if (keyedObject.properties.isNotEmpty) { - int objectIntId = resolveId(keyedObject.data.objectId); - final object = core.resolve(keyedObject.data.objectId); - - animationReset.writeObjectId(objectIntId); - animationReset.writeTotalProperties(keyedObject.properties.length); - - for (final property in keyedObject.properties) { - if (_isColor(property.propertyKey, object!)) { - animationReset.writePropertyKey(property.propertyKey); - if (property.isBaseline) { - animationReset.writeColor( - (property.property.keyframes.first as KeyFrameColor).value); - } else { - animationReset.writeColor(RiveCoreContext.getColor( - core.resolve(keyedObject.data.objectId), - property.propertyKey)); - } - } else if (_isDouble(property.propertyKey, object)) { - animationReset.writePropertyKey(property.propertyKey); - if (property.isBaseline) { - animationReset.writeDouble( - (property.property.keyframes.first as KeyFrameDouble).value); - } else { - animationReset.writeDouble(RiveCoreContext.getDouble( - core.resolve(keyedObject.data.objectId), - property.propertyKey)); - } - } - } - } - }); - animationReset.createReader(); - } -} - -List _pool = []; - -AnimationReset fromAnimations(List animations, - CoreContext core, bool useFirstAsBaseline) { - final animationData = _AnimationsData(animations, core, useFirstAsBaseline); - AnimationReset? animationReset; - for (final pooled in _pool) { - if (animationReset == null || animationReset.size > pooled.size) { - animationReset = pooled; - } - if (pooled.size >= animationData.size) { - break; - } - } - if (animationReset != null) { - _pool.remove(animationReset); - } else { - animationReset = AnimationReset(); - } - animationData.writeObjects(animationReset, core); - return animationReset; -} - -List _fromState( - StateInstance? stateInstance, CoreContext core) { - List animations = []; - if (stateInstance != null) { - final state = stateInstance.state; - if (state is AnimationState && state.animation != null) { - animations.add(state.animation!); - } else if (state is BlendState) { - state.animations.forEach((blend1DAnimation) { - final animation = - core.resolve(blend1DAnimation.animationId); - if (animation != null) { - animations.add(animation); - } - }); - } - } - return animations; -} - -AnimationReset fromStates( - StateInstance? stateFrom, StateInstance? currentState, CoreContext core) { - List animations = []; - animations.addAll(_fromState(currentState, core)); - animations.addAll(_fromState(stateFrom, core)); - return fromAnimations(animations, core, false); -} - -void release(AnimationReset value) { - value.clear(); - int index = 0; - while (index < _pool.length) { - final animationReset = _pool.elementAt(index); - if (animationReset.size > value.size) { - break; - } - index++; - } - _pool.insert(index, value); - // TODO @hernan set a maximum pooling space. Perhaps remove the smallest - // sizes? - // if (_pool.length > 10) {} -} diff --git a/lib/src/rive_core/animation/animation_state.dart b/lib/src/rive_core/animation/animation_state.dart deleted file mode 100644 index e6d6303..0000000 --- a/lib/src/rive_core/animation/animation_state.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/animation_state_base.dart'; -import 'package:rive/src/rive_core/animation/animation_state_instance.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/animation_state_base.dart'; - -class AnimationState extends AnimationStateBase { - @override - String toString() { - return '${super.toString()} ($id) -> ${_animation?.name}'; - } - - LinearAnimation? _animation; - LinearAnimation? get animation => _animation; - set animation(LinearAnimation? value) { - if (_animation == value) { - return; - } - - _animation = value; - animationId = value?.id ?? Core.missingId; - } - - @override - void animationIdChanged(int from, int to) { - animation = id == Core.missingId ? null : context.resolve(to); - } - - @override - StateInstance makeInstance() { - if (animation == null) { - // Failed to load at runtime/some new type we don't understand. - return SystemStateInstance(this); - } - - return AnimationStateInstance(this); - } - - // We keep the importer code here so that we can inject this for runtime. - // #2690 - @override - bool import(ImportStack stack) { - var importer = stack.latest(ArtboardBase.typeKey); - if (importer == null) { - return false; - } - - if (animationId >= 0 && animationId < importer.artboard.animations.length) { - var found = importer.artboard.animations[animationId]; - if (found is LinearAnimation) { - animation = found; - } - } - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/animation_state_instance.dart b/lib/src/rive_core/animation/animation_state_instance.dart deleted file mode 100644 index 17ff21c..0000000 --- a/lib/src/rive_core/animation/animation_state_instance.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/animation_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -/// Simple wrapper around [LinearAnimationInstance] making it compatible with -/// the [StateMachine]'s [StateInstance] interface. -class AnimationStateInstance extends StateInstance { - final LinearAnimationInstance animationInstance; - - AnimationStateInstance(AnimationState state) - : assert(state.animation != null), - animationInstance = LinearAnimationInstance( - state.animation!, - speedMultiplier: state.speed, - ), - super(state); - - @override - void advance(double seconds, StateMachineController controller) => - animationInstance.advance( - seconds * state.speed, - callbackReporter: controller, - ); - - @override - void apply(CoreContext core, double mix) => animationInstance.animation - .apply(animationInstance.time, coreContext: core, mix: mix); - - @override - bool get keepGoing => animationInstance.shouldKeepGoing(state.speed); - - @override - void clearSpilledTime() => animationInstance.clearSpilledTime(); -} diff --git a/lib/src/rive_core/animation/any_state.dart b/lib/src/rive_core/animation/any_state.dart deleted file mode 100644 index 19fb579..0000000 --- a/lib/src/rive_core/animation/any_state.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:rive/src/generated/animation/any_state_base.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; - -export 'package:rive/src/generated/animation/any_state_base.dart'; - -class AnyState extends AnyStateBase { - @override - StateInstance makeInstance() => SystemStateInstance(this); -} diff --git a/lib/src/rive_core/animation/blend_animation.dart b/lib/src/rive_core/animation/blend_animation.dart deleted file mode 100644 index 3a833b2..0000000 --- a/lib/src/rive_core/animation/blend_animation.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/blend_animation_base.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/blend_animation_base.dart'; - -abstract class BlendAnimation extends BlendAnimationBase { - LinearAnimation? _animation; - LinearAnimation? get animation => _animation; - - @override - void animationIdChanged(int from, int to) { - _animation = context.resolve(to); - } - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool import(ImportStack importStack) { - var importer = - importStack.latest(LayerStateBase.typeKey); - if (importer == null || !importer.addBlendAnimation(this)) { - return false; - } - var artboardImporter = - importStack.latest(ArtboardBase.typeKey); - if (artboardImporter == null) { - return false; - } - - if (animationId >= 0 && - animationId < artboardImporter.artboard.animations.length) { - var found = artboardImporter.artboard.animations[animationId]; - if (found is LinearAnimation) { - _animation = found; - } - } - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/blend_animation_1d.dart b/lib/src/rive_core/animation/blend_animation_1d.dart deleted file mode 100644 index ab31291..0000000 --- a/lib/src/rive_core/animation/blend_animation_1d.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/generated/animation/blend_animation_1d_base.dart'; -export 'package:rive/src/generated/animation/blend_animation_1d_base.dart'; - -class BlendAnimation1D extends BlendAnimation1DBase { - @override - void valueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/animation/blend_animation_direct.dart b/lib/src/rive_core/animation/blend_animation_direct.dart deleted file mode 100644 index afe0685..0000000 --- a/lib/src/rive_core/animation/blend_animation_direct.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/blend_animation_direct_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_number.dart'; - -export 'package:rive/src/generated/animation/blend_animation_direct_base.dart'; - -enum DirectBlendSource { inputId, mixValue } - -class BlendAnimationDirect extends BlendAnimationDirectBase { - StateMachineNumber? _input; - StateMachineNumber? get input => _input; - - @override - void inputIdChanged(int from, int to) {} - - @override - bool import(ImportStack stack) { - var importer = stack.latest(StateMachineBase.typeKey); - if (importer == null) { - return false; - } - if (inputId >= 0 && inputId < importer.machine.inputs.length) { - var found = importer.machine.inputs[inputId]; - if (found is StateMachineNumber) { - _input = found; - inputId = found.id; - } - } - - return super.import(stack); - } - - @override - void blendSourceChanged(int from, int to) {} - - @override - void mixValueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/animation/blend_state.dart b/lib/src/rive_core/animation/blend_state.dart deleted file mode 100644 index 91d74cb..0000000 --- a/lib/src/rive_core/animation/blend_state.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/blend_state_base.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; - -export 'package:rive/src/generated/animation/blend_state_base.dart'; - -// -abstract class BlendState extends BlendStateBase { - final BlendAnimations _animations = BlendAnimations(); - BlendAnimations get animations => _animations; - - void internalAddAnimation(T animation) { - assert(!_animations.contains(animation), - 'shouldn\'t already contain the animation'); - _animations.add(animation); - } - - void internalRemoveAnimation(T animation) { - _animations.remove(animation); - } -} diff --git a/lib/src/rive_core/animation/blend_state_1d.dart b/lib/src/rive_core/animation/blend_state_1d.dart deleted file mode 100644 index dce4a42..0000000 --- a/lib/src/rive_core/animation/blend_state_1d.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/blend_state_1d_base.dart'; -import 'package:rive/src/rive_core/animation/blend_state_1d_instance.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_number.dart'; - -export 'package:rive/src/generated/animation/blend_state_1d_base.dart'; - -class BlendState1D extends BlendState1DBase { - StateMachineNumber? _input; - StateMachineNumber? get input => _input; - - void _changeInput(StateMachineNumber? value) { - if (value == _input) { - return; - } - - _input = value; - } - - @override - void inputIdChanged(int from, int to) { - _changeInput(context.resolve(to)); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - _changeInput(context.resolve(inputId)); - } - - @override - StateInstance makeInstance() => BlendState1DInstance(this); - - @override - bool import(ImportStack stack) { - var importer = stack.latest(StateMachineBase.typeKey); - if (importer == null) { - return false; - } - if (inputId >= 0 && inputId < importer.machine.inputs.length) { - var found = importer.machine.inputs[inputId]; - if (found is StateMachineNumber) { - _input = found; - inputId = found.id; - } - } - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/blend_state_1d_instance.dart b/lib/src/rive_core/animation/blend_state_1d_instance.dart deleted file mode 100644 index 5016852..0000000 --- a/lib/src/rive_core/animation/blend_state_1d_instance.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'package:rive/src/rive_core/animation/animation_reset_factory.dart' - as animation_reset_factory; -import 'package:rive/src/rive_core/animation/blend_animation_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_state_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_state_instance.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/layer_state_flags.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -/// [BlendState1D] mixing logic that runs inside the [StateMachine]. -class BlendState1DInstance - extends BlendStateInstance { - late animation_reset_factory.AnimationReset? animationReset; - BlendState1DInstance(BlendState1D state) : super(state) { - animationInstances.sort( - (a, b) => a.blendAnimation.value.compareTo(b.blendAnimation.value)); - - animationReset = - state.flags & LayerStateFlags.reset == LayerStateFlags.reset - ? animation_reset_factory.fromAnimations( - animationInstances - .map((animationInstance) => - animationInstance.animationInstance.animation) - .toList(growable: false), - state.context, - true) - : null; - } - - /// Binary find the closest animation index. - int animationIndex(double value) { - int idx = 0; - int mid = 0; - double closestValue = 0; - int start = 0; - int end = animationInstances.length - 1; - - while (start <= end) { - mid = (start + end) >> 1; - closestValue = animationInstances[mid].blendAnimation.value; - if (closestValue < value) { - start = mid + 1; - } else if (closestValue > value) { - end = mid - 1; - } else { - idx = start = mid; - break; - } - - idx = start; - } - return idx; - } - - BlendStateAnimationInstance? _from; - BlendStateAnimationInstance? _to; - - @override - void advance(double seconds, StateMachineController controller) { - super.advance(seconds, controller); - dynamic inputValue = - controller.getInputValue((state as BlendState1D).inputId); - var value = (inputValue is double - ? inputValue - : (state as BlendState1D).input?.value) ?? - 0; - int index = animationIndex(value); - _to = index >= 0 && index < animationInstances.length - ? animationInstances[index] - : null; - _from = index - 1 >= 0 && index - 1 < animationInstances.length - ? animationInstances[index - 1] - : null; - - double mix, mixFrom; - if (_to == null || - _from == null || - _to!.blendAnimation.value == _from!.blendAnimation.value) { - mix = mixFrom = 1; - } else { - mix = (value - _from!.blendAnimation.value) / - (_to!.blendAnimation.value - _from!.blendAnimation.value); - mixFrom = 1.0 - mix; - } - - var toValue = _to?.blendAnimation.value; - var fromValue = _from?.blendAnimation.value; - for (final animation in animationInstances) { - if (animation.blendAnimation.value == toValue) { - animation.mix = mix; - } else if (animation.blendAnimation.value == fromValue) { - animation.mix = mixFrom; - } else { - animation.mix = 0; - } - } - } - - @override - void apply(CoreContext core, double mix) { - if (animationReset != null) { - animationReset!.apply(core); - } - super.apply(core, mix); - } -} diff --git a/lib/src/rive_core/animation/blend_state_direct.dart b/lib/src/rive_core/animation/blend_state_direct.dart deleted file mode 100644 index 4abc4cf..0000000 --- a/lib/src/rive_core/animation/blend_state_direct.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:rive/src/generated/animation/blend_state_direct_base.dart'; -import 'package:rive/src/rive_core/animation/blend_state_direct_instance.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; - -export 'package:rive/src/generated/animation/blend_state_direct_base.dart'; - -class BlendStateDirect extends BlendStateDirectBase { - @override - StateInstance makeInstance() => BlendStateDirectInstance(this); -} diff --git a/lib/src/rive_core/animation/blend_state_direct_instance.dart b/lib/src/rive_core/animation/blend_state_direct_instance.dart deleted file mode 100644 index 950cf45..0000000 --- a/lib/src/rive_core/animation/blend_state_direct_instance.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:rive/src/rive_core/animation/blend_animation_direct.dart'; -import 'package:rive/src/rive_core/animation/blend_state_direct.dart'; -import 'package:rive/src/rive_core/animation/blend_state_instance.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -/// [BlendStateDirect] mixing logic that runs inside the [StateMachine]. -class BlendStateDirectInstance - extends BlendStateInstance { - BlendStateDirectInstance(BlendStateDirect state) : super(state); - - @override - void advance(double seconds, StateMachineController controller) { - super.advance(seconds, controller); - for (final animation in animationInstances) { - if (animation.blendAnimation.blendSource == - DirectBlendSource.inputId.index) { - dynamic inputValue = - controller.getInputValue(animation.blendAnimation.inputId); - var value = (inputValue is double - ? inputValue - : animation.blendAnimation.input?.value) ?? - 0; - animation.mix = (value / 100).clamp(0, 1); - } else { - var value = animation.blendAnimation.mixValue; - animation.mix = (value / 100).clamp(0, 1); - } - } - } -} diff --git a/lib/src/rive_core/animation/blend_state_instance.dart b/lib/src/rive_core/animation/blend_state_instance.dart deleted file mode 100644 index ace663f..0000000 --- a/lib/src/rive_core/animation/blend_state_instance.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; -import 'package:rive/src/rive_core/animation/blend_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -/// Individual animation in a blend state instance. -class BlendStateAnimationInstance { - final T blendAnimation; - final LinearAnimationInstance animationInstance; - double mix = 0; - - BlendStateAnimationInstance(this.blendAnimation) - : animationInstance = LinearAnimationInstance(blendAnimation.animation!); -} - -/// Generic blend state instance which works for [BlendState]s -/// where T represents the BlendState and K the BlendAnimation. -abstract class BlendStateInstance, - K extends BlendAnimation> extends StateInstance { - final List> animationInstances; - BlendStateInstance(T state) - : animationInstances = state.animations - .where((animation) => animation.animation != null) - .map(BlendStateAnimationInstance.new) - .toList(growable: false), - super(state); - - @override - bool get keepGoing => true; - - @mustCallSuper - @override - void advance(double seconds, StateMachineController controller) { - // Advance all the animations in the blend state - // NOTE: we are intentionally ignoring the animationInstances' keepGoing - // return value. - // Blend states need to keep blending forever, as even if the animation - // does not change the mix values may - for (final animation in animationInstances) { - if (animation.animationInstance.keepGoing) { - // Should animations with m_Mix == 0.0 advance? They will trigger events - // and the event properties (if any) will not be updated by - // animationInstance.apply. - animation.animationInstance.advance( - seconds, - callbackReporter: controller, - ); - } - } - } - - @override - void apply(CoreContext core, double mix) { - for (final animation in animationInstances) { - double m = mix * animation.mix; - if (m == 0) { - continue; - } - animation.animationInstance.animation - .apply(animation.animationInstance.time, coreContext: core, mix: m); - } - } -} diff --git a/lib/src/rive_core/animation/blend_state_transition.dart b/lib/src/rive_core/animation/blend_state_transition.dart deleted file mode 100644 index d76c7d0..0000000 --- a/lib/src/rive_core/animation/blend_state_transition.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:rive/src/generated/animation/blend_state_transition_base.dart'; -import 'package:rive/src/rive_core/animation/blend_animation.dart'; -import 'package:rive/src/rive_core/animation/blend_state_instance.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; - -export 'package:rive/src/generated/animation/blend_state_transition_base.dart'; - -class BlendStateTransition extends BlendStateTransitionBase { - BlendAnimation? exitBlendAnimation; - - @override - LinearAnimationInstance? exitTimeAnimationInstance(StateInstance stateFrom) { - if (stateFrom is BlendStateInstance) { - for (final blendAnimation in stateFrom.animationInstances) { - if (blendAnimation.blendAnimation == exitBlendAnimation) { - return blendAnimation.animationInstance; - } - } - } - return null; - } - - @override - LinearAnimation? exitTimeAnimation(LayerState stateFrom) => - exitBlendAnimation?.animation; - - @override - void exitBlendAnimationIdChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/animation/cubic_ease_interpolator.dart b/lib/src/rive_core/animation/cubic_ease_interpolator.dart deleted file mode 100644 index 88b8280..0000000 --- a/lib/src/rive_core/animation/cubic_ease_interpolator.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:rive/src/generated/animation/cubic_ease_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; - -class Cubic extends CubicEase { - final InterpolatorCubicFactor _x; - final double y1, y2; - Cubic(double x1, this.y1, double x2, this.y2) - : _x = InterpolatorCubicFactor(x1, x2); - - @override - double transform(double f) { - return InterpolatorCubicFactor.calcBezier(_x.getT(f), y1, y2); - } -} - -abstract class CubicEase { - double transform(double t); - - static CubicEase make(double x1, double y1, double x2, double y2) { - if (x1 == y1 && x2 == y2) { - return LinearCubicEase(); - } else { - return Cubic(x1, y1, x2, y2); - } - } -} - -class LinearCubicEase extends CubicEase { - @override - double transform(double f) { - return f; - } -} - -class CubicEaseInterpolator extends CubicEaseInterpolatorBase { - CubicEase _ease = CubicEase.make(0.42, 0, 0.58, 1); - - @override - double transform(double value) => _ease.transform(value); - - @override - double transformValue(double from, double to, double value) => - from + (to - from) * _ease.transform(value); - - @override - void updateInterpolator() { - _ease = CubicEase.make(x1, y1, x2, y2); - super.updateInterpolator(); - } -} diff --git a/lib/src/rive_core/animation/cubic_interpolator.dart b/lib/src/rive_core/animation/cubic_interpolator.dart deleted file mode 100644 index 5d85770..0000000 --- a/lib/src/rive_core/animation/cubic_interpolator.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/cubic_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; - -export 'package:rive/src/generated/animation/cubic_interpolator_base.dart'; - -const int newtonIterations = 4; - -// Implements https://github.com/gre/bezier-easing/blob/master/src/index.js -const double newtonMinSlope = 0.001; -const double sampleStepSize = 1.0 / (splineTableSize - 1.0); -const int splineTableSize = 11; -const int subdivisionMaxIterations = 10; - -const double subdivisionPrecision = 0.0000001; - -abstract class CubicInterface { - double get x1; - set x1(double value); - - double get x2; - set x2(double value); - - double get y1; - set y1(double value); - - double get y2; - set y2(double value); -} - -// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. -abstract class CubicInterpolator extends CubicInterpolatorBase - implements CubicInterface { - @override - bool equalParameters(Interpolator other) { - if (other is CubicInterpolator) { - return x1 == other.x1 && - x2 == other.x2 && - y1 == other.y1 && - y2 == other.y2; - } - return false; - } - - @override - void onAddedDirty() {} - - @override - double transform(double value); - - @override - double transformValue(double from, double to, double value); - - @override - void x1Changed(double from, double to) => updateInterpolator(); - - @override - void x2Changed(double from, double to) => updateInterpolator(); - - @override - void y1Changed(double from, double to) => updateInterpolator(); - - @override - void y2Changed(double from, double to) => updateInterpolator(); -} - -// Helper to convert a factor in cubic space to t value. We use this to compute -// the t value to use to evaluate the y cubic for animation values. -class InterpolatorCubicFactor { - final Float64List _values = Float64List(splineTableSize); - final double x1, x2; - InterpolatorCubicFactor(this.x1, this.x2) { - // Precompute values table - for (int i = 0; i < splineTableSize; ++i) { - _values[i] = calcBezier(i * sampleStepSize, x1, x2); - } - } - - double getT(double x) { - double intervalStart = 0.0; - int currentSample = 1; - int lastSample = splineTableSize - 1; - - for (; - currentSample != lastSample && _values[currentSample] <= x; - ++currentSample) { - intervalStart += sampleStepSize; - } - --currentSample; - - // Interpolate to provide an initial guess for t - var dist = (x - _values[currentSample]) / - (_values[currentSample + 1] - _values[currentSample]); - var guessForT = intervalStart + dist * sampleStepSize; - - var initialSlope = getSlope(guessForT, x1, x2); - if (initialSlope >= newtonMinSlope) { - for (int i = 0; i < newtonIterations; ++i) { - double currentSlope = getSlope(guessForT, x1, x2); - if (currentSlope == 0.0) { - return guessForT; - } - double currentX = calcBezier(guessForT, x1, x2) - x; - guessForT -= currentX / currentSlope; - } - return guessForT; - } else if (initialSlope == 0.0) { - return guessForT; - } else { - double aB = intervalStart + sampleStepSize; - double currentX, currentT; - int i = 0; - do { - currentT = intervalStart + (aB - intervalStart) / 2.0; - currentX = calcBezier(currentT, x1, x2) - x; - if (currentX > 0.0) { - aB = currentT; - } else { - intervalStart = currentT; - } - } while (currentX.abs() > subdivisionPrecision && - ++i < subdivisionMaxIterations); - return currentT; - } - } - - static double calcBezier(double aT, double aA1, double aA2) { - return (((1.0 - 3.0 * aA2 + 3.0 * aA1) * aT + (3.0 * aA2 - 6.0 * aA1)) * - aT + - (3.0 * aA1)) * - aT; - } - -// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. - static double getSlope(double aT, double aA1, double aA2) { - return 3.0 * (1.0 - 3.0 * aA2 + 3.0 * aA1) * aT * aT + - 2.0 * (3.0 * aA2 - 6.0 * aA1) * aT + - (3.0 * aA1); - } -} diff --git a/lib/src/rive_core/animation/cubic_interpolator_component.dart b/lib/src/rive_core/animation/cubic_interpolator_component.dart deleted file mode 100644 index 74380e1..0000000 --- a/lib/src/rive_core/animation/cubic_interpolator_component.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:rive/src/generated/animation/cubic_interpolator_component_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_ease_interpolator.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/animation/cubic_interpolator_component_base.dart'; - -class CubicInterpolatorComponent extends CubicInterpolatorComponentBase - implements Interpolator, CubicInterface { - CubicEase _ease = CubicEase.make(0.42, 0, 0.58, 1); - - @override - void update(int dirt) {} - - @override - void x1Changed(double from, double to) => _updateStoredCubic(); - - @override - void x2Changed(double from, double to) => _updateStoredCubic(); - - @override - void y1Changed(double from, double to) => _updateStoredCubic(); - - @override - void y2Changed(double from, double to) => _updateStoredCubic(); - - @override - bool equalParameters(Interpolator other) { - if (other is CubicInterpolatorComponent) { - return x1 == other.x1 && - x2 == other.x2 && - y1 == other.y1 && - y2 == other.y2; - } - return false; - } - - @override - double transform(double value) => _ease.transform(value); - - @override - void onAddedDirty() { - super.onAddedDirty(); - _updateStoredCubic(); - } - - @override - double transformValue(double from, double to, double value) => - from + (to - from) * _ease.transform(value); - - void _updateStoredCubic() { - _ease = CubicEase.make(x1, y1, x2, y2); - - parent?.onDirty(ComponentDirt.interpolator); - } -} diff --git a/lib/src/rive_core/animation/cubic_value_interpolator.dart b/lib/src/rive_core/animation/cubic_value_interpolator.dart deleted file mode 100644 index d8408b2..0000000 --- a/lib/src/rive_core/animation/cubic_value_interpolator.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:rive/src/generated/animation/cubic_value_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; - -export 'package:rive/src/generated/animation/cubic_value_interpolator_base.dart'; - -class _CubicValue { - final InterpolatorCubicFactor _x; - - // at^3 + bt^2 + ct + d - final double a; - final double b; - final double c; - final double d; - - _CubicValue(double x1, double x2, double y1, double y2, double y3, double y4) - : _x = InterpolatorCubicFactor(x1, x2), - a = y4 + 3 * (y2 - y3) - y1, - b = 3 * (y3 - y2 * 2 + y1), - c = 3 * (y2 - y1), - d = y1; - - double transform(double f) { - var t = _x.getT(f); - return ((a * t + b) * t + c) * t + d; - } -} - -class CubicValueInterpolator extends CubicValueInterpolatorBase { - _CubicValue _cubic = _CubicValue(0, 1, 0.42, 0, 0.58, 1); - - @override - bool equalParameters(Interpolator other) { - if (other is CubicValueInterpolator) { - return x1 == other.x1 && - x2 == other.x2 && - y1 == other.y1 && - y2 == other.y2; - } - return false; - } - - @override - double transform(double value) => throw UnsupportedError( - 'Transform not supported on Cubic Value Interpolator.'); - - double _from = 0, _to = 0; - @override - double transformValue(double from, double to, double value) { - if (_from != from || _to != to) { - _from = from; - _to = to; - updateInterpolator(); - } - return _cubic.transform(value); - } - - @override - void updateInterpolator() { - _cubic = _CubicValue(x1, x2, _from, y1, y2, _to); - super.updateInterpolator(); - } -} diff --git a/lib/src/rive_core/animation/elastic_interpolator.dart b/lib/src/rive_core/animation/elastic_interpolator.dart deleted file mode 100644 index 07e9a66..0000000 --- a/lib/src/rive_core/animation/elastic_interpolator.dart +++ /dev/null @@ -1,133 +0,0 @@ -// ignore_for_file: parameter_assignments - -import 'dart:math'; - -import 'package:rive/src/generated/animation/elastic_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; - -export 'package:rive/src/generated/animation/elastic_interpolator_base.dart'; - -enum Easing { - easeIn, - easeOut, - easeInOut, -} - -class ElasticEase { - final double amplitude; - final double s; - final double period; - - ElasticEase(this.amplitude, this.period) - : s = amplitude < 1.0 - ? period / 4 - : period / (2 * pi) * asin(1.0 / amplitude); - - double computeActualAmplitude(double time) { - if (amplitude < 1.0) { - /// We use this when the amplitude is less than 1.0 (amplitude is - /// described as factor of change in value). We also precompute s which is - /// the effective starting period we use to align the decaying sin with - /// our keyframe. - double t = s.abs(); - if (time.abs() < t) { - double l = time.abs() / t; - return (amplitude * l) + (1.0 - l); - } - } - - return amplitude; - } - - double easeOut(double value) { - var time = value; - - var actualAmplitude = computeActualAmplitude(time); - - return (actualAmplitude * - pow(2, 10 * -time) * - sin((time - s) * (2 * pi) / period)) + - 1; - } - - double easeIn(double value) { - var time = value - 1; - - var actualAmplitude = computeActualAmplitude(time); - - return -(actualAmplitude * - pow(2, 10 * time) * - sin((-time - s) * (2 * pi) / period)); - } - - double easeInOut(double value) { - var time = value * 2 - 1; - var actualAmplitude = computeActualAmplitude(time); - if (time < 0) { - return -0.5 * - actualAmplitude * - pow(2, 10 * time) * - sin((-time - s) * (2 * pi) / period); - } else { - return 0.5 * - (actualAmplitude * - pow(2, 10 * -time) * - sin((time - s) * (2 * pi) / period)) + - 1; - } - } -} - -class ElasticInterpolator extends ElasticInterpolatorBase { - ElasticEase _elastic = ElasticEase(1.0, 0.5); - - @override - bool equalParameters(Interpolator other) { - if (other is ElasticInterpolator) { - return easingValue == other.easingValue && - amplitude == other.amplitude && - period == other.period; - } - return false; - } - - @override - void onAddedDirty() {} - - @override - double transform(double value) { - switch (easing) { - case Easing.easeIn: - return _elastic.easeIn(value); - case Easing.easeOut: - return _elastic.easeOut(value); - case Easing.easeInOut: - return _elastic.easeInOut(value); - } - } - - @override - double transformValue(double from, double to, double value) { - var f = transform(value); - return from + (to - from) * f; - } - - Easing get easing => enumAt(Easing.values, easingValue); - set easing(Easing value) => easingValue = value.index; - - @override - void updateInterpolator() { - _elastic = ElasticEase(amplitude, period == 0 ? 0.5 : period); - super.updateInterpolator(); - } - - @override - void amplitudeChanged(double from, double to) => updateInterpolator(); - - @override - void easingValueChanged(int from, int to) => updateInterpolator(); - - @override - void periodChanged(double from, double to) => updateInterpolator(); -} diff --git a/lib/src/rive_core/animation/entry_state.dart b/lib/src/rive_core/animation/entry_state.dart deleted file mode 100644 index ed64e4f..0000000 --- a/lib/src/rive_core/animation/entry_state.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:rive/src/generated/animation/entry_state_base.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; - -export 'package:rive/src/generated/animation/entry_state_base.dart'; - -class EntryState extends EntryStateBase { - @override - StateInstance makeInstance() => SystemStateInstance(this); -} diff --git a/lib/src/rive_core/animation/exit_state.dart b/lib/src/rive_core/animation/exit_state.dart deleted file mode 100644 index 5e65ef7..0000000 --- a/lib/src/rive_core/animation/exit_state.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:rive/src/generated/animation/exit_state_base.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; - -export 'package:rive/src/generated/animation/exit_state_base.dart'; - -class ExitState extends ExitStateBase { - @override - StateInstance makeInstance() => SystemStateInstance(this); -} diff --git a/lib/src/rive_core/animation/interpolating_keyframe.dart b/lib/src/rive_core/animation/interpolating_keyframe.dart deleted file mode 100644 index a9851f1..0000000 --- a/lib/src/rive_core/animation/interpolating_keyframe.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/interpolating_keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; -import 'package:rive/src/rive_core/animation/cubic_value_interpolator.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolation.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; - -export 'package:rive/src/generated/animation/interpolating_keyframe_base.dart'; - -abstract class InterpolatingKeyFrame extends InterpolatingKeyFrameBase { - @override - bool get canInterpolate => true; - - KeyFrameInterpolation get interpolation => - enumAt(KeyFrameInterpolation.values, interpolationType); - set interpolation(KeyFrameInterpolation value) { - interpolationType = value.index; - } - - @override - void interpolationTypeChanged(int from, int to) {} - - Interpolator? _interpolator; - Interpolator? get interpolator => _interpolator; - set interpolator(Interpolator? value) { - if (_interpolator == value) { - return; - } - - _interpolator = value; - interpolatorId = value?.id ?? Core.missingId; - } - - @override - void interpolatorIdChanged(int from, int to) { - // This might resolve to null during a load or if context isn't available - // yet so we also do this in onAddedDirty. - interpolator = context.resolve(to); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - if (interpolatorId != Core.missingId) { - interpolator = context.resolve(interpolatorId); - } - // Ensure interpolation types are valid, correct them if not. - switch (interpolation) { - case KeyFrameInterpolation.cubicValue: - if (interpolator is! CubicValueInterpolator) { - interpolation = canInterpolate - ? KeyFrameInterpolation.linear - : KeyFrameInterpolation.hold; - } - break; - case KeyFrameInterpolation.cubic: - if (interpolator is! CubicInterpolator) { - interpolation = canInterpolate - ? KeyFrameInterpolation.linear - : KeyFrameInterpolation.hold; - } - break; - default: - break; - } - } -} diff --git a/lib/src/rive_core/animation/interpolator.dart b/lib/src/rive_core/animation/interpolator.dart deleted file mode 100644 index b785de0..0000000 --- a/lib/src/rive_core/animation/interpolator.dart +++ /dev/null @@ -1,12 +0,0 @@ -abstract class Interpolator { - int get id; - - /// Convert a linear interpolation factor to an eased one. Returns a factor - double transform(double f); - - /// Convert a linear interpolation factor to an eased one for from->to values. - /// Returns a value instead of a factor. - double transformValue(double from, double to, double f); - - bool equalParameters(Interpolator other); -} diff --git a/lib/src/rive_core/animation/keyed_object.dart b/lib/src/rive_core/animation/keyed_object.dart deleted file mode 100644 index 114871c..0000000 --- a/lib/src/rive_core/animation/keyed_object.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyed_object_base.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; - -import 'linear_animation.dart'; - -export 'package:rive/src/generated/animation/keyed_object_base.dart'; - -// ignore: one_member_abstracts -abstract class KeyedCallbackReporter { - void reportKeyedCallback( - int objectId, int propertyKey, double elapsedSeconds); -} - -class KeyedObject extends KeyedObjectBase { - final HashMap _keyedProperties = - HashMap(); - - Iterable get keyedProperties => _keyedProperties.values; - - @override - void onAddedDirty() {} - - @override - void onAdded() {} - - bool isValidKeyedProperty(KeyedProperty property) { - var value = _keyedProperties[property.propertyKey]; - - // If the property is already keyed, that's ok just make sure the - // KeyedObject matches. - if (value != null && value != property) { - return false; - } - return true; - } - - /// Called by rive_core to add a KeyedProperty to the animation. This should - /// be @internal when it's supported. - bool internalAddKeyedProperty(KeyedProperty property) { - var value = _keyedProperties[property.propertyKey]; - - // If the property is already keyed, that's ok just make sure the - // KeyedObject matches. - if (value != null && value != property) { - return false; - } - _keyedProperties[property.propertyKey] = property; - - return true; - } - - /// Called by rive_core to remove a KeyedObject to the animation. This should - /// be @internal when it's supported. - bool internalRemoveKeyedProperty(KeyedProperty property) { - var removed = _keyedProperties.remove(property.propertyKey); - - if (_keyedProperties.isEmpty) { - // Remove this keyed property. - context.removeObject(this); - } - // assert(removed == null || removed == property, - // '$removed was not $property or null'); - - return removed != null; - } - - void reportKeyedCallbacks( - double secondsFrom, - double secondsTo, { - required KeyedCallbackReporter reporter, - bool isAtStartFrame = false, - }) { - for (final keyedProperty - in _keyedProperties.values.where((property) => property.isCallback)) { - keyedProperty.reportKeyedCallbacks( - objectId, - secondsFrom, - secondsTo, - reporter: reporter, - isAtStartFrame: isAtStartFrame, - ); - } - } - - void apply( - double time, - double mix, - CoreContext coreContext, - ) { - Core? object = coreContext.resolve(objectId); - if (object == null) { - return; - } - for (final keyedProperty in _keyedProperties.values) { - if (keyedProperty.isCallback) { - continue; - } - keyedProperty.apply(time, mix, object); - } - } - - @override - void objectIdChanged(int from, int to) {} - - @override - bool import(ImportStack stack) { - var animationHelper = - stack.latest(LinearAnimationBase.typeKey); - if (animationHelper == null) { - return false; - } - animationHelper.addKeyedObject(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/keyed_property.dart b/lib/src/rive_core/animation/keyed_property.dart deleted file mode 100644 index afb97eb..0000000 --- a/lib/src/rive_core/animation/keyed_property.dart +++ /dev/null @@ -1,236 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyed_property_base.dart'; -import 'package:rive/src/rive_core/animation/interpolating_keyframe.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/keyframe.dart'; - -export 'package:rive/src/generated/animation/keyed_property_base.dart'; - -abstract class KeyFrameInterface { - int get frame; -} - -class KeyFrameList { - List _keyframes = []; - List get keyframes => _keyframes; - set keyframes(Iterable frames) => _keyframes = frames.toList(); - - /// Get the keyframe immediately following the provided one. - T? after(T keyframe) { - var index = _keyframes.indexOf(keyframe); - if (index != -1 && index + 1 < _keyframes.length) { - return _keyframes[index + 1]; - } - return null; - } - - /// Find the index in the keyframe list of a specific time frame. - int indexOfFrame(int frame) { - int idx = 0; - // Binary find the keyframe index. - int mid = 0; - int closestFrame = 0; - int start = 0; - int end = _keyframes.length - 1; - - while (start <= end) { - mid = (start + end) >> 1; - closestFrame = _keyframes[mid].frame; - if (closestFrame < frame) { - start = mid + 1; - } else if (closestFrame > frame) { - end = mid - 1; - } else { - idx = start = mid; - break; - } - - idx = start; - } - return idx; - } - - void sort() { - _keyframes.sort((a, b) => a.frame.compareTo(b.frame)); - } -} - -class KeyedProperty extends KeyedPropertyBase - with KeyFrameList { - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - /// Called by rive_core to add a KeyFrame to this KeyedProperty. This should - /// be @internal when it's supported. - bool internalAddKeyFrame(KeyFrame frame) { - if (_keyframes.contains(frame)) { - return false; - } - _keyframes.add(frame); - markKeyFrameOrderDirty(); - return true; - } - - /// Called by rive_core to remove a KeyFrame from this KeyedProperty. This - /// should be @internal when it's supported. - bool internalRemoveKeyFrame(KeyFrame frame) { - var removed = _keyframes.remove(frame); - if (_keyframes.isEmpty) { - // If they keyframes are now empty, we might want to remove this keyed - // property. Wait for any other pending changes to complete before - // checking. - context.dirty(_checkShouldRemove); - } else { - markKeyFrameOrderDirty(); - } - - return removed; - } - - void _checkShouldRemove() { - if (_keyframes.isEmpty) { - // Remove this keyed property. - context.removeObject(this); - } - } - - /// Called by keyframes when their time value changes. This is a pretty rare - /// operation, usually occurs when a user moves a keyframe. Meaning: this - /// shouldn't make it into the runtimes unless we want to allow users moving - /// keyframes around at runtime via code for some reason. - void markKeyFrameOrderDirty() { - context.dirty(_sortAndValidateKeyFrames); - } - - void _sortAndValidateKeyFrames() { - sort(); - } - - /// Number of keyframes for this keyed property. - int get numFrames => _keyframes.length; - - KeyFrame getFrameAt(int index) => _keyframes[index]; - - int closestFrameIndex(double seconds, {int exactOffset = 0}) { - // Binary find the keyframe index (use timeInSeconds here as opposed to the - // finder above which operates in frames). - int mid = 0; - double closestSeconds = 0; - int start = 0; - int end = _keyframes.length - 1; - - // If it's the last keyframe, we skip the binary search - if (seconds > _keyframes[end].seconds) { - return end + 1; - } - - while (start <= end) { - mid = (start + end) >> 1; - closestSeconds = _keyframes[mid].seconds; - if (closestSeconds < seconds) { - start = mid + 1; - } else if (closestSeconds > seconds) { - end = mid - 1; - } else { - return mid + exactOffset; - } - } - return start; - } - - bool get isCallback => RiveCoreContext.isCallback(propertyKey); - - /// Report any keyframes that occured between secondsFrom and secondsTo. - void reportKeyedCallbacks( - int objectId, - double secondsFrom, - double secondsTo, { - required KeyedCallbackReporter reporter, - bool isAtStartFrame = false, - }) { - if (secondsFrom == secondsTo) { - return; - } - bool isForward = secondsFrom <= secondsTo; - int fromExactOffset = 0; - int toExactOffset = isForward ? 1 : 0; - if (isForward) { - if (!isAtStartFrame) { - fromExactOffset = 1; - } - } else { - if (isAtStartFrame) { - fromExactOffset = 1; - } - } - int idx = closestFrameIndex(secondsFrom, exactOffset: fromExactOffset); - int idxTo = closestFrameIndex(secondsTo, exactOffset: toExactOffset); - - // going backwards? - if (idxTo < idx) { - var swap = idx; - idx = idxTo; - idxTo = swap; - } - - while (idxTo > idx) { - var frame = _keyframes[idx]; - reporter.reportKeyedCallback( - objectId, propertyKey, secondsTo - frame.seconds); - idx++; - } - } - - /// Apply keyframe values at a given time expressed in [seconds]. - void apply(double seconds, double mix, Core object) { - if (_keyframes.isEmpty) { - return; - } - - int idx = closestFrameIndex(seconds); - int pk = propertyKey; - if (idx == 0) { - var first = _keyframes[0]; - - first.apply(object, pk, mix); - } else { - if (idx < _keyframes.length) { - InterpolatingKeyFrame fromFrame = - _keyframes[idx - 1] as InterpolatingKeyFrame; - KeyFrame toFrame = _keyframes[idx]; - if (seconds == toFrame.seconds) { - toFrame.apply(object, pk, mix); - } else { - /// Equivalent to fromFrame.interpolation == - /// KeyFrameInterpolation.hold. - if (fromFrame.interpolationType == 0) { - fromFrame.apply(object, pk, mix); - } else { - fromFrame.applyInterpolation(object, pk, seconds, toFrame, mix); - } - } - } else { - var last = _keyframes[idx - 1]; - - last.apply(object, pk, mix); - } - } - } - - @override - void propertyKeyChanged(int from, int to) {} - - @override - bool import(ImportStack stack) { - var importer = stack.latest(KeyedObjectBase.typeKey); - if (importer == null) { - return false; - } - importer.addKeyedProperty(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/keyframe.dart b/lib/src/rive_core/animation/keyframe.dart deleted file mode 100644 index 8e5cde6..0000000 --- a/lib/src/rive_core/animation/keyframe.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_base.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; - -export 'package:rive/src/generated/animation/keyframe_base.dart'; - -abstract class KeyFrame extends KeyFrameBase - implements KeyFrameInterface { - bool get canInterpolate => false; - double _timeInSeconds = 0; - double get seconds => _timeInSeconds; - - @override - void onAdded() {} - - void computeSeconds(LinearAnimation animation) { - _timeInSeconds = frame / animation.fps; - } - - @override - void onAddedDirty() {} - - @override - void frameChanged(int from, int to) {} - - /// Apply the value of this keyframe to the object's property. - void apply(Core object, int propertyKey, double mix) {} - - /// Interpolate the value between this keyframe and the next and apply it to - /// the object's property. - void applyInterpolation(Core object, int propertyKey, double seconds, - covariant KeyFrame nextFrame, double mix) {} - - @override - bool import(ImportStack importStack) { - var keyedPropertyHelper = - importStack.latest(KeyedPropertyBase.typeKey); - if (keyedPropertyHelper == null) { - return false; - } - keyedPropertyHelper.addKeyFrame(this); - - return super.import(importStack); - } - - @override - String toString() => '${super.toString()} id: ($id)'; -} diff --git a/lib/src/rive_core/animation/keyframe_bool.dart b/lib/src/rive_core/animation/keyframe_bool.dart deleted file mode 100644 index 837cfb0..0000000 --- a/lib/src/rive_core/animation/keyframe_bool.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_bool_base.dart'; -export 'package:rive/src/generated/animation/keyframe_bool_base.dart'; - -/// KeyFrame for animating bool properties. -class KeyFrameBool extends KeyFrameBoolBase { - @override - bool get canInterpolate => false; - - @override - void apply(Core object, int propertyKey, double mix) { - RiveCoreContext.setBool(object, propertyKey, value); - } - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameBool nextFrame, double mix) { - RiveCoreContext.setBool(object, propertyKey, value); - } - - @override - void valueChanged(bool from, bool to) {} -} diff --git a/lib/src/rive_core/animation/keyframe_callback.dart b/lib/src/rive_core/animation/keyframe_callback.dart deleted file mode 100644 index 1510dea..0000000 --- a/lib/src/rive_core/animation/keyframe_callback.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_callback_base.dart'; -import 'package:rive/src/rive_core/animation/keyframe.dart'; - -export 'package:rive/src/generated/animation/keyframe_callback_base.dart'; - -class KeyFrameCallback extends KeyFrameCallbackBase { - @override - void apply(Core object, int propertyKey, double mix) {} - - @override - void applyInterpolation(Core object, int propertyKey, - double seconds, covariant KeyFrame nextFrame, double mix) {} -} diff --git a/lib/src/rive_core/animation/keyframe_color.dart b/lib/src/rive_core/animation/keyframe_color.dart deleted file mode 100644 index 899fea5..0000000 --- a/lib/src/rive_core/animation/keyframe_color.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_color_base.dart'; -export 'package:rive/src/generated/animation/keyframe_color_base.dart'; - -void _apply(Core object, int propertyKey, double mix, int value) { - if (mix == 1) { - RiveCoreContext.setColor(object, propertyKey, value); - } else { - var mixedColor = Color.lerp( - Color(RiveCoreContext.getColor(object, propertyKey)), - Color(value), - mix); - if (mixedColor != null) { - RiveCoreContext.setColor(object, propertyKey, mixedColor.value); - } - } -} - -class KeyFrameColor extends KeyFrameColorBase { - @override - void apply(Core object, int propertyKey, double mix) => - _apply(object, propertyKey, mix, value); - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameColor nextFrame, double mix) { - var f = (currentTime - seconds) / (nextFrame.seconds - seconds); - - if (interpolator != null) { - f = interpolator!.transform(f); - } - - var color = Color.lerp(Color(value), Color(nextFrame.value), f); - if (color != null) { - _apply(object, propertyKey, mix, color.value); - } - } - - @override - void valueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/animation/keyframe_double.dart b/lib/src/rive_core/animation/keyframe_double.dart deleted file mode 100644 index 39d5544..0000000 --- a/lib/src/rive_core/animation/keyframe_double.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_double_base.dart'; -export 'package:rive/src/generated/animation/keyframe_double_base.dart'; - -void _apply( - Core object, int propertyKey, double mix, double value) { - if (mix == 1) { - RiveCoreContext.setDouble(object, propertyKey, value); - } else { - var mixi = 1.0 - mix; - RiveCoreContext.setDouble(object, propertyKey, - RiveCoreContext.getDouble(object, propertyKey) * mixi + value * mix); - } -} - -class KeyFrameDouble extends KeyFrameDoubleBase { - @override - void apply(Core object, int propertyKey, double mix) => - _apply(object, propertyKey, mix, value); - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameDouble nextFrame, double mix) { - var f = (currentTime - seconds) / (nextFrame.seconds - seconds); - - var frameValue = interpolator?.transformValue(value, nextFrame.value, f) ?? - value + (nextFrame.value - value) * f; - - _apply(object, propertyKey, mix, frameValue); - } - - @override - void valueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/animation/keyframe_id.dart b/lib/src/rive_core/animation/keyframe_id.dart deleted file mode 100644 index 9a688c3..0000000 --- a/lib/src/rive_core/animation/keyframe_id.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_id_base.dart'; - -export 'package:rive/src/generated/animation/keyframe_id_base.dart'; - -class KeyFrameId extends KeyFrameIdBase { - @override - bool get canInterpolate => false; - - @override - void apply(Core object, int propertyKey, double mix) { - RiveCoreContext.setUint(object, propertyKey, value); - } - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameId nextFrame, double mix) { - RiveCoreContext.setUint(object, propertyKey, value); - } - - @override - void valueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/animation/keyframe_interpolation.dart b/lib/src/rive_core/animation/keyframe_interpolation.dart deleted file mode 100644 index 1fd7700..0000000 --- a/lib/src/rive_core/animation/keyframe_interpolation.dart +++ /dev/null @@ -1,29 +0,0 @@ -/// The type of interpolation used for a keyframe. -enum KeyFrameInterpolation { - /// Hold the incoming value until the next keyframe is reached. - hold, - - /// Linearly interpolate from the incoming to the outgoing value. - linear, - - /// Cubicly interpolate from incoming to outgoing value based on the - /// [CubicInterpolator]'s parameters. - cubic, - - /// Cubicly interpolate from incoming to outgoing value based on the - /// [CubicInterpolator]'s parameters. - cubicValue, - - /// Elastic easing. - elastic, -} - -extension KeyFrameInterpolationExtension on KeyFrameInterpolation { - /// Should this type use the interpolation value field beneath the - /// curve preview - bool get usesValuesField => [ - KeyFrameInterpolation.hold, - KeyFrameInterpolation.linear, - KeyFrameInterpolation.cubic, - ].contains(this); -} diff --git a/lib/src/rive_core/animation/keyframe_interpolator.dart b/lib/src/rive_core/animation/keyframe_interpolator.dart deleted file mode 100644 index 742b484..0000000 --- a/lib/src/rive_core/animation/keyframe_interpolator.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_interpolator_base.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/keyframe_interpolator_base.dart'; - -abstract class KeyFrameInterpolator extends KeyFrameInterpolatorBase - implements Interpolator { - @override - void onAdded() => updateInterpolator(); - - @protected - void updateInterpolator() {} - - @override - bool import(ImportStack stack) { - var artboardHelper = stack.latest(ArtboardBase.typeKey); - if (artboardHelper == null) { - return false; - } - artboardHelper.addComponent(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/keyframe_string.dart b/lib/src/rive_core/animation/keyframe_string.dart deleted file mode 100644 index 737d1d5..0000000 --- a/lib/src/rive_core/animation/keyframe_string.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_string_base.dart'; - -export 'package:rive/src/generated/animation/keyframe_id_base.dart'; - -class KeyFrameString extends KeyFrameStringBase { - @override - bool get canInterpolate => false; - - @override - void apply(Core object, int propertyKey, double mix) { - RiveCoreContext.setString(object, propertyKey, value); - } - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameString nextFrame, double mix) { - RiveCoreContext.setString(object, propertyKey, value); - } - - @override - void valueChanged(String from, String to) {} -} diff --git a/lib/src/rive_core/animation/keyframe_uint.dart b/lib/src/rive_core/animation/keyframe_uint.dart deleted file mode 100644 index 692f71a..0000000 --- a/lib/src/rive_core/animation/keyframe_uint.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/keyframe_uint_base.dart'; -export 'package:rive/src/generated/animation/keyframe_uint_base.dart'; - -/// KeyFrame for animating uint properties. -class KeyFrameUint extends KeyFrameUintBase { - @override - bool get canInterpolate => false; - - @override - void apply(Core object, int propertyKey, double mix) { - RiveCoreContext.setUint(object, propertyKey, value); - } - - @override - void applyInterpolation(Core object, int propertyKey, - double currentTime, KeyFrameUint nextFrame, double mix) { - RiveCoreContext.setUint(object, propertyKey, value); - } - - @override - void valueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/animation/layer_state.dart b/lib/src/rive_core/animation/layer_state.dart deleted file mode 100644 index 72bbafd..0000000 --- a/lib/src/rive_core/animation/layer_state.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/layer_state_base.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; - -export 'package:rive/src/generated/animation/layer_state_base.dart'; - -abstract class LayerState extends LayerStateBase { - final StateTransitions _transitions = StateTransitions(); - StateTransitions get transitions => _transitions; - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - void internalAddTransition(StateTransition transition) { - assert(!_transitions.contains(transition), - 'shouldn\'t already contain the transition'); - _transitions.add(transition); - } - - void internalRemoveTransition(StateTransition transition) { - _transitions.remove(transition); - } - - @override - void flagsChanged(int from, int to) {} - - StateInstance makeInstance(); - - @override - bool import(ImportStack stack) { - var importer = - stack.latest(StateMachineLayerBase.typeKey); - if (importer == null) { - return false; - } - importer.addState(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/linear_animation.dart b/lib/src/rive_core/animation/linear_animation.dart deleted file mode 100644 index b6b5212..0000000 --- a/lib/src/rive_core/animation/linear_animation.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/linear_animation_base.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/loop.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/linear_animation_base.dart'; - -class LinearAnimation extends LinearAnimationBase { - /// Map objectId to KeyedObject. N.B. this is the id of the object that we - /// want to key in core, not of the KeyedObject. It's a clear way to see if an - /// object is keyed in this animation. - final _keyedObjects = HashMap(); - - /// The metadata for the objects that are keyed in this animation. - Iterable get keyedObjects => _keyedObjects.values; - - /// Called by rive_core to add a KeyedObject to the animation. This should be - /// @internal when it's supported. - bool internalAddKeyedObject(KeyedObject object) { - if (internalCheckAddKeyedObject(object)) { - _keyedObjects[object.objectId] = object; - return true; - } - return false; - } - - bool internalCheckAddKeyedObject(KeyedObject object) { - var value = _keyedObjects[object.objectId]; - - // If the object is already keyed, that's ok just make sure the KeyedObject - // matches. - if (value != null && value != object) { - return false; - } - return true; - } - - bool isAnyObjectKeyed(Iterable objects) => - objects.any((element) => _keyedObjects.containsKey(element.id)); - - bool isObjectKeyed(Core object) => _keyedObjects.containsKey(object.id); - bool removeObjectKeys(Core object) { - var value = _keyedObjects[object.id]; - if (value == null) { - return false; - } - bool found = false; - for (final kp in value.keyedProperties) { - for (final kf in kp.keyframes.toList()) { - kf.remove(); - found = true; - } - } - return found; - } - - /// Returns the seconds where the animiation work area starts - double get startSeconds => (enableWorkArea ? workStart : 0).toDouble() / fps; - - /// Returns the seconds where the animation work area ends - double get endSeconds => - (enableWorkArea ? workEnd : duration).toDouble() / fps; - - /// Returns the length of the animation - double get durationSeconds => endSeconds - startSeconds; - - /// Returns the end time of the animation in seconds, considering speed - double get endTime => (speed >= 0) ? endSeconds : startSeconds; - - /// Returns the start time of the animation in seconds, considering speed - double get startTime => (speed >= 0) ? startSeconds : endSeconds; - - void reportKeyedCallbacks( - double secondsFrom, - double secondsTo, { - required KeyedCallbackReporter reporter, - int speedDirection = 1, - bool fromPong = false, - }) { - // We have to account for the state machine speed multiplier and the speed - double startingTime = - ((speed * speedDirection) >= 0) ? startSeconds : endSeconds; - bool isAtStartFrame = startingTime == secondsFrom; - - // Do not report a callback twice if it comes from the "pong" part of a - // "ping pong" loop - if (!isAtStartFrame || !fromPong) { - for (final keyedObject in _keyedObjects.values) { - keyedObject.reportKeyedCallbacks( - secondsFrom, - secondsTo, - reporter: reporter, - isAtStartFrame: isAtStartFrame, - ); - } - } - } - - /// Pass in a different [core] context if you want to apply the animation to a - /// different instance. This isn't meant to be used yet but left as mostly a - /// note to remember that at runtime we have to support applying animations to - /// instances. We do a nice job of not duping all that data at runtime (so - /// animations exist once but entire Rive file can be instanced multiple times - /// playing different positions). - void apply(double time, {required CoreContext coreContext, double mix = 1}) { - if (quantize) { - // ignore: parameter_assignments - time = (time * fps).floor() / fps; - } - for (final keyedObject in _keyedObjects.values) { - keyedObject.apply(time, mix, coreContext); - } - } - - Loop get loop => Loop.values[loopValue]; - set loop(Loop value) => loopValue = value.index; - - @override - void durationChanged(int from, int to) {} - - @override - void enableWorkAreaChanged(bool from, bool to) {} - - @override - void fpsChanged(int from, int to) {} - - @override - void loopValueChanged(int from, int to) {} - - @override - void speedChanged(double from, double to) {} - - @override - void workEndChanged(int from, int to) {} - - @override - void workStartChanged(int from, int to) {} - - @override - void quantizeChanged(bool from, bool to) {} - - /// Convert a global clock to local seconds (takes into consideration work - /// area start/end, speed, looping). - double globalToLocalTime(double seconds) { - switch (loop) { - case Loop.oneShot: - return seconds + startTime; - case Loop.loop: - return seconds % (endTime - startTime) + startTime; - case Loop.pingPong: - var localTime = seconds % (endTime - startTime); - var direction = (seconds ~/ (endTime - startTime)) % 2; - return direction == 0 ? localTime + startTime : endTime - localTime; - } - } - - @override - bool import(ImportStack stack) { - var artboardImporter = stack.latest(ArtboardBase.typeKey); - if (artboardImporter == null) { - return false; - } - artboardImporter.addAnimation(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/linear_animation_instance.dart b/lib/src/rive_core/animation/linear_animation_instance.dart deleted file mode 100644 index e44910f..0000000 --- a/lib/src/rive_core/animation/linear_animation_instance.dart +++ /dev/null @@ -1,246 +0,0 @@ -// ignore_for_file: lines_longer_than_80_chars - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/loop.dart'; -import 'package:rive/src/rive_core/event.dart'; - -class LinearAnimationInstance { - final LinearAnimation animation; - final int _speedDirection; - - double _time = 0; - double _totalTime = 0; - double _lastTotalTime = 0; - double _direction = 1; - bool _didLoop = false; - bool get didLoop => _didLoop; - double _spilledTime = 0; - double get spilledTime => _spilledTime; - - double get totalTime => _totalTime; - double get lastTotalTime => _lastTotalTime; - - LinearAnimationInstance(this.animation, {double speedMultiplier = 1.0}) - : _time = - (speedMultiplier >= 0) ? animation.startTime : animation.endTime, - _speedDirection = (speedMultiplier >= 0) ? 1 : -1; - - /// NOTE: that when time is set, the direction will be changed to 1 - set time(double value) { - if (_time == value) { - return; - } - - // Make sure to keep last and total in relative lockstep so state machines - // can track change even when setting time. - var diff = _totalTime - _lastTotalTime; - _time = _totalTime = value; - _lastTotalTime = _totalTime - diff; - - // NOTE: will cause ping-pongs to get reset if "seeking" - _direction = 1; - } - - /// Returns the current time position of the animation in seconds - double get time => _time; - - /// Direction should only be +1 or -1 - set direction(double value) => _direction = value == -1 ? -1 : 1; - - /// Returns the animation's play direction: 1 for forwards, -1 for backwards - double get direction => _direction; - - double get directedSpeed => animation.speed * _direction; - - double get progress => - (_time - animation.startTime).abs() / - (animation.endTime - animation.startTime).abs(); - - /// Resets the animation to the starting frame - void reset({double speedMultiplier = 1}) => - _time = (speedMultiplier >= 0) ? animation.startTime : animation.endTime; - - /// Whether the controller driving this animation should keep requesting - /// frames be drawn. - bool get keepGoing => - animation.loop != Loop.oneShot || - (directedSpeed > 0 && _time < animation.endSeconds) || - (directedSpeed < 0 && _time > animation.startSeconds); - - // We estimate whether the animation should keep playing using the speed - // multiplier provided by the caller - bool shouldKeepGoing(double speedMultiplier) { - return animation.loop != Loop.oneShot || - (speedMultiplier * directedSpeed > 0 && _time < animation.endSeconds) || - (speedMultiplier * directedSpeed < 0 && _time > animation.startSeconds); - } - - /// Apply the changes incurred during advance, also automatically fires any - /// accrued events. - void apply(CoreContext core, {double mix = 1}) { - animation.apply(time, coreContext: core, mix: mix); - } - - void clearSpilledTime() { - _spilledTime = 0; - } - - bool advance(double elapsedSeconds, - {KeyedCallbackReporter? callbackReporter}) { - var deltaSeconds = elapsedSeconds * animation.speed * _direction; - _spilledTime = 0; - - if (deltaSeconds == 0) { - _didLoop = false; - return true; - } - _lastTotalTime = _totalTime; - _totalTime += deltaSeconds.abs(); - - // NOTE: - // do not track spilled time, if our one shot loop is already completed. - // stop gap before we move spilled tracking into state machine logic. - var killSpilledTime = !keepGoing; - - var lastTime = _time; - _time += deltaSeconds; - - if (callbackReporter != null) { - animation.reportKeyedCallbacks( - lastTime, - _time, - reporter: callbackReporter, - speedDirection: _speedDirection, - ); - } - - var fps = animation.fps; - double frames = _time * fps; - - var start = animation.enableWorkArea ? animation.workStart : 0; - var end = animation.enableWorkArea ? animation.workEnd : animation.duration; - var range = end - start; - - bool didLoop = false; - - int direction = deltaSeconds < 0 ? -1 : 1; - switch (animation.loop) { - case Loop.oneShot: - if (direction == 1 && frames > end) { - // Account for the time dilation or contraction applied in the - // animation local time by its speed to calculate spilled time. - // Calculate the ratio of the time excess by the total elapsed - // time in local time (deltaFrames) and multiply the elapsed time - // by it. - final deltaFrames = deltaSeconds * fps; - final spilledFramesRatio = (frames - end) / deltaFrames; - _spilledTime = spilledFramesRatio * elapsedSeconds; - frames = end.toDouble(); - _time = frames / fps; - didLoop = true; - } else if (direction == -1 && frames < start) { - final deltaFrames = (deltaSeconds * fps).abs(); - final spilledFramesRatio = (start - frames) / deltaFrames; - _spilledTime = spilledFramesRatio * elapsedSeconds; - frames = start.toDouble(); - _time = frames / fps; - didLoop = true; - } - break; - case Loop.loop: - if (direction == 1 && frames >= end) { - // How spilled time has to be calculated, given that local time can be scaled - // to a factor of the regular time: - // - for convenience, calculate the local elapsed time in frames (deltaFrames) - // - get the remainder of current frame position (frames) by duration (range) - // - use that remainder as the ratio of the original time that was not consumed - // by the loop (spilledFramesRatio) - // - multiply the original elapsedTime by the ratio to set the spilled time - final deltaFrames = deltaSeconds * fps; - final remainder = (frames - start) % range; - final spilledFramesRatio = remainder / deltaFrames; - _spilledTime = spilledFramesRatio * elapsedSeconds; - frames = start + remainder; - lastTime = 0; - _time = frames / fps; - if (callbackReporter != null) { - animation.reportKeyedCallbacks( - lastTime, - _time, - reporter: callbackReporter, - speedDirection: _speedDirection, - ); - } - didLoop = true; - } else if (direction == -1 && frames <= start) { - final deltaFrames = deltaSeconds * fps; - final remainder = (start - frames) % range; - final spilledFramesRatio = (remainder / deltaFrames).abs(); - _spilledTime = spilledFramesRatio * elapsedSeconds; - frames = end - remainder; - lastTime = end / fps; - _time = frames / fps; - if (callbackReporter != null) { - animation.reportKeyedCallbacks( - lastTime, - _time, - reporter: callbackReporter, - speedDirection: _speedDirection, - ); - } - didLoop = true; - } - break; - case Loop.pingPong: - // ignore: literal_only_boolean_expressions - // In ping-pong we only want to report callbacks once per side - bool fromPong = true; - while (true) { - if (direction == 1 && frames >= end) { - _spilledTime = (frames - end) / animation.fps; - lastTime = end / fps; - frames = end + (end - frames); - } else if (direction == -1 && frames < start) { - _spilledTime = (start - frames) / animation.fps; - lastTime = start / fps; - frames = start + (start - frames); - } else { - // we're within the range, we can stop fixing. We do this in a - // loop to fix conditions when time has advanced so far that we've - // ping-ponged back and forth a few times in a single frame. We - // want to accomodate for this in cases where animations are not - // advanced on regular intervals. - break; - } - _time = frames / animation.fps; - _direction *= -1; - direction *= -1; - didLoop = true; - if (callbackReporter != null) { - animation.reportKeyedCallbacks( - lastTime, - _time, - reporter: callbackReporter, - speedDirection: _speedDirection, - fromPong: fromPong, - ); - } - fromPong = !fromPong; - } - break; - } - - if (killSpilledTime) { - _spilledTime = 0; - } - - _didLoop = didLoop; - return keepGoing; - } - - // Used by runtime to report events from linear animations in nested artboards - // when not played in state machine - void reportEvent(Event event) {} -} diff --git a/lib/src/rive_core/animation/listener_action.dart b/lib/src/rive_core/animation/listener_action.dart deleted file mode 100644 index 5b62d36..0000000 --- a/lib/src/rive_core/animation/listener_action.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/listener_action_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_listener.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_action_base.dart'; - -abstract class ListenerAction extends ListenerActionBase { - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - /// Perform the action. - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition); - - @override - bool import(ImportStack importStack) { - var importer = importStack - .latest(StateMachineListenerBase.typeKey); - if (importer == null) { - return false; - } - importer.addAction(this); - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/listener_align_target.dart b/lib/src/rive_core/animation/listener_align_target.dart deleted file mode 100644 index d2dc5b4..0000000 --- a/lib/src/rive_core/animation/listener_align_target.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:rive/src/generated/animation/listener_align_target_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/node.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_align_target_base.dart'; - -class ListenerAlignTarget extends ListenerAlignTargetBase { - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - Node? target = controller.core.resolve(targetId); - - if (target == null) { - return; - } - - var targetParentWorld = parentWorld(target); - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, targetParentWorld)) { - return; - } - - if (preserveOffset) { - var localPosition = inverse * position; - var prevLocalPosition = inverse * previousPosition; - target.x += localPosition.x - prevLocalPosition.x; - target.y += localPosition.y - prevLocalPosition.y; - } else { - var localPosition = inverse * position; - target.x = localPosition.x; - target.y = localPosition.y; - } - } - - @override - void targetIdChanged(int from, int to) {} - - @override - void preserveOffsetChanged(bool from, bool to) {} -} diff --git a/lib/src/rive_core/animation/listener_bool_change.dart b/lib/src/rive_core/animation/listener_bool_change.dart deleted file mode 100644 index efa3cf3..0000000 --- a/lib/src/rive_core/animation/listener_bool_change.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:rive/src/generated/animation/listener_bool_change_base.dart'; -import 'package:rive/src/rive_core/animation/nested_bool.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_bool_change_base.dart'; - -class ListenerBoolChange extends ListenerBoolChangeBase { - @override - void valueChanged(int from, int to) {} - - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - var nestedInput = nestedInputForController(controller); - bool? newValue; - switch (value) { - case 0: - newValue = false; - break; - case 1: - newValue = true; - break; - default: - // Toggle - dynamic existing = nestedInput != null && nestedInput is NestedBool - ? nestedInput.nestedValue - : controller.getInputValue(inputId); - if (existing is bool) { - newValue = !existing; - } else { - newValue = true; - } - break; - } - if (nestedInput != null && nestedInput is NestedBool) { - nestedInput.nestedValue = newValue; - } else { - controller.setInputValue(inputId, newValue); - } - } -} diff --git a/lib/src/rive_core/animation/listener_fire_event.dart b/lib/src/rive_core/animation/listener_fire_event.dart deleted file mode 100644 index 0cb31b5..0000000 --- a/lib/src/rive_core/animation/listener_fire_event.dart +++ /dev/null @@ -1,22 +0,0 @@ -library rive_core; - -import 'package:rive/src/generated/animation/listener_fire_event_base.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_fire_event_base.dart'; - -class ListenerFireEvent extends ListenerFireEventBase { - @override - void eventIdChanged(int from, int to) {} - - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - Event? event = controller.artboard?.context.resolve(eventId); - if (event != null) { - controller.reportEvent(event); - } - } -} diff --git a/lib/src/rive_core/animation/listener_input_change.dart b/lib/src/rive_core/animation/listener_input_change.dart deleted file mode 100644 index 942b42d..0000000 --- a/lib/src/rive_core/animation/listener_input_change.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/listener_input_change_base.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -export 'package:rive/src/generated/animation/listener_input_change_base.dart'; - -abstract class ListenerInputChange extends ListenerInputChangeBase { - StateMachineInput _input = StateMachineInput.unknown; - StateMachineInput get input => _input; - set input(StateMachineInput value) { - if (value == _input) { - return; - } - - _input = value; - - inputId = _input.id; - } - - NestedInput? nestedInputForController(StateMachineController controller) { - return controller.artboard?.context.resolve(nestedInputId); - } - - @override - void inputIdChanged(int from, int to) { - input = context.resolveWithDefault(to, StateMachineInput.unknown); - } - - @override - void nestedInputIdChanged(int from, int to) {} - - @override - void onAddedDirty() { - super.onAddedDirty(); - input = context.resolveWithDefault(inputId, StateMachineInput.unknown); - } - - @override - bool import(ImportStack importStack) { - if (!super.import(importStack)) { - return false; - } - - var stateMachineImporter = - importStack.latest(StateMachineBase.typeKey); - if (stateMachineImporter == null) { - return false; - } - if (inputId >= 0 && inputId < stateMachineImporter.machine.inputs.length) { - var found = stateMachineImporter.machine.inputs[inputId]; - _input = found as StateMachineInput; - inputId = found.id; - } - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/listener_number_change.dart b/lib/src/rive_core/animation/listener_number_change.dart deleted file mode 100644 index 3964164..0000000 --- a/lib/src/rive_core/animation/listener_number_change.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:rive/src/generated/animation/listener_number_change_base.dart'; -import 'package:rive/src/rive_core/animation/nested_number.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_number_change_base.dart'; - -class ListenerNumberChange extends ListenerNumberChangeBase { - @override - void valueChanged(double from, double to) {} - - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - var nestedInput = nestedInputForController(controller); - if (nestedInput != null && nestedInput is NestedNumber) { - nestedInput.nestedValue = value; - } else { - controller.setInputValue(inputId, value); - } - } -} diff --git a/lib/src/rive_core/animation/listener_trigger_change.dart b/lib/src/rive_core/animation/listener_trigger_change.dart deleted file mode 100644 index f23498e..0000000 --- a/lib/src/rive_core/animation/listener_trigger_change.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/listener_trigger_change_base.dart'; -import 'package:rive/src/rive_core/animation/nested_trigger.dart'; -import 'package:rive/src/rive_core/animation/state_machine_trigger.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_trigger_change_base.dart'; - -class ListenerTriggerChange extends ListenerTriggerChangeBase { - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - var nestedInput = nestedInputForController(controller); - if (nestedInput != null && nestedInput is NestedTrigger) { - nestedInput.fire(CallbackData(controller, delay: 0)); - } else if (input is StateMachineTrigger) { - controller.setInputValue(inputId, true); - } - } -} diff --git a/lib/src/rive_core/animation/listener_viewmodel_change.dart b/lib/src/rive_core/animation/listener_viewmodel_change.dart deleted file mode 100644 index 023b921..0000000 --- a/lib/src/rive_core/animation/listener_viewmodel_change.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/animation/listener_viewmodel_change_base.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/listener_viewmodel_change_base.dart'; - -class ListenerViewModelChange extends ListenerViewModelChangeBase { - @override - void perform(StateMachineController controller, Vec2D position, - Vec2D previousPosition) {} -} diff --git a/lib/src/rive_core/animation/loop.dart b/lib/src/rive_core/animation/loop.dart deleted file mode 100644 index 702dc26..0000000 --- a/lib/src/rive_core/animation/loop.dart +++ /dev/null @@ -1,12 +0,0 @@ -/// Loop options for linear animations. -enum Loop { - /// Play until the duration or end of work area of the animation. - oneShot, - - /// Play until the duration or end of work area of the animation and then go - /// back to the start (0 seconds). - loop, - - /// Play to the end of the duration/work area and then play back. - pingPong, -} diff --git a/lib/src/rive_core/animation/nested_bool.dart b/lib/src/rive_core/animation/nested_bool.dart deleted file mode 100644 index 66bef53..0000000 --- a/lib/src/rive_core/animation/nested_bool.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/generated/animation/nested_bool_base.dart'; -export 'package:rive/src/generated/animation/nested_bool_base.dart'; - -class NestedBool extends NestedBoolBase { - @override - void nestedValueChanged(bool from, bool to) => updateValue(); - - @override - void updateValue() => nestedStateMachine?.setInputValue(inputId, nestedValue); - - @override - set nestedValue(bool value) { - super.nestedValue = value; - - updateValue(); - } -} diff --git a/lib/src/rive_core/animation/nested_input.dart b/lib/src/rive_core/animation/nested_input.dart deleted file mode 100644 index 33fd5d3..0000000 --- a/lib/src/rive_core/animation/nested_input.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:rive/src/generated/animation/nested_input_base.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; - -export 'package:rive/src/generated/animation/nested_input_base.dart'; - -abstract class NestedInput extends NestedInputBase { - @override - void inputIdChanged(int from, int to) {} - - NestedArtboard? get nestedArtboard => - nestedStateMachine?.parent is NestedArtboard - ? nestedStateMachine?.parent as NestedArtboard - : null; - - NestedStateMachine? get nestedStateMachine => - parent is NestedStateMachine ? parent as NestedStateMachine : null; - - @override - bool validate() => super.validate() && nestedStateMachine != null; - - @override - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - super.parentChanged(from, to); - if (nestedStateMachine != null) { - if (!nestedStateMachine!.nestedInputs.contains(this)) { - nestedStateMachine!.nestedInputs.add(this); - } - } - } - - void updateValue(); - - @override - void update(int dirt) {} - - @override - bool import(ImportStack importStack) { - var importer = importStack - .latest(NestedStateMachineBase.typeKey); - if (importer == null) { - return false; - } - importer.addNestedInput(this); - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/nested_linear_animation.dart b/lib/src/rive_core/animation/nested_linear_animation.dart deleted file mode 100644 index eaf2b48..0000000 --- a/lib/src/rive_core/animation/nested_linear_animation.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:rive/src/generated/animation/nested_linear_animation_base.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; - -export 'package:rive/src/generated/animation/nested_linear_animation_base.dart'; - -/// Need this abstraction to not depend on package:rive in rive_core. -// ignore: one_member_abstracts -abstract class NestedLinearAnimationInstance { - void goto(double value); - double get durationSeconds; - - double get speed; - set speed(double value); - - bool advance(double elapsedSeconds); - void apply(covariant MountedArtboard artboard, double mix); -} - -abstract class NestedLinearAnimation extends NestedLinearAnimationBase { - NestedLinearAnimationInstance? _linearAnimationInstance; - NestedLinearAnimationInstance? get linearAnimationInstance => - _linearAnimationInstance; - set linearAnimationInstance(NestedLinearAnimationInstance? value) { - if (_linearAnimationInstance == value) { - return; - } - var from = _linearAnimationInstance; - _linearAnimationInstance = value; - linearAnimationInstanceChanged(from, value); - } - - void linearAnimationInstanceChanged( - NestedLinearAnimationInstance? from, NestedLinearAnimationInstance? to) {} - - @override - bool get isEnabled => true; - - @override - void mixChanged(double from, double to) {} - - @override - bool advance(double elapsedSeconds, MountedArtboard mountedArtboard) { - if (linearAnimationInstance != null && mix != 0) { - linearAnimationInstance!.apply(mountedArtboard, mix); - return true; - } - return false; - } -} diff --git a/lib/src/rive_core/animation/nested_number.dart b/lib/src/rive_core/animation/nested_number.dart deleted file mode 100644 index e5bfa81..0000000 --- a/lib/src/rive_core/animation/nested_number.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/generated/animation/nested_number_base.dart'; -export 'package:rive/src/generated/animation/nested_number_base.dart'; - -class NestedNumber extends NestedNumberBase { - @override - void nestedValueChanged(double from, double to) => updateValue(); - - @override - void updateValue() => nestedStateMachine?.setInputValue(inputId, nestedValue); - - @override - set nestedValue(double value) { - super.nestedValue = value; - - updateValue(); - } -} diff --git a/lib/src/rive_core/animation/nested_remap_animation.dart b/lib/src/rive_core/animation/nested_remap_animation.dart deleted file mode 100644 index c4e3e30..0000000 --- a/lib/src/rive_core/animation/nested_remap_animation.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:rive/src/generated/animation/nested_remap_animation_base.dart'; -import 'package:rive/src/rive_core/animation/nested_linear_animation.dart'; - -export 'package:rive/src/generated/animation/nested_remap_animation_base.dart'; - -class NestedRemapAnimation extends NestedRemapAnimationBase { - @override - void timeChanged(double from, double to) => syncTime(); - - void syncTime() { - if (linearAnimationInstance != null) { - linearAnimationInstance! - .goto(linearAnimationInstance!.durationSeconds * time); - } - } - - @override - void linearAnimationInstanceChanged(NestedLinearAnimationInstance? from, - NestedLinearAnimationInstance? to) => - syncTime(); - - @override - bool get isEnabled => true; -} diff --git a/lib/src/rive_core/animation/nested_simple_animation.dart b/lib/src/rive_core/animation/nested_simple_animation.dart deleted file mode 100644 index 7182a7b..0000000 --- a/lib/src/rive_core/animation/nested_simple_animation.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:rive/src/generated/animation/nested_simple_animation_base.dart'; -import 'package:rive/src/rive_core/animation/nested_linear_animation.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; - -export 'package:rive/src/generated/animation/nested_simple_animation_base.dart'; - -class NestedSimpleAnimation extends NestedSimpleAnimationBase { - @override - void isPlayingChanged(bool from, bool to) {} - - @override - void speedChanged(double from, double to) { - linearAnimationInstance?.speed = to; - } - - @override - void linearAnimationInstanceChanged( - NestedLinearAnimationInstance? from, NestedLinearAnimationInstance? to) { - to?.speed = speed; - } - - @override - bool get isEnabled => true; - - @override - bool advance(double elapsedSeconds, MountedArtboard mountedArtboard) { - var keepGoing = false; - if (isPlaying && linearAnimationInstance != null) { - keepGoing = linearAnimationInstance!.advance(elapsedSeconds); - } - return super.advance(elapsedSeconds, mountedArtboard) || keepGoing; - } -} diff --git a/lib/src/rive_core/animation/nested_state_machine.dart b/lib/src/rive_core/animation/nested_state_machine.dart deleted file mode 100644 index 403871e..0000000 --- a/lib/src/rive_core/animation/nested_state_machine.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/nested_state_machine_base.dart'; -import 'package:rive/src/rive_core/animation/nested_bool.dart'; -import 'package:rive/src/rive_core/animation/nested_input.dart'; -import 'package:rive/src/rive_core/animation/nested_number.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/nested_state_machine_base.dart'; - -abstract class NestedStateMachineInstance { - bool get isActive; - ValueListenable get isActiveChanged; - - void apply(covariant MountedArtboard artboard, double elapsedSeconds); - - bool hitTest(Vec2D position); - - HitResult pointerMove(Vec2D position); - - HitResult pointerDown(Vec2D position, PointerDownEvent event); - - HitResult pointerUp(Vec2D position); - - HitResult pointerExit(Vec2D position); - - dynamic getInputValue(int id); - void setInputValue(int id, dynamic value); -} - -class NestedStateMachine extends NestedStateMachineBase { - @override - bool advance(double elapsedSeconds, MountedArtboard mountedArtboard) { - _stateMachineInstance?.apply(mountedArtboard, elapsedSeconds); - return isEnabled; - } - - @override - bool get isEnabled => _stateMachineInstance?.isActive ?? false; - - final Set _nestedInputs = {}; - Set get nestedInputs => _nestedInputs; - - NestedStateMachineInstance? _stateMachineInstance; - NestedStateMachineInstance? get stateMachineInstance => _stateMachineInstance; - set stateMachineInstance(NestedStateMachineInstance? value) { - if (_stateMachineInstance == value) { - return; - } - var from = _stateMachineInstance; - _stateMachineInstance = value; - stateMachineInstanceChanged(from, value); - - for (final input in nestedInputs) { - if (input is NestedBool || input is NestedNumber) { - input.updateValue(); - } - } - } - - void stateMachineInstanceChanged( - NestedStateMachineInstance? from, NestedStateMachineInstance? to) { - from?.isActiveChanged.removeListener(_isActiveChanged); - to?.isActiveChanged.addListener(_isActiveChanged); - } - - dynamic getInputValue(int id) { - int inputId = id; - - _stateMachineInstance?.getInputValue(inputId); - } - - void setInputValue(int id, dynamic value) { - int inputId = id; - - _stateMachineInstance?.setInputValue(inputId, value); - } - - bool hitTest(Vec2D position) => - _stateMachineInstance?.hitTest(position) ?? false; - - HitResult pointerMove(Vec2D position) => - _stateMachineInstance?.pointerMove(position) ?? HitResult.none; - - HitResult pointerDown(Vec2D position, PointerDownEvent event) => - _stateMachineInstance?.pointerDown(position, event) ?? HitResult.none; - - HitResult pointerUp(Vec2D position) => - _stateMachineInstance?.pointerUp(position) ?? HitResult.none; - - HitResult pointerExit(Vec2D position) => - _stateMachineInstance?.pointerExit(position) ?? HitResult.none; - - void _isActiveChanged() { - // When a nested state machine re-activates (usually when an input changes) - // we need to make sure any nesting artboard knows that we're goign to need - // to advance. - if (stateMachineInstance != null && stateMachineInstance!.isActive) { - nestedArtboard?.markNeedsAdvance(); - } - } - - @override - void onRemoved() { - stateMachineInstance = null; - super.onRemoved(); - } -} diff --git a/lib/src/rive_core/animation/nested_trigger.dart b/lib/src/rive_core/animation/nested_trigger.dart deleted file mode 100644 index 4a22a85..0000000 --- a/lib/src/rive_core/animation/nested_trigger.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/nested_trigger_base.dart'; -import 'package:rive/src/rive_core/notifier.dart'; - -export 'package:rive/src/generated/animation/nested_trigger_base.dart'; - -class NestedTrigger extends NestedTriggerBase { - final Notifier firedTrigger = Notifier(); - - @override - void fire(CallbackData data) { - // Need to pass the CallbackData? - firedTrigger.notify(); - - updateValue(); - } - - @override - void updateValue() => nestedStateMachine?.setInputValue(inputId, true); -} diff --git a/lib/src/rive_core/animation/state_instance.dart b/lib/src/rive_core/animation/state_instance.dart deleted file mode 100644 index b48bdf2..0000000 --- a/lib/src/rive_core/animation/state_instance.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; - -/// Represents the instance of a [LayerState] which is being used in a -/// [LayerController] of a [StateMachineController]. Abstract representation of -/// an Animation (for [AnimationState]) or set of Animations in the case of a -/// [BlendState]. -abstract class StateInstance { - final T state; - - StateInstance(this.state); - - void advance(double seconds, StateMachineController controller); - void apply(CoreContext core, double mix); - - bool get keepGoing; - - void dispose() {} - void clearSpilledTime() {} -} - -/// A single one of these is created per Layer which just represents/wraps the -/// AnyState but conforms to the instance interface. -class SystemStateInstance extends StateInstance { - SystemStateInstance(LayerState state) : super(state); - @override - void advance(double seconds, StateMachineController controller) {} - - @override - void apply(CoreContext core, double mix) {} - - @override - bool get keepGoing => false; -} diff --git a/lib/src/rive_core/animation/state_machine.dart b/lib/src/rive_core/animation/state_machine.dart deleted file mode 100644 index 2035920..0000000 --- a/lib/src/rive_core/animation/state_machine.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; -import 'package:rive/src/rive_core/artboard.dart'; - -export 'package:rive/src/generated/animation/state_machine_base.dart'; - -class StateMachine extends StateMachineBase { - final StateMachineComponents inputs = - StateMachineComponents(); - final StateMachineComponents layers = - StateMachineComponents(); - final StateMachineComponents listeners = - StateMachineComponents(); - - @override - bool import(ImportStack stack) { - var artboardImporter = stack.latest(ArtboardBase.typeKey); - if (artboardImporter == null) { - return false; - } - artboardImporter.addStateMachine(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/animation/state_machine_bool.dart b/lib/src/rive_core/animation/state_machine_bool.dart deleted file mode 100644 index 2f65860..0000000 --- a/lib/src/rive_core/animation/state_machine_bool.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:rive/src/generated/animation/state_machine_bool_base.dart'; -export 'package:rive/src/generated/animation/state_machine_bool_base.dart'; - -class StateMachineBool extends StateMachineBoolBase { - @override - void valueChanged(bool from, bool to) {} - - @override - bool isValidType() => T == bool; -} diff --git a/lib/src/rive_core/animation/state_machine_component.dart b/lib/src/rive_core/animation/state_machine_component.dart deleted file mode 100644 index 1d451cf..0000000 --- a/lib/src/rive_core/animation/state_machine_component.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; - -export 'package:rive/src/generated/animation/state_machine_component_base.dart'; - -/// Implemented by state machine inputs and layers. -abstract class StateMachineComponent - extends StateMachineComponentBase { - StateMachine? _stateMachine; - StateMachine? get stateMachine => _stateMachine; - set stateMachine(StateMachine? machine) { - if (_stateMachine == machine) { - return; - } - if (_stateMachine != null) { - machineComponentList(_stateMachine!).remove(this); - } - _stateMachine = machine; - - if (_stateMachine != null) { - machineComponentList(_stateMachine!).add(this); - } - } - - // Intentionally using ListBase instead of FractionallyIndexedList here as - // it's more compatible with runtime. - ListBase machineComponentList(StateMachine machine); - - @override - void nameChanged(String from, String to) {} - - @override - void onAddedDirty() {} - - @override - void onAdded() {} - - @override - void onRemoved() { - super.onRemoved(); - - stateMachine = null; - } - - @override - bool import(ImportStack importStack) { - var importer = - importStack.latest(StateMachineBase.typeKey); - if (importer == null) { - return false; - } - importer.addMachineComponent(this); - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/state_machine_fire_event.dart b/lib/src/rive_core/animation/state_machine_fire_event.dart deleted file mode 100644 index 2ceb652..0000000 --- a/lib/src/rive_core/animation/state_machine_fire_event.dart +++ /dev/null @@ -1,39 +0,0 @@ -library rive_core; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_fire_event_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; - -export 'package:rive/src/generated/animation/state_machine_fire_event_base.dart'; - -enum StateMachineFireOccurance { - atStart, - atEnd, -} - -class StateMachineFireEvent extends StateMachineFireEventBase { - @override - void onAddedDirty() {} - - @override - void eventIdChanged(int from, int to) {} - - @override - void occursValueChanged(int from, int to) {} - - StateMachineFireOccurance get occurs => - enumAt(StateMachineFireOccurance.values, occursValue); - - @override - bool import(ImportStack importStack) { - var importer = importStack.latest( - StateMachineLayerComponentBase.typeKey); - if (importer == null) { - return false; - } - importer.addFireEvent(this); - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/state_machine_input.dart b/lib/src/rive_core/animation/state_machine_input.dart deleted file mode 100644 index 51e159f..0000000 --- a/lib/src/rive_core/animation/state_machine_input.dart +++ /dev/null @@ -1,21 +0,0 @@ -// ignore_for_file: use_setters_to_change_properties - -import 'dart:collection'; - -import 'package:rive/src/generated/animation/state_machine_input_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -export 'package:rive/src/generated/animation/state_machine_input_base.dart'; - -abstract class StateMachineInput extends StateMachineInputBase { - static final StateMachineInput unknown = _StateMachineUnknownInput(); - - @override - ListBase machineComponentList(StateMachine machine) => - machine.inputs; - - bool isValidType() => false; -} - -class _StateMachineUnknownInput extends StateMachineInput {} diff --git a/lib/src/rive_core/animation/state_machine_layer.dart b/lib/src/rive_core/animation/state_machine_layer.dart deleted file mode 100644 index a4e0548..0000000 --- a/lib/src/rive_core/animation/state_machine_layer.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/animation/any_state_base.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_base.dart'; -import 'package:rive/src/rive_core/animation/any_state.dart'; -import 'package:rive/src/rive_core/animation/entry_state.dart'; -import 'package:rive/src/rive_core/animation/exit_state.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -export 'package:rive/src/generated/animation/state_machine_layer_base.dart'; - -class StateMachineLayer extends StateMachineLayerBase { - LayerState? _entryState; - LayerState? _anyState; - LayerState? _exitState; - - LayerState? get entryState => _entryState; - LayerState? get anyState => _anyState; - LayerState? get exitState => _exitState; - - @override - ListBase machineComponentList(StateMachine machine) => - machine.layers; - - /// Called by rive_core to add a LayerState to the StateMachineLayer. This - /// should be @internal when it's supported. - bool internalAddState(LayerState state) { - switch (state.coreType) { - case AnyStateBase.typeKey: - _anyState = state; - break; - case ExitStateBase.typeKey: - _exitState = state; - break; - case EntryStateBase.typeKey: - _entryState = state; - break; - } - - return true; - } -} diff --git a/lib/src/rive_core/animation/state_machine_layer_component.dart b/lib/src/rive_core/animation/state_machine_layer_component.dart deleted file mode 100644 index 2d37661..0000000 --- a/lib/src/rive_core/animation/state_machine_layer_component.dart +++ /dev/null @@ -1,29 +0,0 @@ -// We really want this file to import core for the flutter runtime, so make the -// linter happy... - -// ignore: unused_import -import 'dart:collection'; - -import 'package:collection/collection.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_fire_event.dart'; - -export 'package:rive/src/generated/animation/state_machine_layer_component_base.dart'; - -abstract class StateMachineLayerComponent - extends StateMachineLayerComponentBase { - final LayerComponentEvents _events = LayerComponentEvents(); - LayerComponentEvents get events => _events; - - void internalAddFireEvent(StateMachineFireEvent event) { - assert(!_events.contains(event), 'shouldn\'t already contain the event'); - _events.add(event); - } - - Iterable eventsAt( - StateMachineFireOccurance occurence) => - _events - .where((fireEvent) => fireEvent.occurs == occurence) - .whereNotNull(); -} diff --git a/lib/src/rive_core/animation/state_machine_listener.dart b/lib/src/rive_core/animation/state_machine_listener.dart deleted file mode 100644 index b557f45..0000000 --- a/lib/src/rive_core/animation/state_machine_listener.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_machine_listener_base.dart'; -import 'package:rive/src/rive_core/animation/listener_action.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/animation/state_machine_listener_base.dart'; - -enum ListenerType { enter, exit, down, up, move, event, click } - -enum GestureClickPhase { out, down, clicked } - -class StateMachineListener extends StateMachineListenerBase { - final ListenerActions actions = ListenerActions(); - - WorldTransformComponent? _target; - WorldTransformComponent? get target => _target; - set target(WorldTransformComponent? value) { - if (_target == value) { - return; - } - - _target = value; - - targetId = _target?.id ?? Core.missingId; - } - - Event? _event; - Event? get event => _event; - set event(Event? value) { - if (_event == value) { - return; - } - - _event = value; - - eventId = _event?.id ?? Core.missingId; - } - - @override - String get name => - super.name.isEmpty ? (_target?.name ?? 'Listener') : super.name; - @override - void listenerTypeValueChanged(int from, int to) {} - - ListenerType get listenerType => ListenerType.values[listenerTypeValue]; - set listenerType(ListenerType value) => listenerTypeValue = value.index; - - @override - ListBase machineComponentList(StateMachine machine) => - machine.listeners; - - @override - void targetIdChanged(int from, int to) { - target = context.resolve(to); - } - - @override - void eventIdChanged(int from, int to) { - event = context.resolve(to); - } - - /// Called by rive_core to add an [ListenerAction] to this - /// [StateMachineListener]. This should be @internal when it's supported. - bool internalAddAction(ListenerAction action) { - if (actions.contains(action)) { - return false; - } - actions.add(action); - - return true; - } - - /// Called by rive_core to remove an [ListenerAction] from this - /// [StateMachineListener]. This should be @internal when it's supported. - bool internalRemoveAction(ListenerAction action) { - var removed = actions.remove(action); - - return removed; - } - - void performChanges(StateMachineController controller, Vec2D position, - Vec2D previousPosition) { - for (final action in actions) { - action.perform(controller, position, previousPosition); - } - } -} diff --git a/lib/src/rive_core/animation/state_machine_number.dart b/lib/src/rive_core/animation/state_machine_number.dart deleted file mode 100644 index ea614f6..0000000 --- a/lib/src/rive_core/animation/state_machine_number.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/generated/animation/state_machine_number_base.dart'; -export 'package:rive/src/generated/animation/state_machine_number_base.dart'; - -class StateMachineNumber extends StateMachineNumberBase { - @override - void valueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/animation/state_machine_trigger.dart b/lib/src/rive_core/animation/state_machine_trigger.dart deleted file mode 100644 index d1c0a23..0000000 --- a/lib/src/rive_core/animation/state_machine_trigger.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:rive/src/generated/animation/state_machine_trigger_base.dart'; -export 'package:rive/src/generated/animation/state_machine_trigger_base.dart'; - -class StateMachineTrigger extends StateMachineTriggerBase { - void fire() {} - - @override - bool isValidType() => T == bool; -} diff --git a/lib/src/rive_core/animation/state_transition.dart b/lib/src/rive_core/animation/state_transition.dart deleted file mode 100644 index 5624789..0000000 --- a/lib/src/rive_core/animation/state_transition.dart +++ /dev/null @@ -1,253 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/state_transition_base.dart'; -import 'package:rive/src/rive_core/animation/animation_state.dart'; -import 'package:rive/src/rive_core/animation/animation_state_instance.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator.dart'; -import 'package:rive/src/rive_core/animation/entry_state.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolation.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/animation/loop.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_input_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_trigger_condition.dart'; -import 'package:rive/src/rive_core/animation/transition_viewmodel_condition.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/state_transition_flags.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; - -export 'package:rive/src/generated/animation/state_transition_base.dart'; - -enum AllowTransition { no, waitingForExit, yes } - -class StateTransition extends StateTransitionBase { - final StateTransitionConditions conditions = StateTransitionConditions(); - LayerState? stateTo; - - static final StateTransition unknown = StateTransition(); - - int evaluatedRandomWeight = 0; - Interpolator? _interpolator; - Interpolator? get interpolator => _interpolator; - set interpolator(Interpolator? value) { - if (_interpolator == value) { - return; - } - - _interpolator = value; - interpolatorId = value?.id ?? Core.missingId; - } - - @override - bool validate() { - return super.validate() && - - // need this last so runtimes get it which makes the whole - // allowTransitionFrom thing above a little weird. - stateTo != null; - } - - @override - void onAdded() {} - - @override - void onAddedDirty() { - if (interpolatorId != Core.missingId && canInterpolate) { - interpolator = context.resolve(interpolatorId); - } - - switch (interpolation) { - case KeyFrameInterpolation.cubic: - if (interpolator is! CubicInterpolator) { - interpolation = KeyFrameInterpolation.linear; - } - break; - default: - break; - } - } - - bool get isDisabled => (flags & StateTransitionFlags.disabled) != 0; - bool get pauseOnExit => (flags & StateTransitionFlags.pauseOnExit) != 0; - bool get enableExitTime => (flags & StateTransitionFlags.enableExitTime) != 0; - bool get enableEarlyExit => - (flags & StateTransitionFlags.enableEarlyExit) != 0; - - /// The amount of time to mix the outgoing animation onto the incoming one - /// when changing state. Only applies when going out from an AnimationState. - /// [stateFrom] must be provided as at runtime we don't store the reference to - /// the state this transition comes from. - double mixTime(LayerState stateFrom) { - if (duration == 0) { - return 0; - } - if ((flags & StateTransitionFlags.durationIsPercentage) != 0) { - var animationDuration = 0.0; - if (stateFrom is AnimationState) { - animationDuration = stateFrom.animation?.durationSeconds ?? 0; - } - return duration / 100 * animationDuration; - } else { - return duration / 1000; - } - } - - /// Provide the animation instance to use for computing percentage durations - /// for exit time. - LinearAnimationInstance? exitTimeAnimationInstance(StateInstance stateFrom) => - stateFrom is AnimationStateInstance ? stateFrom.animationInstance : null; - - /// Provide the animation to use for computing percentage durations for exit - /// time. - LinearAnimation? exitTimeAnimation(LayerState stateFrom) => - stateFrom is AnimationState ? stateFrom.animation : null; - - /// Computes the exit time in seconds of the [stateFrom]. Set [absolute] to - /// true if you want the returned time to be relative to the entire animation. - /// Set [absolute] to false if you want it relative to the work area. - double exitTimeSeconds(LayerState stateFrom, {bool absolute = false}) { - if ((flags & StateTransitionFlags.exitTimeIsPercentage) != 0) { - var animationDuration = 0.0; - var start = 0.0; - - var exitAnimation = exitTimeAnimation(stateFrom); - if (exitAnimation != null) { - start = absolute ? exitAnimation.startSeconds : 0; - animationDuration = exitAnimation.durationSeconds; - } - - return start + exitTime / 100 * animationDuration; - } else { - return exitTime / 1000; - } - } - - @override - bool import(ImportStack importStack) { - var importer = - importStack.latest(LayerStateBase.typeKey); - if (importer == null) { - return false; - } - importer.addTransition(this); - - return super.import(importStack); - } - - /// Called by rive_core to add a [TransitionCondition] to this - /// [StateTransition]. This should be @internal when it's supported. - bool internalAddCondition(TransitionCondition condition) { - if (conditions.contains(condition)) { - return false; - } - conditions.add(condition); - - return true; - } - - /// Called by rive_core to remove a [TransitionCondition] from this - /// [StateTransition]. This should be @internal when it's supported. - bool internalRemoveCondition(TransitionCondition condition) { - var removed = conditions.remove(condition); - - return removed; - } - - @override - void flagsChanged(int from, int to) {} - - @override - void durationChanged(int from, int to) {} - - @override - void randomWeightChanged(int from, int to) {} - - @override - void exitTimeChanged(int from, int to) {} - - @override - void stateToIdChanged(int from, int to) {} - - /// Returns true when this transition can be taken from [stateFrom] with the - /// given [inputValues]. - AllowTransition allowed( - StateInstance stateFrom, - HashMap inputValues, - bool ignoreTriggers, - ViewModelInstance? viewModelInstance) { - if (isDisabled) { - return AllowTransition.no; - } - for (final condition in conditions) { - if (condition is TransitionViewModelCondition) { - return AllowTransition.no; - } else if (condition is TransitionInputCondition && - ((ignoreTriggers && condition is TransitionTriggerCondition) || - !condition.evaluate(inputValues))) { - return AllowTransition.no; - } - } - // For now we only enable exit time from AnimationStates, do we want to - // enable this for BlendStates? How would that work? - if (enableExitTime) { - var exitAnimation = exitTimeAnimationInstance(stateFrom); - if (exitAnimation != null) { - // Exit time is specified in a value less than a single loop, so we - // want to allow exiting regardless of which loop we're on. To do that - // we bring the exit time up to the loop our lastTime is at. - var lastTime = exitAnimation.lastTotalTime; - var time = exitAnimation.totalTime; - var exitTime = exitTimeSeconds(stateFrom.state); - var animationFrom = exitAnimation.animation; - if (exitTime <= animationFrom.durationSeconds && - animationFrom.loop != Loop.oneShot) { - // Get exit time relative to the loop lastTime was in. - exitTime += (lastTime / animationFrom.durationSeconds).floor() * - animationFrom.durationSeconds; - } - // Sometimes the time never reaches exitTime due to precision - // differences on diff platforms - if (time < exitTime) { - return AllowTransition.waitingForExit; - } - } - } - return AllowTransition.yes; - } - - bool applyExitCondition(StateInstance stateFrom) { - // Hold exit time when the user has set to pauseOnExit on this condition - // (only valid when exiting from an Animation). - bool useExitTime = enableExitTime && stateFrom is AnimationStateInstance; - if (pauseOnExit && useExitTime) { - stateFrom.animationInstance.time = - exitTimeSeconds(stateFrom.state, absolute: true); - return true; - } - return useExitTime; - } - - // No interpolation on Entry states. - bool get canInterpolate => stateTo is! EntryState; - - KeyFrameInterpolation get interpolation => - enumAt(KeyFrameInterpolation.values, interpolationType); - set interpolation(KeyFrameInterpolation value) { - if (canInterpolate) { - interpolationType = value.index; - } - } - - @override - void interpolationTypeChanged(int from, int to) {} - - @override - void interpolatorIdChanged(int from, int to) { - interpolator = context.resolve(to); - } -} diff --git a/lib/src/rive_core/animation/transition_artboard_condition.dart b/lib/src/rive_core/animation/transition_artboard_condition.dart deleted file mode 100644 index 3066fc6..0000000 --- a/lib/src/rive_core/animation/transition_artboard_condition.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/animation/transition_artboard_condition_base.dart'; - -export 'package:rive/src/generated/animation/transition_artboard_condition_base.dart'; - -class TransitionArtboardCondition extends TransitionArtboardConditionBase {} diff --git a/lib/src/rive_core/animation/transition_bool_condition.dart b/lib/src/rive_core/animation/transition_bool_condition.dart deleted file mode 100644 index eeef836..0000000 --- a/lib/src/rive_core/animation/transition_bool_condition.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/animation/transition_bool_condition_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_bool.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_bool_condition_base.dart'; - -class TransitionBoolCondition extends TransitionBoolConditionBase { - @override - bool validate() => super.validate() && (input is StateMachineBool); - - @override - bool evaluate(HashMap values) { - if (input is! StateMachineBool) { - return true; - } - var boolInput = input as StateMachineBool; - dynamic providedValue = values[input.id]; - bool value = providedValue is bool ? providedValue : boolInput.value; - return (value && op == TransitionConditionOp.equal) || - (!value && op == TransitionConditionOp.notEqual); - } -} diff --git a/lib/src/rive_core/animation/transition_comparator.dart b/lib/src/rive_core/animation/transition_comparator.dart deleted file mode 100644 index be4a7b9..0000000 --- a/lib/src/rive_core/animation/transition_comparator.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:rive/src/generated/animation/transition_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_comparator_base.dart'; - -abstract class TransitionComparator extends TransitionComparatorBase { - bool compareNumbers( - double left, double right, TransitionConditionOp operation) { - switch (operation) { - case TransitionConditionOp.equal: - return left == right; - case TransitionConditionOp.notEqual: - return left != right; - case TransitionConditionOp.lessThanOrEqual: - return left <= right; - case TransitionConditionOp.lessThan: - return left < right; - case TransitionConditionOp.greaterThanOrEqual: - return left >= right; - case TransitionConditionOp.greaterThan: - return left > right; - } - } - - bool compareEnums(int left, int right, TransitionConditionOp operation) { - switch (operation) { - case TransitionConditionOp.equal: - return left == right; - case TransitionConditionOp.notEqual: - return left != right; - default: - return false; - } - } - - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_condition.dart b/lib/src/rive_core/animation/transition_condition.dart deleted file mode 100644 index e7521d6..0000000 --- a/lib/src/rive_core/animation/transition_condition.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/animation/transition_condition_base.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; - -export 'package:rive/src/generated/animation/transition_condition_base.dart'; - -enum TransitionConditionOp { - equal, - notEqual, - lessThanOrEqual, - greaterThanOrEqual, - lessThan, - greaterThan, -} - -abstract class TransitionCondition extends TransitionConditionBase { - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool import(ImportStack importStack) { - var importer = importStack - .latest(StateTransitionBase.typeKey); - if (importer == null) { - return false; - } - importer.addCondition(this); - - return super.import(importStack); - } -} diff --git a/lib/src/rive_core/animation/transition_input_condition.dart b/lib/src/rive_core/animation/transition_input_condition.dart deleted file mode 100644 index f2cbcd5..0000000 --- a/lib/src/rive_core/animation/transition_input_condition.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/animation/transition_input_condition_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_input.dart'; - -export 'package:rive/src/generated/animation/transition_input_condition_base.dart'; - -abstract class TransitionInputCondition extends TransitionInputConditionBase { - StateMachineInput _input = StateMachineInput.unknown; - StateMachineInput get input => _input; - - set input(StateMachineInput value) { - if (_input == value) { - return; - } - - _input = value; - - inputId = _input.id; - } - - @override - void inputIdChanged(int from, int to) { - input = context.resolveWithDefault(to, StateMachineInput.unknown); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - - input = context.resolveWithDefault(inputId, StateMachineInput.unknown); - } - - bool evaluate(HashMap values); -} diff --git a/lib/src/rive_core/animation/transition_number_condition.dart b/lib/src/rive_core/animation/transition_number_condition.dart deleted file mode 100644 index 49a0a1c..0000000 --- a/lib/src/rive_core/animation/transition_number_condition.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/animation/transition_number_condition_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_number.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_number_condition_base.dart'; - -class TransitionNumberCondition extends TransitionNumberConditionBase { - @override - void valueChanged(double from, double to) {} - - @override - bool validate() => super.validate() && (input is StateMachineNumber); - - @override - bool evaluate(HashMap values) { - if (input is! StateMachineNumber) { - return true; - } - var doubleInput = input as StateMachineNumber; - dynamic providedValue = values[input.id]; - double inputValue = - providedValue is double ? providedValue : doubleInput.value; - switch (op) { - case TransitionConditionOp.equal: - return inputValue == value; - case TransitionConditionOp.notEqual: - return inputValue != value; - case TransitionConditionOp.lessThanOrEqual: - return inputValue <= value; - case TransitionConditionOp.lessThan: - return inputValue < value; - case TransitionConditionOp.greaterThanOrEqual: - return inputValue >= value; - case TransitionConditionOp.greaterThan: - return inputValue > value; - } - } -} diff --git a/lib/src/rive_core/animation/transition_property_comparator.dart b/lib/src/rive_core/animation/transition_property_comparator.dart deleted file mode 100644 index 283000e..0000000 --- a/lib/src/rive_core/animation/transition_property_comparator.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:rive/src/generated/animation/transition_property_comparator_base.dart'; - -export 'package:rive/src/generated/animation/transition_property_comparator_base.dart'; - -abstract class TransitionPropertyComparator - extends TransitionPropertyComparatorBase {} diff --git a/lib/src/rive_core/animation/transition_property_viewmodel_comparator.dart b/lib/src/rive_core/animation/transition_property_viewmodel_comparator.dart deleted file mode 100644 index 3730201..0000000 --- a/lib/src/rive_core/animation/transition_property_viewmodel_comparator.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/generated/animation/transition_property_viewmodel_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_property_viewmodel_comparator_base.dart'; - -class TransitionPropertyViewModelComparator - extends TransitionPropertyViewModelComparatorBase { - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_trigger_condition.dart b/lib/src/rive_core/animation/transition_trigger_condition.dart deleted file mode 100644 index 217b522..0000000 --- a/lib/src/rive_core/animation/transition_trigger_condition.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/animation/transition_trigger_condition_base.dart'; -import 'package:rive/src/rive_core/animation/state_machine_trigger.dart'; - -export 'package:rive/src/generated/animation/transition_trigger_condition_base.dart'; - -class TransitionTriggerCondition extends TransitionTriggerConditionBase { - @override - bool validate() => super.validate() && (input is StateMachineTrigger); - - @override - bool evaluate(HashMap values) { - if (input is! StateMachineTrigger) { - return true; - } - dynamic providedValue = values[input.id]; - if (providedValue is bool && providedValue) { - return true; - } - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_value_boolean_comparator.dart b/lib/src/rive_core/animation/transition_value_boolean_comparator.dart deleted file mode 100644 index 58120c3..0000000 --- a/lib/src/rive_core/animation/transition_value_boolean_comparator.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_boolean_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_boolean_comparator_base.dart'; - -class TransitionValueBooleanComparator - extends TransitionValueBooleanComparatorBase { - @override - void valueChanged(bool from, bool to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_value_color_comparator.dart b/lib/src/rive_core/animation/transition_value_color_comparator.dart deleted file mode 100644 index d4b0f56..0000000 --- a/lib/src/rive_core/animation/transition_value_color_comparator.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_color_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_color_comparator_base.dart'; - -class TransitionValueColorComparator - extends TransitionValueColorComparatorBase { - @override - void valueChanged(int from, int to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_value_comparator.dart b/lib/src/rive_core/animation/transition_value_comparator.dart deleted file mode 100644 index 5ffd9c6..0000000 --- a/lib/src/rive_core/animation/transition_value_comparator.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_comparator_base.dart'; - -export 'package:rive/src/generated/animation/transition_value_comparator_base.dart'; - -abstract class TransitionValueComparator - extends TransitionValueComparatorBase {} diff --git a/lib/src/rive_core/animation/transition_value_condition.dart b/lib/src/rive_core/animation/transition_value_condition.dart deleted file mode 100644 index 76979d5..0000000 --- a/lib/src/rive_core/animation/transition_value_condition.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_condition_base.dart'; - -abstract class TransitionValueCondition extends TransitionValueConditionBase { - TransitionConditionOp get op => TransitionConditionOp.values[opValue]; - - @override - void opValueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/animation/transition_value_enum_comparator.dart b/lib/src/rive_core/animation/transition_value_enum_comparator.dart deleted file mode 100644 index a2b21ba..0000000 --- a/lib/src/rive_core/animation/transition_value_enum_comparator.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_enum_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_enum_comparator_base.dart'; - -class TransitionValueEnumComparator extends TransitionValueEnumComparatorBase { - @override - void valueChanged(int from, int to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_value_number_comparator.dart b/lib/src/rive_core/animation/transition_value_number_comparator.dart deleted file mode 100644 index f0ca914..0000000 --- a/lib/src/rive_core/animation/transition_value_number_comparator.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_number_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_number_comparator_base.dart'; - -class TransitionValueNumberComparator - extends TransitionValueNumberComparatorBase { - @override - void valueChanged(double from, double to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_value_string_comparator.dart b/lib/src/rive_core/animation/transition_value_string_comparator.dart deleted file mode 100644 index 6473ec0..0000000 --- a/lib/src/rive_core/animation/transition_value_string_comparator.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/animation/transition_value_string_comparator_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_value_string_comparator_base.dart'; - -class TransitionValueStringComparator - extends TransitionValueStringComparatorBase { - @override - void valueChanged(String from, String to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - bool compare( - TransitionComparator comparand, TransitionConditionOp operation) { - return false; - } -} diff --git a/lib/src/rive_core/animation/transition_viewmodel_condition.dart b/lib/src/rive_core/animation/transition_viewmodel_condition.dart deleted file mode 100644 index 9c4d934..0000000 --- a/lib/src/rive_core/animation/transition_viewmodel_condition.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:rive/src/generated/animation/transition_viewmodel_condition_base.dart'; -import 'package:rive/src/rive_core/animation/transition_comparator.dart'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -export 'package:rive/src/generated/animation/transition_viewmodel_condition_base.dart'; - -class TransitionViewModelCondition extends TransitionViewModelConditionBase { - TransitionConditionOp get op => TransitionConditionOp.values[opValue]; - - @override - void opValueChanged(int from, int to) {} - - TransitionComparator? get leftComparator => - context.resolve(leftComparatorId); - - TransitionComparator? get rightComparator => - context.resolve(rightComparatorId); - - @override - void rightComparatorIdChanged(int from, int to) {} - - @override - void leftComparatorIdChanged(int from, int to) {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/artboard.dart b/lib/src/rive_core/artboard.dart deleted file mode 100644 index ff8739e..0000000 --- a/lib/src/rive_core/artboard.dart +++ /dev/null @@ -1,843 +0,0 @@ -import 'dart:collection'; -import 'dart:ui'; - -import 'package:meta/meta.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/artboard_base.dart'; -import 'package:rive/src/rive_core/animation/animation.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_bool.dart'; -import 'package:rive/src/rive_core/animation/nested_number.dart'; -import 'package:rive/src/rive_core/animation/nested_trigger.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/backboard.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind_context.dart'; -import 'package:rive/src/rive_core/data_bind/data_context.dart'; -import 'package:rive/src/rive_core/draw_rules.dart'; -import 'package:rive/src/rive_core/draw_target.dart'; -import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/joystick.dart'; -import 'package:rive/src/rive_core/layout_component.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/rive_core/rive_animation_controller.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive_common/layout_engine.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/artboard_base.dart'; - -class Artboard extends ArtboardBase with ShapePaintContainer { - final HashSet _dirtyLayout = HashSet(); - - void markLayoutDirty(LayoutComponent layoutComponent) { - _dirtyLayout.add(layoutComponent); - } - - @override - AABB get layoutBounds { - if (!hasLayoutMeasurements()) { - return AABB.fromValues( - x, - y, - x + width, - y + height, - ); - } - return super.layoutBounds; - } - - bool _frameOrigin = true; - bool hasChangedDrawOrderInLastUpdate = false; - - /// Returns true when the artboard will shift the origin from the top left to - /// the relative width/height of the artboard itself. This is what the editor - /// does visually when you change the origin value to give context as to where - /// the origin lies within the framed bounds. - bool get frameOrigin => _frameOrigin; - - /// When composing multiple artboards together in a common world-space, it may - /// be desireable to have them share the same space regardless of origin - /// offset from the bounding artboard. Set frameOrigin to false to move the - /// bounds relative to the origin instead of the origin relative to the - /// bounds. - set frameOrigin(bool value) { - if (_frameOrigin == value) { - return; - } - _frameOrigin = value; - addDirt(ComponentDirt.paint); - } - - ViewModelInstance? viewModelInstance; - - /// Should antialiasing be used when drawing? - bool _antialiasing = true; - - bool get antialiasing => _antialiasing; - set antialiasing(bool value) { - if (_antialiasing == value) { - return; - } - _antialiasing = value; - // Call syncColor on all ShapePaintMutators to update antialiasing on the - // paint objects - forAll((c) { - if (c is ShapePaintMutator) { - (c as ShapePaintMutator).syncColor(); - } - return true; - }); - } - - /// Artboard are one of the few (only?) components that can be orphaned. - @override - bool get canBeOrphaned => true; - - final Path path = Path(); - List _dependencyOrder = []; - final List _drawables = []; - final List _rules = []; - List _sortedDrawRules = []; - - final Set _components = {}; - - List get drawables => _drawables; - - final AnimationList _animations = AnimationList(); - final EventList _events = EventList(); - - /// List of animations and state machines in the artboard. - AnimationList get animations => _animations; - - /// List of events in the artboard. - EventList get events => _events; - - DataContext? dataContext; - final List globalDataBinds = []; - - /// List of linear animations in the artboard. - Iterable get linearAnimations => - _animations.whereType(); - - /// List of state machines in the artboard. - Iterable get stateMachines => - _animations.whereType(); - - int _dirtDepth = 0; - - /// Iterate each component and call callback for it. - void forEachComponent(void Function(Component) callback) => - _components.forEach(callback); - - /// Find a component of a specific type with a specific name. - T? component(String name) { - return getComponentWhereOrNull((component) => component.name == name); - } - - /// Find a component that matches the given predicate. - T? getComponentWhereOrNull(bool Function(Component) callback) { - for (final component in _components) { - if (component is T && callback(component)) { - return component as T; - } - } - return null; - } - - @override - Artboard get artboard => this; - - Vec2D get originWorld { - return Vec2D.fromValues(x + width * originX, y + height * originY); - } - - Vec2D get origin => Vec2D.fromValues(width * originX, height * originY); - - /// Walk the dependency tree and update components in order. Returns true if - /// any component updated. - bool updateComponents() { - bool didUpdate = false; - - if ((dirt & ComponentDirt.bindings) != 0) { - computeBindings(true); - dirt &= ~ComponentDirt.bindings; - didUpdate = true; - } - if ((dirt & ComponentDirt.drawOrder) != 0) { - sortDrawOrder(); - dirt &= ~ComponentDirt.drawOrder; - didUpdate = true; - } - if ((dirt & ComponentDirt.components) != 0) { - const int maxSteps = 100; - int step = 0; - int count = _dependencyOrder.length; - while ((dirt & ComponentDirt.components) != 0 && step < maxSteps) { - dirt &= ~ComponentDirt.components; - // Track dirt depth here so that if something else marks - // dirty, we restart. - for (int i = 0; i < count; i++) { - Component component = _dependencyOrder[i]; - _dirtDepth = i; - int d = component.dirt; - - if (d == 0 || (d & ComponentDirt.collapsed) != 0) { - continue; - } - - component.dirt &= ComponentDirt.collapsed; - component.update(d); - if (_dirtDepth < i) { - break; - } - } - step++; - } - return true; - } - return didUpdate; - } - - final Set _activeNestedArtboards = {}; - Iterable get activeNestedArtboards => _activeNestedArtboards; - - final List _joysticks = []; - Iterable get joysticks => _joysticks; - - final List _dataBinds = []; - Iterable get dataBinds => _dataBinds; - - bool canPreApplyJoysticks() { - if (_joysticks.isEmpty) { - return false; - } - if (_joysticks.any((joystick) => joystick.isComplex)) { - return false; - } - return true; - } - - void updateDataBinds() { - for (final dataBind in globalDataBinds) { - dataBind.updateSourceBinding(); - final dirt = dataBind.dirt; - if (dirt == 0) { - continue; - } - dataBind.update(dirt); - dataBind.dirt = 0; - } - } - - bool applyJoysticks({bool isRoot = false}) { - if (_joysticks.isEmpty) { - return false; - } - for (final joystick in _joysticks) { - if (isRoot) { - updateDataBinds(); - } - if (joystick.isComplex) { - updateComponents(); - } - joystick.apply(context); - } - return true; - } - - /// Update any dirty components in this artboard. - bool advanceInternal(double elapsedSeconds, - {bool nested = false, bool isRoot = false}) { - bool didUpdate = false; - if (_dirtyLayout.isNotEmpty) { - var dirtyLayout = _dirtyLayout.toList(); - _dirtyLayout.clear(); - syncStyle(); - for (final layoutComponent in dirtyLayout) { - layoutComponent.syncStyle(); - } - layoutNode.calculateLayout(width, height, LayoutDirection.ltr); - if (dirt & ComponentDirt.layoutStyle != 0) { - // Maybe we can genericize this to pass all styles to children if - // the child should inherit - cascadeAnimationStyle(interpolation, interpolator, interpolationTime); - } - // Need to sync all layout positions. - for (final layout in _dependencyOrder.whereType()) { - layout.updateLayoutBounds(); - if ((layout == this && super.advance(elapsedSeconds)) || - (layout != this && layout.advance(elapsedSeconds))) { - didUpdate = true; - } - } - } - - for (final controller in _animationControllers) { - if (controller.isActive) { - controller.apply(context, elapsedSeconds); - didUpdate = true; - } - } - hasChangedDrawOrderInLastUpdate = false; - - // Joysticks can be applied before updating components if none of the - // joysticks have "external" control. If they are controlled/moved by some - // other component then they need to apply after the update cycle, which is - // less efficient. - var canApplyJoysticksEarly = canPreApplyJoysticks(); - if (canApplyJoysticksEarly) { - applyJoysticks(isRoot: isRoot); - } - - if (isRoot) { - updateDataBinds(); - } - if (updateComponents() || didUpdate) { - didUpdate = true; - } - - // If joysticks applied, run the update again for the animation changes. - if (!canApplyJoysticksEarly && applyJoysticks(isRoot: isRoot)) { - if (updateComponents()) { - didUpdate = true; - } - } - - if (nested) { - var active = _activeNestedArtboards.toList(growable: false); - for (final activeNestedArtboard in active) { - if (activeNestedArtboard.advance(elapsedSeconds)) { - didUpdate = true; - } - } - } - - return didUpdate; - } - - @override - bool advance(double elapsedSeconds, {bool nested = false}) { - return advanceInternal(elapsedSeconds, nested: nested, isRoot: true); - } - - @override - void heightChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - invalidateStrokeEffects(); - super.heightChanged(from, to); - } - - void onComponentDirty(Component component) { - if ((dirt & ComponentDirt.components) == 0) { - context.markNeedsAdvance(); - dirt |= ComponentDirt.components; - } - - /// If the order of the component is less than the current dirt depth, - /// update the dirt depth so that the update loop can break out early and - /// re-run (something up the tree is dirty). - if (component.graphOrder < _dirtDepth) { - _dirtDepth = component.graphOrder; - } - } - - @override - bool resolveArtboard() => true; - - /// Sort the DAG for resolution in order of dependencies such that dependent - /// components process after their dependencies. - void sortDependencies() { - var optimistic = DependencyGraphNodeSorter(); - var order = optimistic.sort(this); - if (order.isEmpty) { - // cycle detected, use a more robust solver - var robust = TarjansDependencyGraphNodeSorter(); - order = robust.sort(this); - } - - _dependencyOrder = order; - for (final component in _dependencyOrder) { - component.graphOrder = graphOrder++; - // component.dirt = 255; - } - - dirt |= ComponentDirt.components; - } - - @override - void update(int dirt) { - if (dirt & ComponentDirt.worldTransform != 0) { - var rect = - Rect.fromLTWH(width * -originX, height * -originY, width, height); - path.reset(); - path.addRect(rect); - - for (final fill in fills) { - fill.renderOpacity = opacity; - } - for (final stroke in strokes) { - stroke.renderOpacity = opacity; - } - } - } - - @override - void widthChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - invalidateStrokeEffects(); - super.widthChanged(from, to); - } - - @override - void xChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - } - - @override - void yChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - } - - @override - void viewModelIdChanged(int from, int to) {} - - Vec2D renderTranslation(Vec2D worldTranslation) { - final wt = originWorld; - return worldTranslation + wt; - } - - Mat2D get renderTransform => Mat2D.fromTranslate(x, y); - - /// Adds a component to the artboard. Good place for the artboard to check for - /// components it'll later need to do stuff with (like draw them or sort them - /// when the draw order changes). - void addComponent(Component component) { - if (!_components.add(component)) { - return; - } - switch (component.coreType) { - case NestedArtboardBase.typeKey: - addNestedArtboard(component as NestedArtboard); - break; - case NestedBoolBase.typeKey: - case NestedNumberBase.typeKey: - case NestedTriggerBase.typeKey: - break; - case JoystickBase.typeKey: - _joysticks.add(component as Joystick); - break; - case DataBindBase.typeKey: - case DataBindContextBase.typeKey: - _dataBinds.add(component as DataBind); - break; - } - } - - /// Remove a component from the artboard and its various tracked lists of - /// components. - void removeComponent(Component component) { - _components.remove(component); - switch (component.coreType) { - case NestedArtboardBase.typeKey: - removeNestedArtboard(component as NestedArtboard); - break; - case NestedBoolBase.typeKey: - case NestedNumberBase.typeKey: - case NestedTriggerBase.typeKey: - break; - case JoystickBase.typeKey: - _joysticks.remove(component as Joystick); - break; - case DataBindBase.typeKey: - case DataBindContextBase.typeKey: - _dataBinds.remove(component as DataBind); - break; - } - } - - void addNestedArtboard(NestedArtboard artboard) { - _activeNestedArtboards.add(artboard); - } - - void removeNestedArtboard(NestedArtboard artboard) { - _activeNestedArtboards.remove(artboard); - } - - /// Let the artboard know that the drawables need to be resorted before - /// drawing next. - void markDrawOrderDirty() { - if ((dirt & ComponentDirt.drawOrder) == 0) { - context.markNeedsAdvance(); - dirt |= ComponentDirt.drawOrder; - } - } - - /// Draw the drawable components in this artboard. - void draw( - Canvas canvas, - ) { - canvas.save(); - if (clip) { - if (_frameOrigin) { - canvas.clipRect(Rect.fromLTWH(0, 0, width, height)); - } else { - canvas.clipRect( - Rect.fromLTWH(-width * originX, -height * originY, width, height)); - } - } - // Get into artboard's world space. This is because the artboard draws - // components in the artboard's space (in component lingo we call this world - // space). The artboards themselves are drawn in the editor's world space, - // which is the world space that is used by stageItems. This is a little - // confusing and perhaps we should find a better wording for the transform - // spaces. We used "world space" in components as that's the game engine - // ratified way of naming the top-most transformation. Perhaps we should - // rename those to artboardTransform and worldTransform is only reserved for - // stageItems? The other option is to stick with 'worldTransform' in - // components and use 'editor or stageTransform' for stageItems. - if (_frameOrigin) { - canvas.translate(width * originX, height * originY); - } - - for (final fill in fills) { - fill.draw(canvas, path); - } - - for (var drawable = firstDrawable; - drawable != null; - drawable = drawable.prev) { - if (drawable.isHidden || drawable.renderOpacity == 0) { - continue; - } - - drawable.draw(canvas); - } - - canvas.restore(); - } - - @override - void originXChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - } - - @override - void originYChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - } - - /// Called by rive_core to add an Animation to an Artboard. This should be - /// @internal when it's supported. - bool internalAddAnimation(Animation animation) { - if (_animations.contains(animation)) { - return false; - } - _animations.add(animation); - - return true; - } - - /// Called by rive_core to remove an Animation from an Artboard. This should - /// be @internal when it's supported. - bool internalRemoveAnimation(Animation animation) { - bool removed = _animations.remove(animation); - - return removed; - } - - /// Called by rive_core to add an Event to an Artboard. This should be - /// @internal when it's supported. - bool internalAddEvent(Event event) { - if (_events.contains(event)) { - return false; - } - _events.add(event); - - return true; - } - - /// Called by rive_core to remove an Event from an Artboard. This should - /// be @internal when it's supported. - bool internalRemoveEvent(Event event) { - bool removed = _events.remove(event); - - return removed; - } - - /// The animation controllers that are called back whenever the artboard - /// advances. - final Set _animationControllers = {}; - - /// Access a read-only iterator of currently applied animation controllers. - Iterable get animationControllers => - _animationControllers; - - /// Add an animation controller to this artboard. Playing will be scheduled if - /// it's already playing. - bool addController(RiveAnimationController controller) { - if (_animationControllers.contains(controller) || - !controller.init(context)) { - return false; - } - controller.isActiveChanged.addListener(_onControllerPlayingChanged); - _animationControllers.add(controller); - if (controller.isActive) { - context.markNeedsAdvance(); - } - return true; - } - - /// Remove an animation controller form this artboard. - bool removeController(RiveAnimationController controller) { - if (_animationControllers.remove(controller)) { - controller.isActiveChanged.removeListener(_onControllerPlayingChanged); - controller.dispose(); - return true; - } - return false; - } - - void _onControllerPlayingChanged() => context.markNeedsAdvance(); - - @override - void onFillsChanged() {} - - @override - void onPaintMutatorChanged(ShapePaintMutator mutator) {} - - @override - void onStrokesChanged() {} - - @mustBeOverridden - void play() {} - - @mustBeOverridden - void pause() {} - - @mustBeOverridden - bool get isPlaying => true; - - @override - Vec2D get worldTranslation => Vec2D(); - - Drawable? firstDrawable; - - void computeDrawOrder() { - _drawables.clear(); - _rules.clear(); - buildDrawOrder(_drawables, null, _rules); - - // Build rule dependencies. In practice this'll need to happen anytime a - // target drawable is changed or rule is added/removed. - var root = DrawTarget(); - // Make sure all dependents are empty. - for (final nodeRules in _rules) { - for (final target in nodeRules.targets) { - target.dependents.clear(); - } - } - - // Now build up the dependencies. - for (final nodeRules in _rules) { - for (final target in nodeRules.targets) { - root.dependents.add(target); - var dependentRules = target.drawable?.flattenedDrawRules; - if (dependentRules != null) { - for (final dependentRule in dependentRules.targets) { - dependentRule.dependents.add(target); - } - } - } - } - - var sorter = DependencyGraphNodeSorter(); - - _sortedDrawRules = sorter.sort(root).cast().skip(1).toList(); - - sortDrawOrder(); - } - - void populateDataBinds(List globalDataBinds) { - dataBinds.forEach((dataBind) { - globalDataBinds.add(dataBind); - }); - - for (final nestedArtboard in _activeNestedArtboards) { - final mountedArtboard = nestedArtboard.mountedArtboard; - if (mountedArtboard != null) { - mountedArtboard.populateDataBinds(globalDataBinds); - } - } - } - - void sortDataBinds() { - globalDataBinds.sort((a, b) => a.flags.compareTo(b.flags) * -1); - } - - void computeBindings(bool isRoot) { - if (dataContext == null) { - return; - } - for (final dataBind in dataBinds) { - dataBind.bind(dataContext); - } - if (isRoot) { - globalDataBinds.clear(); - populateDataBinds(globalDataBinds); - sortDataBinds(); - } - } - - void sortDrawOrder() { - hasChangedDrawOrderInLastUpdate = true; - // Clear out rule first/last items. - for (final rule in _sortedDrawRules) { - rule.first = rule.last = null; - } - - firstDrawable = null; - Drawable? lastDrawable; - for (final drawable in _drawables) { - var rules = drawable.flattenedDrawRules; - - var target = rules?.activeTarget; - if (target != null) { - if (target.first == null) { - target.first = target.last = drawable; - drawable.prev = drawable.next = null; - } else { - target.last?.next = drawable; - drawable.prev = target.last; - target.last = drawable; - drawable.next = null; - } - } else { - drawable.prev = lastDrawable; - drawable.next = null; - if (lastDrawable == null) { - lastDrawable = firstDrawable = drawable; - } else { - lastDrawable.next = drawable; - lastDrawable = drawable; - } - } - } - - for (final rule in _sortedDrawRules) { - if (rule.first == null) { - continue; - } - switch (rule.placement) { - case DrawTargetPlacement.before: - if (rule.drawable?.prev != null) { - rule.drawable!.prev?.next = rule.first; - rule.first?.prev = rule.drawable!.prev; - } - if (rule.drawable == firstDrawable) { - firstDrawable = rule.first; - } - rule.drawable?.prev = rule.last; - rule.last?.next = rule.drawable; - break; - case DrawTargetPlacement.after: - if (rule.drawable?.next != null) { - rule.drawable!.next!.prev = rule.last; - rule.last?.next = rule.drawable?.next; - } - if (rule.drawable == lastDrawable) { - lastDrawable = rule.last; - } - rule.drawable?.next = rule.first; - rule.first?.prev = rule.drawable; - break; - } - } - - firstDrawable = lastDrawable; - } - - // Make an instance of the artboard, clones internal objects and properties. - Artboard instance() { - /// Intentionally not implemented in the editor, must be overridden in - /// runtime version of the artboard. - throw UnsupportedError( - 'Instancing the artboard in the editor isn\'t supported'); - } - - @override - void clipChanged(bool from, bool to) { - addDirt(ComponentDirt.paint); - } - - @override - bool import(ImportStack stack) { - var backboardImporter = - stack.latest(BackboardBase.typeKey); - if (backboardImporter != null) { - // Backboard isn't strictly required (editor doesn't always export a - // backboard when serializing for the clipboard, for example). - backboardImporter.addArtboard(this); - } - - return super.import(stack); - } - - StateMachine? _defaultStateMachine; - StateMachine? get defaultStateMachine => _defaultStateMachine; - set defaultStateMachine(StateMachine? value) { - if (_defaultStateMachine == value) { - return; - } - - _defaultStateMachine = value; - defaultStateMachineId = value?.id ?? Core.missingId; - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - dependencyRoot = this; - defaultStateMachine = defaultStateMachineId == Core.missingId - ? null - : context.resolve(defaultStateMachineId); - } - - @override - void defaultStateMachineIdChanged(int from, int to) { - defaultStateMachine = to == Core.missingId ? null : context.resolve(to); - } - - void internalDataContext(DataContext dataContextValue, - DataContext? parentDataContext, bool isRoot) { - dataContext = dataContextValue; - dataContext!.parent = parentDataContext; - for (final nestedArtboard in _activeNestedArtboards) { - final mountedArtboard = nestedArtboard.mountedArtboard; - if (mountedArtboard != null) { - ViewModelInstance? nestedViewModelInstance = - dataContext!.getViewModelInstance(nestedArtboard.dataBindPath); - if (nestedViewModelInstance != null) { - mountedArtboard.bindViewModelInstance( - nestedViewModelInstance, dataContext, false); - } else { - mountedArtboard.internalDataContext( - dataContext!, dataContext!.parent, false); - } - } - } - computeBindings(isRoot); - } - - void bindViewModelInstance( - ViewModelInstance viewModelInstance, DataContext? parent, bool isRoot) { - final dataContext = DataContext(viewModelInstance); - internalDataContext(dataContext, parent, isRoot); - } -} diff --git a/lib/src/rive_core/assets/asset.dart b/lib/src/rive_core/assets/asset.dart deleted file mode 100644 index 1fc54d4..0000000 --- a/lib/src/rive_core/assets/asset.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/generated/assets/asset_base.dart'; - -export 'package:rive/src/generated/assets/asset_base.dart'; - -abstract class Asset extends AssetBase { - @override - void nameChanged(String from, String to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/assets/audio_asset.dart b/lib/src/rive_core/assets/audio_asset.dart deleted file mode 100644 index a4f4dcc..0000000 --- a/lib/src/rive_core/assets/audio_asset.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:rive/src/generated/assets/audio_asset_base.dart'; -import 'package:rive_common/rive_audio.dart'; - -export 'package:rive/src/generated/assets/audio_asset_base.dart'; - -enum AudioContainerFormat { unknown, wav, flac, mp3 } - -class AudioAsset extends AudioAssetBase { - Uint8List? _audioBytes; - final ValueNotifier audioSource = ValueNotifier(null); - - Uint8List? get audioBytes => _audioBytes; - set audioBytes(Uint8List? bytes) { - if (_audioBytes == bytes) { - return; - } - _audioBytes = bytes; - audioSource.value?.dispose(); - if (bytes != null) { - audioSource.value = AudioEngine.loadSource(bytes); - } else { - audioSource.value = null; - } - } - - @override - Future decode(Uint8List bytes) async { - audioBytes = bytes; - } - - static AudioContainerFormat containerFormatFromName(String name) { - switch (name) { - case 'flac': - return AudioContainerFormat.flac; - case 'mp3': - return AudioContainerFormat.mp3; - case 'wav': - return AudioContainerFormat.wav; - } - return AudioContainerFormat.unknown; - } - - // See comment in font_asset.dart - @override - String get fileExtension => 'wav'; -} diff --git a/lib/src/rive_core/assets/drawable_asset.dart b/lib/src/rive_core/assets/drawable_asset.dart deleted file mode 100644 index a135124..0000000 --- a/lib/src/rive_core/assets/drawable_asset.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/assets/drawable_asset_base.dart'; - -export 'package:rive/src/generated/assets/drawable_asset_base.dart'; - -abstract class DrawableAsset extends DrawableAssetBase { - @override - void heightChanged(double from, double to) {} - - @override - void widthChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/assets/export_audio.dart b/lib/src/rive_core/assets/export_audio.dart deleted file mode 100644 index 8b6856a..0000000 --- a/lib/src/rive_core/assets/export_audio.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:rive/src/generated/assets/export_audio_base.dart'; -export 'package:rive/src/generated/assets/export_audio_base.dart'; - -abstract class ExportAudio extends ExportAudioBase { - @override - void volumeChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/assets/file_asset.dart b/lib/src/rive_core/assets/file_asset.dart deleted file mode 100644 index f5dcf81..0000000 --- a/lib/src/rive_core/assets/file_asset.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/assets/file_asset_base.dart'; -import 'package:rive/src/rive_core/backboard.dart'; - -export 'package:rive/src/generated/assets/file_asset_base.dart'; - -abstract class FileAsset extends FileAssetBase { - late final List> _fileAssetReferencers = - []; - List> get fileAssetReferencers => - _fileAssetReferencers; - - // this needs to be late to be able to refer to _fileAssetReferencers - late Finalizer finalizer = Finalizer((_) { - // remove file asset referencers that are no longer alive when - // the finalizer is triggered. - _fileAssetReferencers.removeWhere((element) => element.target == null); - }); - - /// Add a callback to be executed when the asset has been loaded/updated - void registerFileAssetReferencer(FileAssetReferencer referencer) { - _fileAssetReferencers.add(WeakReference(referencer)); - - // we do not passe the referencer itself here because that would - // keep the referencer alive - finalizer.attach(referencer, null); - } - - @override - void assetIdChanged(int from, int to) {} - - @override - void cdnUuidChanged(Uint8List from, Uint8List to) {} - - @override - void cdnBaseUrlChanged(String from, String to) {} - - Future decode(Uint8List bytes); - - @override - bool import(ImportStack stack) { - var backboardImporter = - stack.latest(BackboardBase.typeKey); - if (backboardImporter == null) { - return false; - } - - // When we paste a FileAssetReference (e.g an Image) into a file, we want to - // prevent the asset being re-added if there is already a copy of it in the - // file. We check if an asset with the same assetId already exists, and if - // so add it to the backboard importer, any fileAssetReferences will map - // to the existing asset instead. - for (final object in backboardImporter.backboard.assets) { - if (object is FileAsset && object.assetId == assetId) { - backboardImporter.addFileAsset(object); - return false; - } - } - - backboardImporter.addFileAsset(this); - return super.import(stack); - } - - /// Returns the file extension, for example for an image it would be png. - String get fileExtension; - - /// Returns a unique filename, useful for resolving files out of band. - String get uniqueFilename { - // remove final extension - var uniqueFilename = name; - var index = uniqueFilename.lastIndexOf('.'); - if (index != -1) { - uniqueFilename = uniqueFilename.substring(0, index); - } - return '$uniqueFilename-$assetId.$fileExtension'; - } -} - -/// A mixin for any class that references a generic FileAsset. -abstract class FileAssetReferencer { - T? _asset; - T? get asset => _asset; - - int get assetId; - set assetId(int value); - - set asset(T? value) => setAsset(value); - - void setAsset(T? value, {bool changeId = true}) { - if (_asset == value) { - return; - } - - _asset = value; - - _asset?.registerFileAssetReferencer(this); - if (changeId) { - assetId = value?.id ?? Core.missingId; - } - } - - /// Get the Core typeKey for the property that stores the assetId on the - /// concrete object. - int get assetIdPropertyKey; - - bool registerWithImporter(ImportStack stack) { - var backboardImporter = - stack.latest(BackboardBase.typeKey); - if (backboardImporter == null) { - return false; - } - backboardImporter.addFileAssetReferencer(this); - - return true; - } -} diff --git a/lib/src/rive_core/assets/file_asset_contents.dart b/lib/src/rive_core/assets/file_asset_contents.dart deleted file mode 100644 index 21d1b48..0000000 --- a/lib/src/rive_core/assets/file_asset_contents.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/assets/file_asset_contents_base.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; - -export 'package:rive/src/generated/assets/file_asset_contents_base.dart'; - -/// Stores the data of the bytes into an object that is always imported in -/// context of a FileAsset. -class FileAssetContents extends FileAssetContentsBase { - @override - void bytesChanged(List from, List to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - /// Never permanently added to core, so always invalidate. - @override - bool validate() => false; - - @override - bool import(ImportStack stack) { - var resolver = stack.latest(FileAssetBase.typeKey); - if (resolver == null) { - return false; - } - resolver.resolveContents(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/assets/folder.dart b/lib/src/rive_core/assets/folder.dart deleted file mode 100644 index 54226e5..0000000 --- a/lib/src/rive_core/assets/folder.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:rive/src/generated/assets/folder_base.dart'; -export 'package:rive/src/generated/assets/folder_base.dart'; - -class Folder extends FolderBase {} diff --git a/lib/src/rive_core/assets/font_asset.dart b/lib/src/rive_core/assets/font_asset.dart deleted file mode 100644 index 3b9739d..0000000 --- a/lib/src/rive_core/assets/font_asset.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:rive/src/generated/assets/font_asset_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/text/text_style.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/assets/font_asset_base.dart'; - -class FontAsset extends FontAssetBase { - final Set _callbacks = {}; - - /// Call [callback] when the font is ready. Set [notifyAlreadySet] to - /// specify if you want to be called if the font is already set. - bool setFontCallback( - VoidCallback callback, { - bool notifyAlreadySet = true, - }) { - if (font != null) { - if (notifyAlreadySet) { - callback(); - } - return true; - } - - _callbacks.add(callback); - return false; - } - - Font? _font; - Font? get font => _font; - set font(Font? font) { - if (_font == font) { - return; - } - _font = font; - - var callbacks = _callbacks.toList(growable: false); - _callbacks.clear(); - for (final callback in callbacks) { - callback(); - } - - // the referencer could register a callback as well rather - // actual referencers. might be cleaner for this specific scenario - // but i'm not sure if there are other use-cases for the back-ref - // that will require a different paradigm - for (final referencer in fileAssetReferencers) { - final target = referencer.target; - if (target is TextStyle) { - target.addDirt(ComponentDirt.textShape); - } - } - } - - @override - Future decode(Uint8List bytes) async { - font = await parseBytes(bytes); - } - - static Future parseBytes(Uint8List bytes) async { - return Font.decode(bytes); - } - - @override - void onRemoved() { - super.onRemoved(); - font?.dispose(); - font = null; - } - - // 'otf' supported as well. This getter isn't being used for fontAssets so - // fine just being ttf for now. - @override - String get fileExtension => 'ttf'; -} diff --git a/lib/src/rive_core/assets/image_asset.dart b/lib/src/rive_core/assets/image_asset.dart deleted file mode 100644 index 197e049..0000000 --- a/lib/src/rive_core/assets/image_asset.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'dart:async'; -import 'dart:ui' as ui; - -import 'package:flutter/foundation.dart'; -import 'package:rive/src/generated/assets/image_asset_base.dart'; -import 'package:rive/src/rive_core/shapes/image.dart'; - -export 'package:rive/src/generated/assets/image_asset_base.dart'; - -class ImageAsset extends ImageAssetBase { - ui.Image? _image; - ui.Image? get image => _image; - - ImageAsset(); - - @visibleForTesting - ImageAsset.fromTestImage(this._image); - - set image(ui.Image? image) { - if (_image == image) { - return; - } - _image = image; - } - - @override - Future decode(Uint8List bytes) async { - image = await parseBytes(bytes); - } - - static Future parseBytes(Uint8List bytes) async { - final codec = await ui.instantiateImageCodec(bytes); - final frameInfo = await codec.getNextFrame(); - return frameInfo.image; - } - - Image getDefaultObject() => Image() - ..asset = this - ..name = name; - - static final imageExtensions = ['png', 'webp', 'jpeg']; - - @override - String get fileExtension => imageExtensions[format]; - - int get format => 0; -} diff --git a/lib/src/rive_core/audio_event.dart b/lib/src/rive_core/audio_event.dart deleted file mode 100644 index 9379629..0000000 --- a/lib/src/rive_core/audio_event.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/audio_event_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/assets/audio_asset.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/audio_player.dart'; - -export 'package:rive/src/generated/audio_event_base.dart'; - -class AudioEvent extends AudioEventBase with FileAssetReferencer { - @override - void changeArtboard(Artboard? value) { - artboard?.internalRemoveEvent(this); - super.changeArtboard(value); - artboard?.internalAddEvent(this); - } - - @override - void assetIdChanged(int from, int to) { - asset = context.resolve(to); - } - - @override - void copy(covariant AudioEvent source) { - super.copy(source); - asset = source.asset; - } - - @override - int get assetIdPropertyKey => AudioEventBase.assetIdPropertyKey; - - @override - bool import(ImportStack stack) { - if (!registerWithImporter(stack)) { - return false; - } - return super.import(stack); - } - - void play(AudioPlayer player) { - player.playSource(asset); - } -} diff --git a/lib/src/rive_core/audio_player.dart b/lib/src/rive_core/audio_player.dart deleted file mode 100644 index 258121c..0000000 --- a/lib/src/rive_core/audio_player.dart +++ /dev/null @@ -1,130 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:rive/src/rive_core/assets/audio_asset.dart'; -import 'package:rive_common/rive_audio.dart'; - -class AudioPlayer { - final ValueNotifier isPlaying = ValueNotifier(false); - AudioEngine? _engine; - AudioEngine? get engine => _engine; - final List _sounds = []; - - Timer? _timer; - - AudioPlayer({required AudioEngine? engine}) : _engine = engine; - - static AudioPlayer? make() { - var engine = AudioEngine.init(2, AudioEngine.playbackSampleRate); - if (engine == null) { - return null; - } - - return AudioPlayer(engine: engine); - } - - double get engineTimeInSeconds { - var engine = this.engine; - if (engine == null) { - return 0; - } - return engine.timeInFrames / engine.sampleRate; - } - - void playBuffered( - BufferedAudioSource source, { - Duration startTime = Duration.zero, - Duration? endTime, - double volume = 1, - }) { - var engine = this.engine; - if (engine == null) { - return; - } - - if (startTime > source.duration) { - return; - } - - var engineTime = engine.timeInFrames; - - isPlaying.value = true; - - var sound = engine.play( - source, - engineTime, - endTime == null - ? 0 - : (engineTime + - (endTime - startTime).inMicroseconds * - 1e-6 * - engine.sampleRate) - .round(), - (startTime.inMicroseconds * 1e-6 * engine.sampleRate).round()); - if (volume != 1) { - sound.volume = volume; - } - _sounds.add(sound); - _timer ??= Timer.periodic(const Duration(seconds: 1), _frameCallback); - } - - bool playSource(AudioAsset? audio) { - var source = audio?.audioSource.value; - if (source == null) { - return false; - } - var engine = this.engine; - if (engine == null) { - return false; - } - - var engineTime = engine.timeInFrames; - - var sound = engine.play(source, engineTime, 0, 0); - if (audio?.volume != 1) { - sound.volume = audio?.volume ?? 1; - } - _sounds.add(sound); - _timer ??= Timer.periodic(const Duration(seconds: 1), _frameCallback); - return true; - } - - void _frameCallback(Timer timer) { - var engine = this.engine; - if (engine == null) { - return; - } - - var completed = _sounds.where((sound) => sound.completed).toList(); - - _sounds.removeWhere((sound) => sound.completed); - for (final sound in completed) { - sound.dispose(); - } - if (_sounds.isEmpty) { - _timer?.cancel(); - _timer = null; - } - } - - void stop() { - isPlaying.value = false; - _timer?.cancel(); - _timer = null; - for (final sound in _sounds) { - sound.stop(); - sound.dispose(); - } - _sounds.clear(); - } - - void dispose() { - var engine = this.engine; - if (engine == null) { - return; - } - stop(); - engine.dispose(); - _engine = null; - } -} diff --git a/lib/src/rive_core/backboard.dart b/lib/src/rive_core/backboard.dart deleted file mode 100644 index 671bfb2..0000000 --- a/lib/src/rive_core/backboard.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/backboard_base.dart'; -import 'package:rive/src/rive_core/assets/asset.dart'; - -export 'package:rive/src/generated/backboard_base.dart'; - -class Backboard extends BackboardBase { - static final Backboard unknown = Backboard(); - - final AssetList _assets = AssetList(); - AssetList get assets => _assets; - - bool internalAddAsset(Asset asset) { - if (_assets.contains(asset)) { - return false; - } - _assets.add(asset); - - return true; - } - - bool internalRemoveAsset(Asset asset) { - bool removed = _assets.remove(asset); - - return removed; - } - - @override - void onAdded() {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/bones/bone.dart b/lib/src/rive_core/bones/bone.dart deleted file mode 100644 index d83e6c4..0000000 --- a/lib/src/rive_core/bones/bone.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:rive/src/generated/bones/bone_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/bones/bone_base.dart'; - -typedef bool BoneCallback(Bone bone); - -class Bone extends BoneBase { - /// Child constraints applied to some child of this bone which also affect - /// this bone. - final Set _peerConstraints = {}; - Iterable get peerConstraints => _peerConstraints; - - bool addPeerConstraint(Constraint child) => _peerConstraints.add(child); - bool removePeerConstraint(Constraint child) => _peerConstraints.remove(child); - - @override - void lengthChanged(double from, double to) { - for (final child in children) { - if (child.coreType == BoneBase.typeKey) { - (child as Bone).markTransformDirty(); - } - } - } - - Bone? get firstChildBone { - for (final child in children) { - if (child.coreType == BoneBase.typeKey) { - return child as Bone; - } - } - return null; - } - - /// Iterate through the child bones. [BoneCallback] returns false if iteration - /// can stop. Returns false if iteration stopped, true if it made it through - /// the whole list. - bool forEachBone(BoneCallback callback) { - for (final child in children) { - if (child.coreType == BoneBase.typeKey) { - if (!callback(child as Bone)) { - return false; - } - } - } - return true; - } - - @override - double get x => (parent as Bone).length; - - @override - set x(double value) { - throw UnsupportedError('not expected to set x on a bone.'); - } - - @override - double get y => 0; - - @override - set y(double value) { - throw UnsupportedError('not expected to set y on a bone.'); - } - - @override - bool validate() { - // Bones are only valid if they're parented to other bones. RootBones are a - // special case, but they inherit from bone so we check the concrete type - // here to make sure we evalute this check only for non-root bones. - return super.validate() && (coreType != BoneBase.typeKey || parent is Bone); - } - - Vec2D get tipWorldTranslation => getTipWorldTranslation(worldTransform); - - Vec2D getTipWorldTranslation(Mat2D worldTransform) { - return worldTransform.mapXY(length, 0); - } -} diff --git a/lib/src/rive_core/bones/cubic_weight.dart b/lib/src/rive_core/bones/cubic_weight.dart deleted file mode 100644 index 9caa65b..0000000 --- a/lib/src/rive_core/bones/cubic_weight.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:rive/src/generated/bones/cubic_weight_base.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/bones/cubic_weight_base.dart'; - -class CubicWeight extends CubicWeightBase { - final Vec2D inTranslation = Vec2D(); - final Vec2D outTranslation = Vec2D(); - - @override - void inIndicesChanged(int from, int to) {} - - @override - void inValuesChanged(int from, int to) {} - - @override - void outIndicesChanged(int from, int to) {} - - @override - void outValuesChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/bones/root_bone.dart b/lib/src/rive_core/bones/root_bone.dart deleted file mode 100644 index cda4758..0000000 --- a/lib/src/rive_core/bones/root_bone.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/generated/bones/root_bone_base.dart'; -export 'package:rive/src/generated/bones/root_bone_base.dart'; - -class RootBone extends RootBoneBase { - @override - void xChanged(double from, double to) { - markTransformDirty(); - } - - @override - void yChanged(double from, double to) { - markTransformDirty(); - } -} diff --git a/lib/src/rive_core/bones/skeletal_component.dart b/lib/src/rive_core/bones/skeletal_component.dart deleted file mode 100644 index 159005e..0000000 --- a/lib/src/rive_core/bones/skeletal_component.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:rive/src/generated/bones/skeletal_component_base.dart'; -export 'package:rive/src/generated/bones/skeletal_component_base.dart'; - -abstract class SkeletalComponent extends SkeletalComponentBase {} diff --git a/lib/src/rive_core/bones/skin.dart b/lib/src/rive_core/bones/skin.dart deleted file mode 100644 index 8177b24..0000000 --- a/lib/src/rive_core/bones/skin.dart +++ /dev/null @@ -1,178 +0,0 @@ -import 'dart:typed_data'; - -import 'package:rive/src/generated/bones/skin_base.dart'; -import 'package:rive/src/rive_core/bones/bone.dart'; -import 'package:rive/src/rive_core/bones/skinnable.dart'; -import 'package:rive/src/rive_core/bones/tendon.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/vertex.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/bones/skin_base.dart'; - -/// Represents a skin deformation of either a Path or an Image Mesh connected to -/// a set of bones. -class Skin extends SkinBase { - final List _tendons = []; - List get tendons => _tendons; - Float32List _boneTransforms = Float32List(0); - final Mat2D _worldTransform = Mat2D(); - - @override - void onDirty(int mask) { - // When the skin is dirty the deformed skinnable will need to regenerate its - // drawing commands. - if (parent is Skinnable) { - (parent as Skinnable).markSkinDirty(); - } - } - - @override - void update(int dirt) { - // Any dirt here indicates that the transforms needs to be rebuilt. This - // should only be worldTransform from the bones (recursively passed down) or - // ComponentDirt.path from the PointsPath (set explicitly). - var size = (_tendons.length + 1) * 6; - - if (_boneTransforms.length != size) { - _boneTransforms = Float32List(size); - _boneTransforms[0] = 1; - _boneTransforms[1] = 0; - _boneTransforms[2] = 0; - _boneTransforms[3] = 1; - _boneTransforms[4] = 0; - _boneTransforms[5] = 0; - } - - var temp = Mat2D(); - var bidx = 6; - for (final tendon in _tendons) { - if (tendon.bone == null) { - continue; - } - var boneWorld = tendon.bone!.worldTransform; - var wt = Mat2D.multiply(temp, boneWorld, tendon.inverseBind); - _boneTransforms[bidx++] = wt[0]; - _boneTransforms[bidx++] = wt[1]; - _boneTransforms[bidx++] = wt[2]; - _boneTransforms[bidx++] = wt[3]; - _boneTransforms[bidx++] = wt[4]; - _boneTransforms[bidx++] = wt[5]; - } - } - - void deform(List vertices) { - for (final vertex in vertices) { - vertex.deform(_worldTransform, _boneTransforms); - } - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - if (parent is Skinnable) { - (parent as Skinnable).addSkin(this); - parent!.markRebuildDependencies(); - } - _worldTransform[0] = xx; - _worldTransform[1] = xy; - _worldTransform[2] = yx; - _worldTransform[3] = yy; - _worldTransform[4] = tx; - _worldTransform[5] = ty; - } - - @override - void onRemoved() { - if (parent is Skinnable) { - (parent as Skinnable).removeSkin(this); - parent!.markRebuildDependencies(); - } - super.onRemoved(); - } - - @override - void buildDependencies() { - super.buildDependencies(); - // A skin depends on all its bones. N.B. that we don't depend on the parent - // skinnable. The skinnable depends on us. - for (final tendon in _tendons) { - var bone = tendon.bone; - if (bone == null) { - continue; - } - bone.addDependent(this); - if (bone is Bone) { - for (final childConstraint in bone.peerConstraints) { - childConstraint.constrainedComponent?.addDependent(this); - } - } - } - } - - @override - void childAdded(Component child) { - super.childAdded(child); - switch (child.coreType) { - case TendonBase.typeKey: - _tendons.add(child as Tendon); - // Add dirt to recompute stored _boneTransforms - addDirt(ComponentDirt.worldTransform); - markRebuildDependencies(); - if (parent is Skinnable) { - parent!.markRebuildDependencies(); - } - break; - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - switch (child.coreType) { - case TendonBase.typeKey: - _tendons.remove(child as Tendon); - if (_tendons.isEmpty) { - remove(); - } else { - // Add dirt to recompute stored _boneTransforms - addDirt(ComponentDirt.worldTransform); - markRebuildDependencies(); - } - parent?.markRebuildDependencies(); - - break; - } - } - - @override - void txChanged(double from, double to) { - _worldTransform[4] = to; - } - - @override - void tyChanged(double from, double to) { - _worldTransform[5] = to; - } - - @override - void xxChanged(double from, double to) { - _worldTransform[0] = to; - } - - @override - void xyChanged(double from, double to) { - _worldTransform[1] = to; - } - - @override - void yxChanged(double from, double to) { - _worldTransform[2] = to; - } - - @override - void yyChanged(double from, double to) { - _worldTransform[3] = to; - } -} diff --git a/lib/src/rive_core/bones/skinnable.dart b/lib/src/rive_core/bones/skinnable.dart deleted file mode 100644 index 67487a6..0000000 --- a/lib/src/rive_core/bones/skinnable.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:rive/src/rive_core/bones/skin.dart'; -import 'package:rive/src/rive_core/component.dart'; - -import 'package:rive/src/rive_core/shapes/vertex.dart'; - -/// An abstraction to give a common interface to any container component that -/// can contain a skin to bind bones to. -abstract class Skinnable { - // _skin is null when this object isn't connected to bones. - Skin? _skin; - Skin? get skin => _skin; - - void appendChild(Component child); - - // ignore: use_setters_to_change_properties - void addSkin(Skin skin) { - // Notify old skin/maybe support multiple skins in the future? - _skin = skin; - - markSkinDirty(); - } - - void removeSkin(Skin skin) { - if (_skin == skin) { - _skin = null; - - markSkinDirty(); - } - } - - void markSkinDirty(); -} - -abstract class SkinnableProvider { - Skinnable? get skinnable; -} diff --git a/lib/src/rive_core/bones/tendon.dart b/lib/src/rive_core/bones/tendon.dart deleted file mode 100644 index a4f9de5..0000000 --- a/lib/src/rive_core/bones/tendon.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:rive/src/generated/bones/tendon_base.dart'; -import 'package:rive/src/rive_core/bones/skeletal_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/bones/tendon_base.dart'; - -class Tendon extends TendonBase { - final Mat2D _bind = Mat2D(); - Mat2D? _inverseBind; - SkeletalComponent? _bone; - SkeletalComponent? get bone => _bone; - - Mat2D get inverseBind { - if (_inverseBind == null) { - _inverseBind = Mat2D(); - Mat2D.invert(_inverseBind!, _bind); - } - return _inverseBind!; - } - - @override - void boneIdChanged(int from, int to) { - // This never happens, or at least it should only happen prior to an - // onAddedDirty call. - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - _bone = context.resolve(boneId); - - _bind[0] = xx; - _bind[1] = xy; - _bind[2] = yx; - _bind[3] = yy; - _bind[4] = tx; - _bind[5] = ty; - } - - @override - void update(int dirt) {} - - @override - void txChanged(double from, double to) { - _bind[4] = to; - _inverseBind = null; - } - - @override - void tyChanged(double from, double to) { - _bind[5] = to; - _inverseBind = null; - } - - @override - void xxChanged(double from, double to) { - _bind[0] = to; - _inverseBind = null; - } - - @override - void xyChanged(double from, double to) { - _bind[1] = to; - _inverseBind = null; - } - - @override - void yxChanged(double from, double to) { - _bind[2] = to; - _inverseBind = null; - } - - @override - void yyChanged(double from, double to) { - _bind[3] = to; - _inverseBind = null; - } -} diff --git a/lib/src/rive_core/bones/weight.dart b/lib/src/rive_core/bones/weight.dart deleted file mode 100644 index 09cfad9..0000000 --- a/lib/src/rive_core/bones/weight.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'dart:typed_data'; - -import 'package:rive/src/generated/bones/weight_base.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/bones/weight_base.dart'; - -class Weight extends WeightBase { - final Vec2D translation = Vec2D(); - - @override - void indicesChanged(int from, int to) {} - - @override - void update(int dirt) { - // Intentionally empty. Weights don't update. - } - - @override - void valuesChanged(int from, int to) {} - - static void deform(double x, double y, int indices, int weights, Mat2D world, - Float32List boneTransforms, Vec2D result) { - double xx = 0, xy = 0, yx = 0, yy = 0, tx = 0, ty = 0; - var rx = world[0] * x + world[2] * y + world[4]; - var ry = world[1] * x + world[3] * y + world[5]; - for (int i = 0; i < 4; i++) { - var weight = encodedWeightValue(i, weights); - if (weight == 0) { - continue; - } - - double normalizedWeight = weight / 255; - var index = encodedWeightValue(i, indices); - var startBoneTransformIndex = index * 6; - xx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - xy += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - yx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - yy += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - tx += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - ty += boneTransforms[startBoneTransformIndex++] * normalizedWeight; - } - result.x = xx * rx + yx * ry + tx; - result.y = xy * rx + yy * ry + ty; - } - - static int encodedWeightValue(int index, int data) { - return (data >> (index * 8)) & 0xFF; - } -} diff --git a/lib/src/rive_core/bones/weighted_vertex.dart b/lib/src/rive_core/bones/weighted_vertex.dart deleted file mode 100644 index 315a86c..0000000 --- a/lib/src/rive_core/bones/weighted_vertex.dart +++ /dev/null @@ -1,158 +0,0 @@ -/// Helper to abstract changing weighted values on a vertex. -abstract class WeightedVertex { - int get weights; - int get weightIndices; - set weights(int value); - set weightIndices(int value); - - /// Set the weight of this vertex for a specific tendon. - void setWeight(int tendonIndex, int tendonCount, double weight) { - int tendonWeightIndex = - _setTendonWeight(tendonIndex, (weight.clamp(0, 1) * 255).round()); - - // re-normalize the list such that only bones with value are at the - // start and they sum to 100%, if any need to change make sure to give - // priority (not change) tendonIndex which we just tried to set. - - var tendonWeights = _tendonWeights; - int totalWeight = tendonWeights.fold( - 0, (value, tendonWeight) => value + tendonWeight.weight); - var vertexTendons = - tendonWeights.where((tendonWeight) => tendonWeight.tendon != 0); - - const maxWeight = 255; - - var remainder = maxWeight - totalWeight; - if (vertexTendons.length == 1) { - // User is specifically setting a single tendon to a value, just pick - // the next one up (modulate by the total number of tendons). - var patchTendonIndex = (tendonIndex + 1) % tendonCount; - _setTendonWeight( - patchTendonIndex, tendonCount == 1 ? maxWeight : remainder); - } else { - var distributeTendons = - vertexTendons.where((tendon) => tendon.index != tendonWeightIndex); - for (final patchTendon in distributeTendons) { - var patchedWeight = patchTendon.weight + remainder; - if (patchedWeight < 0) { - remainder = patchedWeight; - patchedWeight = 0; - } else if (patchedWeight > 255) { - remainder = patchedWeight - 255; - patchedWeight = 255; - } else { - remainder = 0; - } - _rawSetWeight(patchTendon.index, patchedWeight); - patchTendon.weight = patchedWeight; - } - } - _sortWeights(); - } - - void _sortWeights() { - var tendonWeights = _tendonWeights; - // Sort weights such that tendons with value show up first and any with no - // value (0 weight) are cleared to the 0 (no) tendon. - tendonWeights.sort((a, b) => b.weight.compareTo(a.weight)); - for (int i = 0; i < tendonWeights.length; i++) { - final tw = tendonWeights[i]; - _setTendonIndex(i, tw.weight == 0 ? 0 : tw.tendon); - _rawSetWeight(i, tw.weight); - } - } - - List<_WeightHelper> get _tendonWeights => [ - _WeightHelper(0, weightIndices & 0xFF, _getRawWeight(0)), - _WeightHelper(1, (weightIndices >> 8) & 0xFF, _getRawWeight(1)), - _WeightHelper(2, (weightIndices >> 16) & 0xFF, _getRawWeight(2)), - _WeightHelper(3, (weightIndices >> 24) & 0xFF, _getRawWeight(3)) - ]; - - int _setTendonWeight(int tendonIndex, int weight) { - var indices = weightIndices; - var bonesIndices = [ - indices & 0xFF, - (indices >> 8) & 0xFF, - (indices >> 16) & 0xFF, - (indices >> 24) & 0xFF, - ]; - - int setWeightIndex = -1; - for (int i = 0; i < 4; i++) { - if (bonesIndices[i] == tendonIndex + 1) { - _rawSetWeight(i, weight); - setWeightIndex = i; - break; - } - } - - // This bone wasn't weighted for this vertex, go find the bone with the - // least weight (or a 0 bone) and use it. - if (setWeightIndex == -1) { - int lowestWeight = double.maxFinite.toInt(); - for (int i = 0; i < 4; i++) { - if (bonesIndices[i] == 0) { - // this isn't set to a bone yet, use it! - setWeightIndex = i; - break; - } - var weight = _getRawWeight(i); - if (weight < lowestWeight) { - setWeightIndex = i; - lowestWeight = weight; - } - } - - _setTendonIndex(setWeightIndex, tendonIndex + 1); - _rawSetWeight(setWeightIndex, weight); - } - return setWeightIndex; - } - - /// [tendonIndex] of 0 means no bound tendon, when bound to an actual tendon, - /// it should be set to the skin's tendon's index + 1. - void _setTendonIndex(int weightIndex, int tendonIndex) { - assert(weightIndex < 4 && weightIndex >= 0); - var indexValues = weightIndices; - // Clear the bits for this weight value. - indexValues &= ~(0xFF << (weightIndex * 8)); - // Set the bits for this weight value. - weightIndices = indexValues | (tendonIndex << (weightIndex * 8)); - } - - int getTendon(int weightIndex) { - assert(weightIndex < 4 && weightIndex >= 0); - return (weightIndices >> (weightIndex * 8)) & 0xFF; - } - - void _rawSetWeight(int weightIndex, int weightValue) { - assert(weightIndex < 4 && weightIndex >= 0); - var weightValues = weights; - // Clear the bits for this weight value. - weightValues &= ~(0xFF << (weightIndex * 8)); - // Set the bits for this weight value. - weights = weightValues | (weightValue << (weightIndex * 8)); - } - - int _getRawWeight(int weightIndex) => (weights >> (weightIndex * 8)) & 0xFF; - - double getWeightAtIndex(int weightIndex) => _getRawWeight(weightIndex) / 255; - - double getWeight(int tendonIndex) { - for (int i = 0; i < 4; i++) { - if (getTendon(i) == tendonIndex + 1) { - return _getRawWeight(i) / 255; - } - } - return 0; - } -} - -class _WeightHelper { - final int index; - final int tendon; - int weight; - - _WeightHelper(this.index, this.tendon, this.weight); -} diff --git a/lib/src/rive_core/bounds_provider.dart b/lib/src/rive_core/bounds_provider.dart deleted file mode 100644 index acaded2..0000000 --- a/lib/src/rive_core/bounds_provider.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'dart:ui'; - -import 'package:rive_common/math.dart'; - -// ignore: one_member_abstracts -abstract class BoundsProvider { - AABB computeBounds(Mat2D toParent); -} - -abstract class Sizable { - Size computeIntrinsicSize(Size min, Size max); - void controlSize(Size size); -} diff --git a/lib/src/rive_core/component.dart b/lib/src/rive_core/component.dart deleted file mode 100644 index 5f57567..0000000 --- a/lib/src/rive_core/component.dart +++ /dev/null @@ -1,293 +0,0 @@ -import 'package:rive/src/generated/component_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/dependency_helper.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/component_base.dart'; - -abstract class Component extends ComponentBase - implements DependencyGraphNode, Parentable { - Artboard? _artboard; - dynamic _userData; - final DependencyHelper _dependencyHelper = - DependencyHelper(); - - /// Whether this Component's update processes at all. - bool get isCollapsed => (dirt & ComponentDirt.collapsed) != 0; - - bool propagateCollapse(bool collapse) { - if (isCollapsed == collapse) { - return false; - } - if (collapse) { - dirt |= ComponentDirt.collapsed; - } else { - dirt &= ~ComponentDirt.collapsed; - } - onDirty(dirt); - _dependencyHelper.onComponentDirty(this); - return true; - } - - /// Override to true if you want some object inheriting from Component to not - /// have a parent. Most objects will validate that they have a parent during - /// the onAdded callback otherwise they are considered invalid and are culled - /// from core. - bool get canBeOrphaned => false; - - // Used during update process. - int graphOrder = 0; - int dirt = ComponentDirt.filthy; - - // This is really only for sanity and earlying out of recursive loops. - static const int maxTreeDepth = 5000; - - bool addDirt(int value, {bool recurse = false}) { - if ((dirt & value) == value) { - // Already marked. - return false; - } - - // Make sure dirt is set before calling anything that can set more dirt. - dirt |= value; - - onDirty(dirt); - _dependencyHelper.onComponentDirty(this); - - if (!recurse) { - return true; - } - - _dependencyHelper.addDirt(value, recurse: recurse); - return true; - } - - void onDirty(int mask) {} - void update(int dirt); - - Artboard? get dependencyRoot { - return _dependencyHelper.dependencyRoot; - } - - set dependencyRoot(Artboard? component) { - _dependencyHelper.dependencyRoot = component; - } - - /// The artboard this component belongs to. - - Artboard? get artboard => _artboard; - - // Note that this isn't a setter as we don't want anything externally changing - // the artboard. - @protected - @mustCallSuper - void changeArtboard(Artboard? value) { - _artboard?.removeComponent(this); - _artboard = value; - dependencyRoot = _artboard; - _artboard?.addComponent(this); - } - - /// Called whenever we're resolving the artboard, we piggy back on that - /// process to visit ancestors in the tree. This is a good opportunity to - /// check if we have an ancestor of a specific type. For example, a Path needs - /// to know which Shape it's within. - @mustCallSuper - void visitAncestor(Component ancestor) {} - - /// Find the artboard in the hierarchy. - bool resolveArtboard() { - int sanity = maxTreeDepth; - for (Component? curr = this; - curr != null && sanity > 0; - curr = curr.parent, sanity--) { - visitAncestor(curr); - if (curr is Artboard) { - if (artboard != curr) { - changeArtboard(curr); - } - return true; - } - } - changeArtboard(null); - return false; - } - - dynamic get userData => _userData; - set userData(dynamic value) { - if (value == _userData) { - return; - } - dynamic last = _userData; - _userData = value; - userDataChanged(last, value); - } - - void userDataChanged(dynamic from, dynamic to) {} - - @override - void parentIdChanged(int from, int to) { - parent = context.resolve(to); - } - - ContainerComponent? _parent; - @override - ContainerComponent? get parent => _parent; - - set parent(ContainerComponent? value) { - if (_parent == value) { - return; - } - propagateCollapse(false); - var old = _parent; - _parent = value; - parentId = value?.id ?? Core.missingId; - parentChanged(old, value); - } - - @protected - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - from?.children.remove(this); - from?.childRemoved(this); - - if (to != null) { - to.children.add(this); - - to.childAdded(this); - } - - // We need to resolve our artboard. - markRebuildDependencies(); - } - - /// Components that this component depends on. - final Set _dependsOn = {}; - - @override - Set get dependents => _dependencyHelper.dependents; - - Set get dependencies { - Set components = {}; - allDependencies(components); - return components; - } - - void allDependencies(Set dependencies) { - for (final dependency in _dependsOn) { - if (dependencies.add(dependency)) { - dependency.allDependencies(dependencies); - } - } - } - - /// Mark [dependent] as a component which must update after this. Provide - /// [via] as the Component registering the dependency when it is not - /// [dependent] itself. At edit time this allows the editor to rebuild both - /// [dependent] and [via] when [dependent] has its dependencies cleared. - bool addDependent(Component dependent, {Component? via}) { - assert(artboard == dependent.artboard, - 'Components must be in the same artboard.'); - - if (!_dependencyHelper.addDependent(dependent)) { - return false; - } - dependent._dependsOn.add(this); - - return true; - } - - bool isValidParent(Component parent) => parent is ContainerComponent; - - void markRebuildDependencies() { - if (!context.markDependenciesDirty(this)) { - // no context, or already dirty. - return; - } - - for (final dependent in dependents) { - dependent.markRebuildDependencies(); - } - } - - void clearDependencies() { - for (final parentDep in _dependsOn) { - parentDep.dependents.remove(this); - } - _dependsOn.clear(); - } - - void buildDependencies() {} - - /// Something we depend on has been removed. It's important to clear out any - /// stored references to that dependency so it can be garbage collected (if - /// necessary). - void onDependencyRemoved(Component dependent) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() { - if (parentId != Core.missingId) { - parent = context.resolve(parentId); - } - } - - /// When a component has been removed from the Core Context, we clean up any - /// dangling references left on the parent and on any other dependent - /// component. It's important for specialization of Component to respond to - /// override [onDependencyRemoved] and clean up any further stored references - /// to that component (for example the target of a Constraint). - @override - @mustCallSuper - void onRemoved() { - super.onRemoved(); - for (final parentDep in _dependsOn) { - parentDep.dependents.remove(this); - } - _dependsOn.clear(); - - for (final dependent in dependents) { - dependent.onDependencyRemoved(this); - } - dependents.clear(); - - // silently clear from the parent in order to not cause any further undo - // stack changes - if (parent != null) { - parent!.children.remove(this); - parent!.childRemoved(this); - } - - // The artboard containing this component will need its dependencies - // re-sorted. - - if (artboard != null) { - context.markDependencyOrderDirty(); - changeArtboard(null); - } - } - - @override - String toString() { - return '${super.toString()} ($id) -> $name'; - } - - @override - void nameChanged(String from, String to) { - /// Changing name doesn't really do anything. - } - - @override - bool import(ImportStack stack) { - var artboardImporter = stack.latest(ArtboardBase.typeKey); - if (artboardImporter == null) { - return false; - } - artboardImporter.addComponent(this); - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/component_dirt.dart b/lib/src/rive_core/component_dirt.dart deleted file mode 100644 index 9bf7508..0000000 --- a/lib/src/rive_core/component_dirt.dart +++ /dev/null @@ -1,62 +0,0 @@ -class ComponentDirt { - /// Means to not process the update! - static const int collapsed = 1 << 0; - - static const int dependents = 1 << 1; - - /// General flag for components are dirty (if this is up, the update cycle - /// runs). It gets automatically applied with any other dirt. - static const int components = 1 << 2; - - /// Draw order needs to be re-computed. - static const int drawOrder = 1 << 3; - - /// Draw order needs to be re-computed. - static const int naturalDrawOrder = 1 << 4; - - /// Path is dirty and needs to be rebuilt. - static const int path = 1 << 5; - - /// Text modifier coverage is dirty and needs to be rebuilt. - static const int textCoverage = 1 << 5; - - /// Interpolator is dirty. - static const int interpolator = 1 << 5; - - /// Text shape is dirty, the shaper needs to re-run. - static const int textShape = 1 << 5; - - /// Vertices have changed, re-order cached lists. - static const int vertices = 1 << 6; - - /// Used by any component that needs to recompute their local transform. - /// Usually components that have their transform dirty will also have their - /// worldTransform dirty. - static const int transform = 1 << 7; - - /// Used by any component that needs to update its world transform. - static const int worldTransform = 1 << 8; - - /// Dirt used to mark some stored paint needs to be rebuilt or that we just - /// want to trigger an update cycle so painting occurs. - static const int paint = 1 << 9; - - /// Used by the gradients track when the stops need to be re-ordered. - static const int stops = 1 << 10; - - /// Used by ClippingShape to help Shape know when to recalculate its list of - /// clipping sources. - static const int clip = 1 << 11; - - /// Set when blend modes need to be updated. - static const int blendMode = 1 << 12; - - /// Set when layout styles may need to be re-cascaded - static const int layoutStyle = 1 << 13; - - /// Used by data binds to track the value has changed. - static const int bindings = 1 << 14; - - /// All dirty. Every flag (apart from Collapsed) is set. - static const int filthy = 0xFFFE; -} diff --git a/lib/src/rive_core/component_flags.dart b/lib/src/rive_core/component_flags.dart deleted file mode 100644 index 2f67ccd..0000000 --- a/lib/src/rive_core/component_flags.dart +++ /dev/null @@ -1,16 +0,0 @@ -class ComponentFlags { - /// Whether the component should be drawn (at runtime this only used by - /// drawables and paths). - static const int hidden = 1 << 0; - - /// Whether the component was locked for editing in the editor. - static const int locked = 1 << 1; - - /// Whether this Component is disconnected from the hierarchy meaning it won't - /// receive any update cycles nor will any drawables draw. - static const int disconnected = 1 << 2; - - /// Whether this Component lets hit events pass through to components behind - /// it (used by shapes at runtine) - static const int opaque = 1 << 3; -} diff --git a/lib/src/rive_core/constraints/constraint.dart b/lib/src/rive_core/constraints/constraint.dart deleted file mode 100644 index 65c20a2..0000000 --- a/lib/src/rive_core/constraints/constraint.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:rive/src/generated/constraints/constraint_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/constraint_base.dart'; - -/// A specialized [Component] which can be parented to any [TransformComponent] -/// providing rules for how to constrain its transform space. -abstract class Constraint extends ConstraintBase { - /// Returns the [TransformComponent] which this [Constraint] is applied to. - TransformComponent? get constrainedComponent => - parent is TransformComponent ? parent as TransformComponent : null; - - @override - void strengthChanged(double from, double to) => - constrainedComponent?.markTransformDirty(); - - @override - bool validate() => super.validate() && parent is TransformComponent; - - void constrain(TransformComponent component); - - @override - void buildDependencies() { - super.buildDependencies(); - - parent!.addDependent(this); - } - - @override - void update(int dirt) {} - - void markConstraintDirty() => constrainedComponent?.markTransformDirty(); - - @override - void onDirty(int mask) => markConstraintDirty(); -} - -/// Get the parent's world transform. Takes into consideration when the parent -/// is an artboard. -Mat2D parentWorld(WorldTransformComponent component) { - var parent = component.parent; - if (parent is WorldTransformComponent) { - return parent.worldTransform; - } - return Mat2D(); -} diff --git a/lib/src/rive_core/constraints/distance_constraint.dart b/lib/src/rive_core/constraints/distance_constraint.dart deleted file mode 100644 index 77af00d..0000000 --- a/lib/src/rive_core/constraints/distance_constraint.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:rive/src/generated/constraints/distance_constraint_base.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/distance_constraint_base.dart'; - -/// [DistanceConstraint]'s logical distancing method. -enum DistanceConstraintMode { closer, further, exact } - -const _distanceEpsilon = 0.001; - -/// A constraint which transaltes its constrained component in world space to a -/// certain distance from the [target] based on [mode]. -class DistanceConstraint extends DistanceConstraintBase { - @override - void constrain(TransformComponent component) { - if (target == null || target!.isCollapsed) { - return; - } - var targetTranslation = target!.worldTranslation; - var ourTranslation = component.worldTranslation; - - var toTarget = ourTranslation - targetTranslation; - var currentDistance = toTarget.length(); - switch (mode) { - case DistanceConstraintMode.closer: - if (currentDistance < distance) { - return; - } - break; - case DistanceConstraintMode.further: - if (currentDistance > distance) { - return; - } - break; - case DistanceConstraintMode.exact: - break; - } - if (currentDistance < _distanceEpsilon) { - return; - } - - Vec2D.scale(toTarget, toTarget, 1.0 / currentDistance); - Vec2D.scale(toTarget, toTarget, distance); - - var world = component.worldTransform; - - var position = targetTranslation + toTarget; - Vec2D.lerp(position, ourTranslation, position, strength); - world[4] = position.x; - world[5] = position.y; - } - - @override - void distanceChanged(double from, double to) => markConstraintDirty(); - - @override - void modeValueChanged(int from, int to) => markConstraintDirty(); - - DistanceConstraintMode get mode => - enumAt(DistanceConstraintMode.values, modeValue); - set mode(DistanceConstraintMode value) => modeValue = value.index; -} diff --git a/lib/src/rive_core/constraints/follow_path_constraint.dart b/lib/src/rive_core/constraints/follow_path_constraint.dart deleted file mode 100644 index eda7693..0000000 --- a/lib/src/rive_core/constraints/follow_path_constraint.dart +++ /dev/null @@ -1,179 +0,0 @@ -import 'dart:math'; -import 'dart:ui' as ui; - -import 'package:rive/src/generated/constraints/follow_path_constraint_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/shapes/path.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/follow_path_constraint_base.dart'; - -/// A constraint which transforms its constrained TransformComponent to the -/// targeted path. -class FollowPathConstraint extends FollowPathConstraintBase { - final ui.Path _worldPath = ui.Path(); - - Mat2D get targetTransform { - if (target is Shape || target is Path) { - var metrics = _worldPath.computeMetrics().toList(growable: false); - if (metrics.isEmpty) { - return Mat2D(); - } - double totalLength = 0.0; - for (final metric in metrics) { - totalLength += metric.length; - } - // Normalize distance value to 0-1 since we need to support values - // <0 and >1 - // Negative values follow path in reverse direction - var actualDistance = distance % 1; - // This handles the case where distance is any whole number other than 0. - // In those cases we want actualDistance to return 1 - if (distance != 0 && actualDistance == 0) { - actualDistance = 1; - } - double distanceUnits = totalLength * actualDistance.clamp(0, 1); - var itr = metrics.iterator; - - // We already checked it wasn't empty. - itr.moveNext(); - ui.PathMetric metric; - do { - metric = itr.current; - if (distanceUnits <= metric.length) { - break; - } - - distanceUnits -= metric.length; - } while (itr.moveNext()); - - var tangent = metric.getTangentForOffset(distanceUnits); - - if (tangent == null) { - return Mat2D(); - } - - Vec2D position = - Vec2D.fromValues(tangent.position.dx, tangent.position.dy); - Mat2D transformB = Mat2D.clone(target!.worldTransform); - - if (orient) { - Mat2D.fromRotation( - transformB, atan2(tangent.vector.dy, tangent.vector.dx)); - } - final offsetPosition = offset - ? Vec2D.fromValues(constrainedComponent!.transform[4], - constrainedComponent!.transform[5]) - : Vec2D(); - transformB[4] = position.x + offsetPosition.x; - transformB[5] = position.y + offsetPosition.y; - return transformB; - } else { - return target!.worldTransform; - } - } - - @override - void constrain(TransformComponent component) { - if (target == null || target!.isCollapsed) { - return; - } - // Constrained component world transform - var transformA = component.worldTransform; - // Target transform - var transformB = Mat2D.clone(targetTransform); - if (sourceSpace == TransformSpace.local) { - var targetParentWorld = parentWorld(target!); - - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, targetParentWorld)) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - } - if (destSpace == TransformSpace.local && component.parent != null) { - var targetParentWorld = parentWorld(component); - Mat2D.multiply(transformB, targetParentWorld, transformB); - } - - Mat2D.decompose(transformA, componentsA); - Mat2D.decompose(transformB, componentsB); - - var t = strength; - var ti = 1 - t; - - // If orient is on, use the rotation value we calculated when getting the - // tanget of the path, otherwise respect constrained component's rotation - if (!orient) { - componentsB[4] = componentsA[4] % (pi * 2); - } - // Merge x/y position based on strength value - componentsB[0] = componentsA[0] * ti + componentsB[0] * t; - componentsB[1] = componentsA[1] * ti + componentsB[1] * t; - // Maintain scale & skew of constrained component - componentsB[2] = componentsA[2]; - componentsB[3] = componentsA[3]; - componentsB[5] = componentsA[5]; - - Mat2D.compose(component.worldTransform, componentsB); - } - - @override - void buildDependencies() { - if (target is Shape) { - var shape = target as Shape; - // Follow path should update after the target's path composer - shape.pathComposer.addDependent(this); - } else if (target is Path) { - var path = target as Path; - path.addDependent(this); - } - - if (constrainedComponent != null) { - // The constrained component should update after follow path - addDependent(constrainedComponent!, via: this); - } - } - - void _resetWorldPath(Set paths) { - _worldPath.reset(); - for (final path in paths) { - _worldPath.addPath(path.uiPath, ui.Offset.zero, - matrix4: path.pathTransform.mat4); - } - } - - @override - void update(int dirt) { - final _target = target; - if (_target is Shape) { - _resetWorldPath(_target.paths); - } else if (_target is Path) { - _resetWorldPath({_target}); - } - } - - @override - Component? get targetDependencyParent => target is Shape - ? (target as Shape) - : target is Path - ? (target as Path) - : null; - - @override - void distanceChanged(double from, double to) => markConstraintDirty(); - - @override - void orientChanged(bool from, bool to) => markConstraintDirty(); - - @override - void offsetChanged(bool from, bool to) => markConstraintDirty(); - - @override - bool validate() => - super.validate() && (target == null || target is Shape || target is Path); -} diff --git a/lib/src/rive_core/constraints/ik_constraint.dart b/lib/src/rive_core/constraints/ik_constraint.dart deleted file mode 100644 index 2cacc48..0000000 --- a/lib/src/rive_core/constraints/ik_constraint.dart +++ /dev/null @@ -1,306 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/generated/constraints/ik_constraint_base.dart'; -import 'package:rive/src/rive_core/bones/bone.dart'; -import 'package:rive/src/rive_core/bones/root_bone.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/ik_constraint_base.dart'; - -/// A constraint which rotates its constrained bone and the parentBoneCount -/// bones above it in order to move the tip of the constrained bone towards the -/// target. -class IKConstraint extends IKConstraintBase { - @override - void invertDirectionChanged(bool from, bool to) => markConstraintDirty(); - - @override - void parentBoneCountChanged(int from, int to) {} - - @override - void markConstraintDirty() { - super.markConstraintDirty(); - - // We automatically propagate dirt to the parent constrained bone, but we - // also need to make sure the other bones we influence above it rebuild - // their transforms. - for (int i = 0; i < _fkChain.length - 1; i++) { - _fkChain[i].bone.markTransformDirty(); - } - } - - /// The list of bones in FK order. - final List<_BoneChainLink> _fkChain = []; - Iterable<_BoneChainLink> get fkChain => _fkChain; - - @override - void onAdded() { - super.onAdded(); - _buildFKChain(); - } - - @override - void onRemoved() { - _clearFKChain(); - - super.onRemoved(); - } - - void _clearFKChain() { - for (final link in _fkChain) { - link.bone.markRebuildDependencies(); - link.bone.removePeerConstraint(this); - } - _fkChain.clear(); - } - - bool _buildFKChain() { - var nextFKChain = <_BoneChainLink>[]; - var boneCount = parentBoneCount; - var bone = parent as Bone; - var bones = [bone]; - var hitRootBone = bone is RootBone; - // Get the reverse FK chain of bones (from tip up). - while (!hitRootBone && bone.parent is Bone && boneCount > 0) { - boneCount--; - bone = bone.parent as Bone; - bones.add(bone); - hitRootBone = bone is RootBone; - } - // Now put them in FK order (top to bottom). - for (final bone in bones.reversed) { - nextFKChain.add(_BoneChainLink( - index: nextFKChain.length, - bone: bone, - )); - } - - _clearFKChain(); - - _fkChain.addAll(nextFKChain); - for (final link in _fkChain) { - link.bone.markRebuildDependencies(); - link.bone.addPeerConstraint(this); - } - markRebuildDependencies(); - return true; - } - - @override - void buildDependencies() { - super.buildDependencies(); - - // Make sure all of the first level children of each bone depend on the - // tip (constrainedComponent). - var tip = parent as Bone; - - var bones = _fkChain.reversed.map((link) => link.bone).toSet(); - for (final bone in bones.skip(1)) { - for (final child in bone.children) { - if (child is TransformComponent && !bones.contains(child)) { - tip.addDependent(child, via: this); - } - } - } - } - - @override - bool validate() => super.validate() && parent is Bone; - - @override - void constrain(TransformComponent component) { - if (target == null || target!.isCollapsed) { - return; - } - - var worldTargetTranslation = target!.worldTranslation; - // Decompose the chain. - for (final item in _fkChain) { - var bone = item.bone; - Mat2D parentWorldTransform = parentWorld(bone); - - Mat2D.invert(item.parentWorldInverse, parentWorldTransform); - - var boneTransform = bone.transform; - Mat2D.multiply( - boneTransform, item.parentWorldInverse, bone.worldTransform); - Mat2D.decompose(boneTransform, item.transformComponents); - } - - switch (_fkChain.length) { - case 1: - solve1(_fkChain.first, worldTargetTranslation); - break; - case 2: - solve2(_fkChain[0], _fkChain[1], worldTargetTranslation); - break; - default: - { - var last = _fkChain.length - 1; - var tip = _fkChain[last]; - for (int i = 0; i < last; i++) { - var item = _fkChain[i]; - solve2(item, tip, worldTargetTranslation); - for (int j = item.index + 1, end = _fkChain.length - 1; - j < end; - j++) { - var fk = _fkChain[j]; - Mat2D.invert(fk.parentWorldInverse, parentWorld(fk.bone)); - } - } - break; - } - } - - // At the end, mix the FK angle with the IK angle by strength - if (strength != 1.0) { - for (final fk in _fkChain) { - var fromAngle = fk.transformComponents.rotation % (pi * 2); - var toAngle = fk.angle % (pi * 2); - var diff = toAngle - fromAngle; - if (diff > pi) { - diff -= pi * 2; - } else if (diff < -pi) { - diff += pi * 2; - } - var angle = fromAngle + diff * strength; - _constrainRotation(fk, angle); - } - } - } - - void solve1(_BoneChainLink fk1, Vec2D worldTargetTranslation) { - Mat2D iworld = fk1.parentWorldInverse; - var pA = fk1.bone.worldTranslation; - var pBT = Vec2D.clone(worldTargetTranslation); - - // To target in worldspace - var toTarget = pBT - pA; - - // Note this is directional, hence not transformMat2d - Vec2D toTargetLocal = Vec2D.transformMat2(Vec2D(), toTarget, iworld); - var r = toTargetLocal.atan2(); - - _constrainRotation(fk1, r); - fk1.angle = r; - } - - void solve2( - _BoneChainLink fk1, _BoneChainLink fk2, Vec2D worldTargetTranslation) { - Bone b1 = fk1.bone; - Bone b2 = fk2.bone; - var firstChild = _fkChain[fk1.index + 1]; - - var iworld = fk1.parentWorldInverse; - - var pA = b1.worldTranslation; - var pC = firstChild.bone.worldTranslation; - var pB = b2.tipWorldTranslation; - var pBT = Vec2D.clone(worldTargetTranslation); - - pA.apply(iworld); - pC.apply(iworld); - pB.apply(iworld); - pBT.apply(iworld); - - // http://mathworld.wolfram.com/LawofCosines.html - - var av = pB - pC; - var a = av.length(); - - var bv = pC - pA; - var b = bv.length(); - - var cv = pBT - pA; - var c = cv.length(); - if (b == 0 || c == 0) { - // Cannot solve, would cause divide by zero. Usually means one of the two - // bones has a 0/0 scale. - return; - } - var A = acos(max(-1, min(1, (-a * a + b * b + c * c) / (2 * b * c)))); - var C = acos(max(-1, min(1, (a * a + b * b - c * c) / (2 * a * b)))); - final cvAngle = cv.atan2(); - - double r1, r2; - if (b2.parent != b1) { - var secondChild = _fkChain[fk1.index + 2]; - - var secondChildWorldInverse = secondChild.parentWorldInverse; - - pC = firstChild.bone.worldTranslation; - pB = b2.tipWorldTranslation; - - var avec = pB - pC; - - var avLocal = Vec2D.transformMat2(Vec2D(), avec, secondChildWorldInverse); - var angleCorrection = -avLocal.atan2(); - - if (invertDirection) { - r1 = cvAngle - A; - r2 = -C + pi + angleCorrection; - } else { - r1 = A + cvAngle; - r2 = C - pi + angleCorrection; - } - } else if (invertDirection) { - r1 = cvAngle - A; - r2 = -C + pi; - } else { - r1 = A + cvAngle; - r2 = C - pi; - } - _constrainRotation(fk1, r1); - _constrainRotation(firstChild, r2); - if (firstChild != fk2) { - var bone = fk2.bone; - Mat2D.multiply(bone.worldTransform, parentWorld(bone), bone.transform); - } - - // Simple storage, need this for interpolation. - fk1.angle = r1; - firstChild.angle = r2; - } -} - -class _BoneChainLink { - final int index; - final Bone bone; - double angle = 0; - TransformComponents transformComponents = TransformComponents(); - Mat2D parentWorldInverse = Mat2D(); - - _BoneChainLink({ - required this.index, - required this.bone, - }); -} - -void _constrainRotation(_BoneChainLink link, double rotation) { - var bone = link.bone; - Mat2D parentWorldTransform = parentWorld(bone); - var boneTransform = bone.transform; - if (rotation == 0) { - Mat2D.setIdentity(boneTransform); - } else { - Mat2D.fromRotation(boneTransform, rotation); - } - var c = link.transformComponents; - boneTransform[4] = c.x; - boneTransform[5] = c.y; - var scaleX = c.scaleX; - var scaleY = c.scaleY; - boneTransform[0] *= scaleX; - boneTransform[1] *= scaleX; - boneTransform[2] *= scaleY; - boneTransform[3] *= scaleY; - - var skew = c.skew; - if (skew != 0) { - boneTransform[2] = boneTransform[0] * skew + boneTransform[2]; - boneTransform[3] = boneTransform[1] * skew + boneTransform[3]; - } - Mat2D.multiply(bone.worldTransform, parentWorldTransform, boneTransform); -} diff --git a/lib/src/rive_core/constraints/rotation_constraint.dart b/lib/src/rive_core/constraints/rotation_constraint.dart deleted file mode 100644 index a3df93f..0000000 --- a/lib/src/rive_core/constraints/rotation_constraint.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/generated/constraints/rotation_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/rotation_constraint_base.dart'; - -/// A constraint copies the rotation from the target component to the -/// constrained component in world or local space and applies copy/min/max -/// rules. -class RotationConstraint extends RotationConstraintBase { - @override - void constrain(TransformComponent component) { - if (target?.isCollapsed ?? false) { - return; - } - var transformA = component.worldTransform; - var transformB = Mat2D(); - Mat2D.decompose(transformA, componentsA); - if (target == null) { - Mat2D.copy(transformB, transformA); - TransformComponents.copy(componentsB, componentsA); - } else { - Mat2D.copy(transformB, target!.worldTransform); - if (sourceSpace == TransformSpace.local) { - var inverse = Mat2D(); - - if (!Mat2D.invert(inverse, parentWorld(target!))) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - } - - Mat2D.decompose(transformB, componentsB); - - if (!doesCopy) { - componentsB.rotation = - destSpace == TransformSpace.local ? 0 : componentsA.rotation; - } else { - componentsB.rotation = componentsB.rotation * copyFactor; - if (offset) { - componentsB.rotation = componentsB.rotation + component.rotation; - } - } - - if (destSpace == TransformSpace.local) { - // Destination space is in parent transform coordinates. Recompose the - // parent local transform and get it in world, then decompose the world - // for interpolation. - - Mat2D.compose(transformB, componentsB); - var grandParentWorld = parentWorld(component); - Mat2D.multiply(transformB, grandParentWorld, transformB); - Mat2D.decompose(transformB, componentsB); - } - } - bool clampLocal = minMaxSpace == TransformSpace.local; - if (clampLocal) { - // Apply min max in local space, so transform to local coordinates first. - Mat2D.compose(transformB, componentsB); - Mat2D inverse = Mat2D(); - if (!Mat2D.invert(inverse, parentWorld(component))) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - Mat2D.decompose(transformB, componentsB); - } - if (this.max && componentsB.rotation > maxValue) { - componentsB.rotation = maxValue; - } - if (this.min && componentsB.rotation < minValue) { - componentsB.rotation = minValue; - } - if (clampLocal) { - // Transform back to world. - Mat2D.compose(transformB, componentsB); - Mat2D.multiply(transformB, parentWorld(component), transformB); - Mat2D.decompose(transformB, componentsB); - } - - var pi2 = pi * 2; - var angleA = componentsA.rotation % pi2; - var angleB = componentsB.rotation % pi2; - var diff = angleB - angleA; - - if (diff > pi) { - diff -= pi2; - } else if (diff < -pi) { - diff += pi2; - } - - componentsB.rotation = componentsA.rotation + diff * strength; - componentsB.x = componentsA.x; - componentsB.y = componentsA.y; - componentsB.scaleX = componentsA.scaleX; - componentsB.scaleY = componentsA.scaleY; - componentsB.skew = componentsA.skew; - - Mat2D.compose(component.worldTransform, componentsB); - } -} diff --git a/lib/src/rive_core/constraints/scale_constraint.dart b/lib/src/rive_core/constraints/scale_constraint.dart deleted file mode 100644 index 6d6120b..0000000 --- a/lib/src/rive_core/constraints/scale_constraint.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:rive/src/generated/constraints/scale_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/scale_constraint_base.dart'; - -/// A constraint copies the scale from the target component to the -/// constrained component in world or local space and applies copy/min/max -/// rules. -class ScaleConstraint extends ScaleConstraintBase { - @override - void constrain(TransformComponent component) { - if (target?.isCollapsed ?? false) { - return; - } - var transformA = component.worldTransform; - var transformB = Mat2D(); - Mat2D.decompose(transformA, componentsA); - if (target == null) { - Mat2D.copy(transformB, transformA); - TransformComponents.copy(componentsB, componentsA); - } else { - Mat2D.copy(transformB, target!.worldTransform); - if (sourceSpace == TransformSpace.local) { - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, parentWorld(target!))) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - } - Mat2D.decompose(transformB, componentsB); - - if (!doesCopy) { - componentsB.scaleX = - destSpace == TransformSpace.local ? 1 : componentsA.scaleX; - } else { - componentsB.scaleX = componentsB.scaleX * copyFactor; - if (offset) { - componentsB.scaleX = componentsB.scaleX * component.scaleX; - } - } - - if (!doesCopyY) { - componentsB.scaleY = - destSpace == TransformSpace.local ? 1 : componentsA.scaleY; - } else { - componentsB.scaleY = componentsB.scaleY * copyFactorY; - if (offset) { - componentsB.scaleY = componentsB.scaleY * component.scaleY; - } - } - - if (destSpace == TransformSpace.local) { - // Destination space is in parent transform coordinates. Recompose the - // parent local transform and get it in world, then decompose the world - // for interpolation. - - Mat2D.compose(transformB, componentsB); - Mat2D.multiply(transformB, parentWorld(component), transformB); - Mat2D.decompose(transformB, componentsB); - } - } - - bool clamplocal = minMaxSpace == TransformSpace.local; - if (clamplocal) { - // Apply min max in local space, so transform to local coordinates first. - Mat2D.compose(transformB, componentsB); - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, parentWorld(component))) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - Mat2D.decompose(transformB, componentsB); - } - if (max && componentsB.scaleX > maxValue) { - componentsB.scaleX = maxValue; - } - if (min && componentsB.scaleX < minValue) { - componentsB.scaleX = minValue; - } - if (maxY && componentsB.scaleY > maxValueY) { - componentsB.scaleY = maxValueY; - } - if (minY && componentsB.scaleY < minValueY) { - componentsB.scaleY = minValueY; - } - if (clamplocal) { - // Transform back to world. - Mat2D.compose(transformB, componentsB); - Mat2D.multiply(transformB, parentWorld(component), transformB); - Mat2D.decompose(transformB, componentsB); - } - - var ti = 1 - strength; - - componentsB.rotation = componentsA.rotation; - componentsB.x = componentsA.x; - componentsB.y = componentsA.y; - componentsB.scaleX = - componentsA.scaleX * ti + componentsB.scaleX * strength; - componentsB.scaleY = - componentsA.scaleY * ti + componentsB.scaleY * strength; - componentsB.skew = componentsA.skew; - - Mat2D.compose(component.worldTransform, componentsB); - } -} diff --git a/lib/src/rive_core/constraints/targeted_constraint.dart b/lib/src/rive_core/constraints/targeted_constraint.dart deleted file mode 100644 index eef0f85..0000000 --- a/lib/src/rive_core/constraints/targeted_constraint.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; - -export 'package:rive/src/generated/constraints/targeted_constraint_base.dart'; - -/// A [Constraint] which uses an external target to help influence the computed -/// transform. -abstract class TargetedConstraint extends TargetedConstraintBase { - WorldTransformComponent? _target; - WorldTransformComponent? get target => _target; - set target(WorldTransformComponent? value) { - if (_target == value) { - return; - } - - _target = value; - } - - @override - void targetIdChanged(int from, int to) => target = context.resolve(to); - - /// The dependency parent this constraint will be dependent on. We allow - /// overriding this as some constraints may want to use a helper component - /// (like the ShapeComposer of the Shape). - Component? get targetDependencyParent => _target; - - @override - void buildDependencies() { - super.buildDependencies(); - // Targeted constraints must have their constrainedComponent update after - // the target. - if (constrainedComponent != null) { - targetDependencyParent?.addDependent(constrainedComponent!, via: this); - } - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - target = context.resolve(targetId); - } -} diff --git a/lib/src/rive_core/constraints/transform_component_constraint.dart b/lib/src/rive_core/constraints/transform_component_constraint.dart deleted file mode 100644 index c9cb48b..0000000 --- a/lib/src/rive_core/constraints/transform_component_constraint.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:rive/src/generated/constraints/transform_component_constraint_base.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -export 'package:rive/src/generated/constraints/transform_component_constraint_base.dart'; - -abstract class TransformComponentConstraint - extends TransformComponentConstraintBase { - TransformSpace get minMaxSpace => TransformSpace.values[minMaxSpaceValue]; - set minMaxSpace(TransformSpace value) => minMaxSpaceValue = value.index; - - @override - void minMaxSpaceValueChanged(int from, int to) => markConstraintDirty(); - - @override - void minValueChanged(double from, double to) => markConstraintDirty(); - - @override - void maxValueChanged(double from, double to) => markConstraintDirty(); - - @override - void copyFactorChanged(double from, double to) => markConstraintDirty(); - - @override - void doesCopyChanged(bool from, bool to) => markConstraintDirty(); - - @override - void maxChanged(bool from, bool to) => markConstraintDirty(); - - @override - void minChanged(bool from, bool to) => markConstraintDirty(); - - @override - void offsetChanged(bool from, bool to) => markConstraintDirty(); -} diff --git a/lib/src/rive_core/constraints/transform_component_constraint_y.dart b/lib/src/rive_core/constraints/transform_component_constraint_y.dart deleted file mode 100644 index d7ddfba..0000000 --- a/lib/src/rive_core/constraints/transform_component_constraint_y.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/constraints/transform_component_constraint_y_base.dart'; -export 'package:rive/src/generated/constraints/transform_component_constraint_y_base.dart'; - -abstract class TransformComponentConstraintY - extends TransformComponentConstraintYBase { - @override - void minValueYChanged(double from, double to) => markConstraintDirty(); - - @override - void maxValueYChanged(double from, double to) => markConstraintDirty(); - - @override - void copyFactorYChanged(double from, double to) => markConstraintDirty(); - - @override - void doesCopyYChanged(bool from, bool to) => markConstraintDirty(); - - @override - void maxYChanged(bool from, bool to) => markConstraintDirty(); - - @override - void minYChanged(bool from, bool to) => markConstraintDirty(); -} diff --git a/lib/src/rive_core/constraints/transform_constraint.dart b/lib/src/rive_core/constraints/transform_constraint.dart deleted file mode 100644 index bea7cc1..0000000 --- a/lib/src/rive_core/constraints/transform_constraint.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/generated/constraints/transform_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/transform_constraint_base.dart'; - -/// A constraint copies the transform from the target component to the -/// constrained component in world or local space. -class TransformConstraint extends TransformConstraintBase { - Mat2D get targetTransform { - var bounds = target!.constraintBounds; - var local = Mat2D.fromTranslation( - Vec2D.fromValues( - bounds.left + bounds.width * originX, - bounds.top + bounds.height * originY, - ), - ); - return Mat2D.multiply(Mat2D(), target!.worldTransform, local); - } - - @override - void constrain(TransformComponent component) { - if (target == null || target!.isCollapsed) { - return; - } - var transformA = component.worldTransform; - var transformB = Mat2D.clone(targetTransform); - if (sourceSpace == TransformSpace.local) { - var targetParentWorld = parentWorld(target!); - - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, targetParentWorld)) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - } - if (destSpace == TransformSpace.local && component.parent != null) { - var targetParentWorld = parentWorld(component); - Mat2D.multiply(transformB, targetParentWorld, transformB); - } - - Mat2D.decompose(transformA, componentsA); - Mat2D.decompose(transformB, componentsB); - - var angleA = componentsA[4] % (pi * 2); - var angleB = componentsB[4] % (pi * 2); - var diff = angleB - angleA; - if (diff > pi) { - diff -= pi * 2; - } else if (diff < -pi) { - diff += pi * 2; - } - - var t = strength; - var ti = 1 - t; - - componentsB[4] = angleA + diff * t; - componentsB[0] = componentsA[0] * ti + componentsB[0] * t; - componentsB[1] = componentsA[1] * ti + componentsB[1] * t; - componentsB[2] = componentsA[2] * ti + componentsB[2] * t; - componentsB[3] = componentsA[3] * ti + componentsB[3] * t; - componentsB[5] = componentsA[5] * ti + componentsB[5] * t; - - Mat2D.compose(component.worldTransform, componentsB); - } - - @override - void originXChanged(double from, double to) => - constrainedComponent?.markTransformDirty(); - - @override - void originYChanged(double from, double to) => - constrainedComponent?.markTransformDirty(); -} diff --git a/lib/src/rive_core/constraints/transform_space_constraint.dart b/lib/src/rive_core/constraints/transform_space_constraint.dart deleted file mode 100644 index 2143ef5..0000000 --- a/lib/src/rive_core/constraints/transform_space_constraint.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/transform_space_constraint_base.dart'; - -abstract class TransformSpaceConstraint extends TransformSpaceConstraintBase { - final TransformComponents componentsA = TransformComponents(); - final TransformComponents componentsB = TransformComponents(); - - TransformSpace get destSpace => enumAt(TransformSpace.values, destSpaceValue); - set destSpace(TransformSpace value) => destSpaceValue = value.index; - - TransformSpace get sourceSpace => TransformSpace.values[sourceSpaceValue]; - set sourceSpace(TransformSpace value) => sourceSpaceValue = value.index; - - @override - void destSpaceValueChanged(int from, int to) => markConstraintDirty(); - - @override - void sourceSpaceValueChanged(int from, int to) => markConstraintDirty(); -} diff --git a/lib/src/rive_core/constraints/translation_constraint.dart b/lib/src/rive_core/constraints/translation_constraint.dart deleted file mode 100644 index 1db0322..0000000 --- a/lib/src/rive_core/constraints/translation_constraint.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'package:rive/src/generated/constraints/translation_constraint_base.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/transform_space.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/constraints/translation_constraint_base.dart'; - -/// A constraint copies the translation from the target component to the -/// constrained component in world or local space and applies copy/min/max -/// rules. -class TranslationConstraint extends TranslationConstraintBase { - @override - void constrain(TransformComponent component) { - if (target?.isCollapsed ?? false) { - return; - } - var transformA = component.worldTransform; - var translationA = Vec2D.fromValues(transformA[4], transformA[5]); - var translationB = Vec2D(); - if (target == null) { - Vec2D.copy(translationB, translationA); - } else { - var transformB = Mat2D.clone(target!.worldTransform); - if (sourceSpace == TransformSpace.local) { - var inverse = Mat2D(); - if (!Mat2D.invert(inverse, parentWorld(target!))) { - return; - } - Mat2D.multiply(transformB, inverse, transformB); - } - translationB.x = transformB[4]; - translationB.y = transformB[5]; - - if (!doesCopy) { - translationB.x = destSpace == TransformSpace.local ? 0 : translationA.x; - } else { - translationB.x *= copyFactor; - if (offset) { - translationB.x += component.x; - } - } - - if (!doesCopyY) { - translationB.y = destSpace == TransformSpace.local ? 0 : translationA.y; - } else { - translationB.y *= copyFactorY; - - if (offset) { - translationB.y += component.y; - } - } - - if (destSpace == TransformSpace.local) { - // Destination space is in parent transform coordinates. - translationB.apply(parentWorld(component)); - } - } - - bool clampLocal = minMaxSpace == TransformSpace.local; - if (clampLocal) { - // Apply min max in local space, so transform to local coordinates first. - var invert = Mat2D(); - if (!Mat2D.invert(invert, parentWorld(component))) { - return; - } - // Get our target world coordinates in parent local. - translationB.apply(invert); - } - if (max && translationB.x > maxValue) { - translationB.x = maxValue; - } - if (min && translationB.x < minValue) { - translationB.x = minValue; - } - if (maxY && translationB.y > maxValueY) { - translationB.y = maxValueY; - } - if (minY && translationB.y < minValueY) { - translationB.y = minValueY; - } - if (clampLocal) { - // Transform back to world. - translationB.apply(parentWorld(component)); - } - - var ti = 1 - strength; - - // Just interpolate world translation - transformA[4] = translationA.x * ti + translationB.x * strength; - transformA[5] = translationA.y * ti + translationB.y * strength; - } -} diff --git a/lib/src/rive_core/container_component.dart b/lib/src/rive_core/container_component.dart deleted file mode 100644 index ca936b6..0000000 --- a/lib/src/rive_core/container_component.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/container_component_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/draw_rules.dart'; -import 'package:rive/src/rive_core/drawable.dart'; - -export 'package:rive/src/core/core.dart'; - -typedef bool DescentCallback(Component component); - -abstract class ContainerComponent extends ContainerComponentBase { - final ContainerChildren children = ContainerChildren(); - - /// Adds the child to the children list and re-wires the parent reference of - /// the child to the parent. Effectively detach and append. - void appendChild(Component child) { - child.parent = this; - } - - void prependChild(Component child) { - child.parent = this; - } - - @mustCallSuper - void childAdded(Component child) { - propagateCollapseToChildren(isCollapsed); - } - - void childRemoved(Component child) {} - - // Make sure that the current function can be applied to the current - // [Component], before descending onto all the children. - bool forAll(DescentCallback cb) { - if (cb(this) == false) { - return false; - } - forEachChild(cb); - return true; - } - - // Recursively descend onto all the children in the hierarchy tree. - // If the callback returns false, it won't recurse down a particular branch. - void forEachChild(DescentCallback cb) { - for (final child in children) { - if (cb(child) == false) { - continue; - } - - // TODO: replace with a more robust check. - if (child is ContainerComponent) { - child.forEachChild(cb); - } - } - } - - /// Recursive version of [Component.remove]. This should only be called when - /// you know this is the only part of the branch you are removing in your - /// operation. If your operation could remove items from the same branch - /// multiple times, you should consider building up a list of the individual - /// items to remove and then remove them individually to avoid calling remove - /// multiple times on children. - void removeRecursive() { - Set deathRow = {this}; - forEachChild((child) => deathRow.add(child)); - deathRow.forEach(context.removeObject); - } - - void buildDrawOrder( - List drawables, DrawRules? rules, List allRules) { - for (final child in children) { - if (child is ContainerComponent) { - child.buildDrawOrder(drawables, rules, allRules); - } - } - } - - @protected - void propagateCollapseToChildren(bool collapse) { - for (final child in children) { - child.propagateCollapse(collapse); - } - } - - @override - bool propagateCollapse(bool collapse) { - if (!super.propagateCollapse(collapse)) { - return false; - } - propagateCollapseToChildren(collapse); - return true; - } -} diff --git a/lib/src/rive_core/custom_property.dart b/lib/src/rive_core/custom_property.dart deleted file mode 100644 index f0e742e..0000000 --- a/lib/src/rive_core/custom_property.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/custom_property_base.dart'; -export 'package:rive/src/generated/custom_property_base.dart'; - -/// A custom property value stored in the hierarchy with a boolean value. -class CustomProperty extends CustomPropertyBase { - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/custom_property_boolean.dart b/lib/src/rive_core/custom_property_boolean.dart deleted file mode 100644 index a7f0686..0000000 --- a/lib/src/rive_core/custom_property_boolean.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/custom_property_boolean_base.dart'; -export 'package:rive/src/generated/custom_property_boolean_base.dart'; - -/// A custom property value stored in the hierarchy with a boolean value. -class CustomPropertyBoolean extends CustomPropertyBooleanBase { - @override - void propertyValueChanged(bool from, bool to) {} -} diff --git a/lib/src/rive_core/custom_property_number.dart b/lib/src/rive_core/custom_property_number.dart deleted file mode 100644 index d522ae4..0000000 --- a/lib/src/rive_core/custom_property_number.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/custom_property_number_base.dart'; -export 'package:rive/src/generated/custom_property_number_base.dart'; - -/// A custom property value stored in the hierarchy with a numeric value. -class CustomPropertyNumber extends CustomPropertyNumberBase { - @override - void propertyValueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/custom_property_string.dart b/lib/src/rive_core/custom_property_string.dart deleted file mode 100644 index 69b94ff..0000000 --- a/lib/src/rive_core/custom_property_string.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/custom_property_string_base.dart'; -export 'package:rive/src/generated/custom_property_string_base.dart'; - -/// A custom property value stored in the hierarchy with a string value. -class CustomPropertyString extends CustomPropertyStringBase { - @override - void propertyValueChanged(String from, String to) {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property.dart b/lib/src/rive_core/data_bind/bindable_property.dart deleted file mode 100644 index 60729d4..0000000 --- a/lib/src/rive_core/data_bind/bindable_property.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_base.dart'; - -enum PropertyType { - number, - string, - boolean, - enumerator, - color, -} - -class BindableProperty extends BindablePropertyBase { - @override - void onAddedDirty() {} - - @override - void onAdded() {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property_boolean.dart b/lib/src/rive_core/data_bind/bindable_property_boolean.dart deleted file mode 100644 index da955e1..0000000 --- a/lib/src/rive_core/data_bind/bindable_property_boolean.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_boolean_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_boolean_base.dart'; - -class BindablePropertyBoolean extends BindablePropertyBooleanBase { - @override - void propertyValueChanged(bool from, bool to) {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property_color.dart b/lib/src/rive_core/data_bind/bindable_property_color.dart deleted file mode 100644 index 0bf6f50..0000000 --- a/lib/src/rive_core/data_bind/bindable_property_color.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_color_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_color_base.dart'; - -class BindablePropertyColor extends BindablePropertyColorBase { - @override - void propertyValueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property_enum.dart b/lib/src/rive_core/data_bind/bindable_property_enum.dart deleted file mode 100644 index 2fb7aaa..0000000 --- a/lib/src/rive_core/data_bind/bindable_property_enum.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_enum_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_enum_base.dart'; - -class BindablePropertyEnum extends BindablePropertyEnumBase { - @override - void propertyValueChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property_number.dart b/lib/src/rive_core/data_bind/bindable_property_number.dart deleted file mode 100644 index ba3734e..0000000 --- a/lib/src/rive_core/data_bind/bindable_property_number.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_number_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_number_base.dart'; - -class BindablePropertyNumber extends BindablePropertyNumberBase { - @override - void propertyValueChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/data_bind/bindable_property_string.dart b/lib/src/rive_core/data_bind/bindable_property_string.dart deleted file mode 100644 index c05d727..0000000 --- a/lib/src/rive_core/data_bind/bindable_property_string.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/data_bind/bindable_property_string_base.dart'; - -export 'package:rive/src/generated/data_bind/bindable_property_string_base.dart'; - -class BindablePropertyString extends BindablePropertyStringBase { - @override - void propertyValueChanged(String from, String to) {} -} diff --git a/lib/src/rive_core/data_bind/context/context_value.dart b/lib/src/rive_core/data_bind/context/context_value.dart deleted file mode 100644 index f56d14b..0000000 --- a/lib/src/rive_core/data_bind/context/context_value.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -abstract class ContextValue { - ViewModelInstanceValue? source; - ContextValue(this.source); - void apply(Core core, int propertyKey); - void applyToSource(Core core, int propertyKey); - void update(Core core) {} -} diff --git a/lib/src/rive_core/data_bind/context/context_value_boolean.dart b/lib/src/rive_core/data_bind/context/context_value_boolean.dart deleted file mode 100644 index 07a8265..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_boolean.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_boolean.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueBoolean extends ContextValue { - ContextValueBoolean(ViewModelInstanceValue? source) : super(source); - - @override - void apply(Core core, int propertyKey) { - if (source?.coreType == ViewModelInstanceBooleanBase.typeKey) { - final sourceBoolean = source as ViewModelInstanceBoolean; - - RiveCoreContext.setBool(core, propertyKey, sourceBoolean.propertyValue); - } - } - - @override - void applyToSource(Core core, int propertyKey) { - final value = RiveCoreContext.getBool(core, propertyKey); - final sourceBoolean = source as ViewModelInstanceBoolean; - sourceBoolean.propertyValue = value; - } -} diff --git a/lib/src/rive_core/data_bind/context/context_value_color.dart b/lib/src/rive_core/data_bind/context/context_value_color.dart deleted file mode 100644 index 9e4eacd..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_color.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_color.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueColor extends ContextValue { - ContextValueColor(ViewModelInstanceValue? source) : super(source); - - @override - void apply(Core core, int propertyKey) { - if (source?.coreType == ViewModelInstanceColorBase.typeKey) { - final sourceColor = source as ViewModelInstanceColor; - - RiveCoreContext.setColor(core, propertyKey, sourceColor.propertyValue); - } - } - - @override - void applyToSource(Core core, int propertyKey) { - final value = RiveCoreContext.getColor(core, propertyKey); - final sourceColor = source as ViewModelInstanceColor; - sourceColor.propertyValue = value; - } -} diff --git a/lib/src/rive_core/data_bind/context/context_value_enum.dart b/lib/src/rive_core/data_bind/context/context_value_enum.dart deleted file mode 100644 index 8ea34be..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_enum.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueEnum extends ContextValue { - ContextValueEnum(ViewModelInstanceValue? source) : super(source); - - @override - void apply(Core core, int propertyKey) { - // TODO: @hernan implement - } - - @override - void applyToSource(Core core, int propertyKey) { - // TODO: @hernan implement - } -} diff --git a/lib/src/rive_core/data_bind/context/context_value_list.dart b/lib/src/rive_core/data_bind/context/context_value_list.dart deleted file mode 100644 index 62f386b..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_list.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueList extends ContextValue { - ContextValueList(ViewModelInstanceValue? source) : super(source); - - @override - void apply(Core core, int propertyKey) { - // TODO: @hernan implement - } - - @override - void applyToSource(Core core, int propertyKey) { - // TODO: @hernan implement - } -} diff --git a/lib/src/rive_core/data_bind/context/context_value_number.dart b/lib/src/rive_core/data_bind/context/context_value_number.dart deleted file mode 100644 index 15d6415..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_number.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_number.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueNumber extends ContextValue { - ContextValueNumber(ViewModelInstanceValue? source) : super(source); - - @override - void apply(Core core, int propertyKey) { - if (source?.coreType == ViewModelInstanceNumberBase.typeKey) { - final sourceNumber = source as ViewModelInstanceNumber; - - RiveCoreContext.setDouble(core, propertyKey, sourceNumber.propertyValue); - } - } - - @override - void applyToSource(Core core, int propertyKey) { - final value = RiveCoreContext.getDouble(core, propertyKey); - final sourceNumber = source as ViewModelInstanceNumber; - sourceNumber.propertyValue = value; - } -} diff --git a/lib/src/rive_core/data_bind/context/context_value_string.dart b/lib/src/rive_core/data_bind/context/context_value_string.dart deleted file mode 100644 index 221cfcf..0000000 --- a/lib/src/rive_core/data_bind/context/context_value_string.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_string.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -class ContextValueString extends ContextValue { - ContextValueString(ViewModelInstanceValue? source) - : super(source as ViewModelInstanceString); - @override - void apply(Core core, int propertyKey) { - if (source?.coreType == ViewModelInstanceStringBase.typeKey) { - final sourceString = source as ViewModelInstanceString; - - RiveCoreContext.setString(core, propertyKey, sourceString.propertyValue); - } - } - - @override - void applyToSource(Core core, int propertyKey) { - final value = RiveCoreContext.getString(core, propertyKey); - final sourceString = source as ViewModelInstanceString; - sourceString.propertyValue = value; - } -} diff --git a/lib/src/rive_core/data_bind/data_bind.dart b/lib/src/rive_core/data_bind/data_bind.dart deleted file mode 100644 index 7c830bd..0000000 --- a/lib/src/rive_core/data_bind/data_bind.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:rive/src/generated/data_bind/data_bind_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value_boolean.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value_color.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value_number.dart'; -import 'package:rive/src/rive_core/data_bind/context/context_value_string.dart'; -import 'package:rive/src/rive_core/data_bind/data_context.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_boolean.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_color.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_enum.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_list.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_number.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_string.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; - -export 'package:rive/src/generated/data_bind/data_bind_base.dart'; - -class DataBind extends DataBindBase { - Component? target; - ViewModelInstanceValue? source; - ContextValue? contextValue; - - int dirt = ComponentDirt.filthy; - - bool addDirt(int value, {bool recurse = false}) { - if ((dirt & value) == value) { - return false; - } - - dirt |= value; - return true; - } - - @override - void onAddedDirty() {} - - @override - void onAdded() {} - - void update(int dirt) {} - - void updateSourceBinding() {} - - @override - void propertyKeyChanged(int from, int to) {} - - @override - // ignore: override_on_non_overriding_member - void targetIdChanged(int from, int to) {} - - @override - void converterIdChanged(int from, int to) {} - - @override - void flagsChanged(int from, int to) {} - - void bind(DataContext? dataContext) { - switch (source?.coreType) { - case ViewModelInstanceNumberBase.typeKey: - contextValue = ContextValueNumber(source); - break; - case ViewModelInstanceStringBase.typeKey: - contextValue = ContextValueString(source); - break; - case ViewModelInstanceEnumBase.typeKey: - break; - case ViewModelInstanceListBase.typeKey: - break; - case ViewModelInstanceColorBase.typeKey: - contextValue = ContextValueColor(source); - break; - case ViewModelInstanceBooleanBase.typeKey: - contextValue = ContextValueBoolean(source); - break; - } - } -} diff --git a/lib/src/rive_core/data_bind/data_bind_context.dart b/lib/src/rive_core/data_bind/data_bind_context.dart deleted file mode 100644 index 18e0954..0000000 --- a/lib/src/rive_core/data_bind/data_bind_context.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:rive/src/generated/data_bind/data_bind_context_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/data_bind/data_context.dart'; -import 'package:rive/src/rive_core/data_bind_flags.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_color.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_number.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_string.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/data_bind/data_bind_context_base.dart'; - -// ignore: one_member_abstracts -abstract class DataBindContextInterface { - bool addDirt(int value, {bool recurse = false}); -} - -class DataBindContext extends DataBindContextBase - with DataBindContextInterface { - @override - void sourcePathIdsChanged(List from, List to) {} - - final List _ids = []; - - void onTargetPropertyChanged(dynamic from, dynamic to) { - addDirt(ComponentDirt.bindings); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - - var reader = BinaryReader.fromList(sourcePathIds); - while (!reader.isEOF) { - _ids.add(reader.readVarUint()); - } - } - - @override - void bind(DataContext? dataContext) { - if (dataContext != null) { - final value = dataContext.getViewModelProperty(_ids); - if (value != null) { - if (value is ViewModelInstanceNumber) { - value.addDependent(this); - } else if (value is ViewModelInstanceString) { - value.addDependent(this); - } else if (value is ViewModelInstanceColor) { - value.addDependent(this); - } - source = value; - super.bind(dataContext); - } - } - } - - @override - void update(int dirt) { - if (dirt & ComponentDirt.bindings != 0) { - if ((flags & DataBindFlags.direction == DataBindFlags.toTarget) || - (flags & DataBindFlags.twoWay == DataBindFlags.twoWay)) { - if (contextValue != null) { - contextValue!.apply(target!, propertyKey); - } - } - } - super.update(dirt); - } - - @override - void updateSourceBinding() { - if ((flags & DataBindFlags.direction == DataBindFlags.toSource) || - (flags & DataBindFlags.twoWay == DataBindFlags.twoWay)) { - if (contextValue != null) { - contextValue!.applyToSource(target!, propertyKey); - } - } - } -} diff --git a/lib/src/rive_core/data_bind/data_context.dart b/lib/src/rive_core/data_bind/data_context.dart deleted file mode 100644 index 95dbf02..0000000 --- a/lib/src/rive_core/data_bind/data_context.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart'; - -class DataContext { - final ViewModelInstance viewModelInstance; - DataContext? parent; - - DataContext(this.viewModelInstance); - - ViewModelInstanceValue? getViewModelProperty(List path) { - if (path.isNotEmpty) { - if (path.first == viewModelInstance.viewModelId) { - ViewModelInstance? viewModelInstanceTarget = viewModelInstance; - int index = 1; - while (index < path.length - 1) { - viewModelInstanceTarget = (viewModelInstanceTarget! - .propertyValueByPropertyId( - path[index]) as ViewModelInstanceViewModel) - .referenceViewModelInstance; - if (viewModelInstanceTarget == null) { - return parent?.getViewModelProperty(path); - } - index += 1; - } - return viewModelInstanceTarget!.propertyValueByPropertyId(path[index]); - } - } - return parent?.getViewModelProperty(path); - } - - ViewModelInstance? getViewModelInstance(List path) { - if (path.isNotEmpty && path.first == viewModelInstance.viewModelId) { - ViewModelInstance? viewModelInstanceTarget = viewModelInstance; - int index = 1; - while (index < path.length) { - final viewModelInstanceViewModel = viewModelInstanceTarget! - .propertyValueByPropertyId( - path[index]) as ViewModelInstanceViewModel?; - if (viewModelInstanceViewModel == null) { - return parent?.getViewModelInstance(path); - } - viewModelInstanceTarget = - viewModelInstanceViewModel.referenceViewModelInstance; - if (viewModelInstanceTarget == null) { - return parent?.getViewModelInstance(path); - } - index += 1; - } - return viewModelInstanceTarget; - } - return parent?.getViewModelInstance(path); - } -} diff --git a/lib/src/rive_core/data_bind_flags.dart b/lib/src/rive_core/data_bind_flags.dart deleted file mode 100644 index fe3e741..0000000 --- a/lib/src/rive_core/data_bind_flags.dart +++ /dev/null @@ -1,14 +0,0 @@ -class DataBindFlags { - /// Whether the main binding direction is to target (0) or to source (1) - static const int direction = 1 << 0; - - /// Whether the binding direction is twoWay - static const int twoWay = 1 << 1; - - /// Whether the binding happens only once - static const int once = 1 << 2; - - static const int toTarget = 0; - - static const int toSource = 1 << 0; -} diff --git a/lib/src/rive_core/dependency_helper.dart b/lib/src/rive_core/dependency_helper.dart deleted file mode 100644 index fb0383b..0000000 --- a/lib/src/rive_core/dependency_helper.dart +++ /dev/null @@ -1,27 +0,0 @@ -class DependencyHelper { - Set dependents = {}; - T? dependencyRoot; - - DependencyHelper(); - - bool addDependent(U value) { - if (!dependents.contains(value)) { - dependents.add(value); - return true; - } - return false; - } - - void addDirt(int dirt, {bool recurse = false}) { - dependents - .forEach((dependent) => dependent.addDirt(dirt, recurse: recurse)); - } - - void onComponentDirty(U component) { - dependencyRoot?.onComponentDirty(component); - } - - void clear() { - dependents.clear(); - } -} diff --git a/lib/src/rive_core/draw_rules.dart b/lib/src/rive_core/draw_rules.dart deleted file mode 100644 index 574ae28..0000000 --- a/lib/src/rive_core/draw_rules.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/draw_rules_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/draw_target.dart'; - -export 'package:rive/src/generated/draw_rules_base.dart'; - -class DrawRules extends DrawRulesBase { - final List _targets = []; - List get targets => _targets; - - DrawTarget? _activeTarget; - DrawTarget? get activeTarget => _activeTarget; - set activeTarget(DrawTarget? value) => - drawTargetId = value?.id ?? Core.missingId; - - @override - void drawTargetIdChanged(int from, int to) { - _activeTarget = context.resolve(to); - artboard?.markDrawOrderDirty(); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - _activeTarget = context.resolve(drawTargetId); - } - - @override - void update(int dirt) {} - - @override - void childAdded(Component child) { - super.childAdded(child); - switch (child.coreType) { - case DrawTargetBase.typeKey: - _addTarget(child as DrawTarget); - - break; - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - switch (child.coreType) { - case DrawTargetBase.typeKey: - _targets.remove(child as DrawTarget); - if (_targets.isEmpty) { - remove(); - } - - break; - } - } - - void _addTarget(DrawTarget child) { - if (!_targets.contains(child)) { - _targets.add(child); - } - } -} diff --git a/lib/src/rive_core/draw_target.dart b/lib/src/rive_core/draw_target.dart deleted file mode 100644 index cc4ff5b..0000000 --- a/lib/src/rive_core/draw_target.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/draw_target_base.dart'; -import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; - -export 'package:rive/src/generated/draw_target_base.dart'; - -enum DrawTargetPlacement { before, after } - -class DrawTarget extends DrawTargetBase { - // Store first and last drawables that are affected by this target. - Drawable? first; - Drawable? last; - - Drawable? _drawable; - Drawable? get drawable => _drawable; - set drawable(Drawable? value) { - if (_drawable == value) { - return; - } - - _drawable = value; - drawableId = value?.id ?? Core.missingId; - } - - DrawTargetPlacement get placement => - enumAt(DrawTargetPlacement.values, placementValue); - set placement(DrawTargetPlacement value) => placementValue = value.index; - - @override - void drawableIdChanged(int from, int to) { - drawable = context.resolve(to); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - drawable = context.resolve(drawableId); - } - - @override - void placementValueChanged(int from, int to) { - artboard?.markDrawOrderDirty(); - } - - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/drawable.dart b/lib/src/rive_core/drawable.dart deleted file mode 100644 index d42aa3f..0000000 --- a/lib/src/rive_core/drawable.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/drawable_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/component_flags.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/draw_rules.dart'; -import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; - -export 'package:rive/src/generated/drawable_base.dart'; - -abstract class Drawable extends DrawableBase { - /// Flattened rules inherited from parents (or self) so we don't have to look - /// up the tree when re-sorting. - DrawRules? flattenedDrawRules; - - /// The previous drawable in the draw order. - Drawable? prev; - - /// The next drawable in the draw order. - Drawable? next; - - @override - void buildDrawOrder( - List drawables, DrawRules? rules, List allRules) { - flattenedDrawRules = drawRules ?? rules; - - drawables.add(this); - - super.buildDrawOrder(drawables, rules, allRules); - } - - /// Draw the contents of this drawable component in world transform space. - void draw(Canvas canvas); - - BlendMode get blendMode => BlendMode.values[blendModeValue]; - set blendMode(BlendMode value) => blendModeValue = value.index; - - @override - void blendModeValueChanged(int from, int to) {} - - List _clippingShapes = []; - - bool clip(Canvas canvas) { - if (_clippingShapes.isEmpty) { - return false; - } - canvas.save(); - for (final clip in _clippingShapes) { - if (!clip.isVisible) { - continue; - } - canvas.clipPath(clip.clippingPath); - } - return true; - } - - @override - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - super.parentChanged(from, to); - // Make sure we re-compute clipping shapes when we change parents. Issue - // #1586 - addDirt(ComponentDirt.clip); - } - - @override - void update(int dirt) { - super.update(dirt); - if (dirt & ComponentDirt.clip != 0) { - // Find clip in parents. - List clippingShapes = []; - for (ContainerComponent? p = this; p != null; p = p.parent) { - if (p is TransformComponent) { - if (p.clippingShapes.isNotEmpty) { - clippingShapes.addAll(p.clippingShapes); - } - } - } - _clippingShapes = clippingShapes; - } - } - - // When drawable flags change, repaint. - @override - void drawableFlagsChanged(int from, int to) => addDirt(ComponentDirt.paint); - - bool get isHidden => - (drawableFlags & ComponentFlags.hidden) != 0 || - (dirt & ComponentDirt.collapsed) != 0; - - bool get isTargetOpaque { - return (drawableFlags & ComponentFlags.opaque) != 0; - } -} diff --git a/lib/src/rive_core/enum_helper.dart b/lib/src/rive_core/enum_helper.dart deleted file mode 100644 index fa79cdd..0000000 --- a/lib/src/rive_core/enum_helper.dart +++ /dev/null @@ -1,3 +0,0 @@ -/// Helper for getting a valid enum at an index (or default to the first one). -T enumAt(List values, int index) => - index < values.length ? values[index] : values.first; diff --git a/lib/src/rive_core/event.dart b/lib/src/rive_core/event.dart deleted file mode 100644 index 38e0ce4..0000000 --- a/lib/src/rive_core/event.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:rive/src/generated/event_base.dart'; -import 'package:rive/src/rive_core/animation/linear_animation_instance.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/custom_property.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/event_base.dart'; - -class Event extends EventBase { - final List customProperties = []; - - double _secondsDelay = 0.0; - double get secondsDelay => _secondsDelay; - - @override - void update(int dirt) {} - - @override - void changeArtboard(Artboard? value) { - artboard?.internalRemoveEvent(this); - super.changeArtboard(value); - artboard?.internalAddEvent(this); - } - - void _syncCustomProperties() { - var nextCustomProperties = children.whereType().toSet(); - if (!iterableEquals(customProperties, nextCustomProperties)) { - customProperties.clear(); - customProperties.addAll(nextCustomProperties); - } - } - - @override - void childAdded(Component child) { - super.childAdded(child); - _syncCustomProperties(); - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - _syncCustomProperties(); - } - - @override - void trigger(CallbackData data) { - if (data.context is StateMachineController) { - var controller = data.context as StateMachineController; - _secondsDelay = data.delay; - controller.reportEvent(this); - } else if (data.context is LinearAnimationInstance) { - var animation = data.context as LinearAnimationInstance; - animation.reportEvent(this); - } - } -} diff --git a/lib/src/rive_core/joystick.dart b/lib/src/rive_core/joystick.dart deleted file mode 100644 index f38fef4..0000000 --- a/lib/src/rive_core/joystick.dart +++ /dev/null @@ -1,256 +0,0 @@ -import 'package:rive/src/generated/joystick_base.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/joystick_base.dart'; - -class JoystickFlags { - /// Whether to invert the application of the x axis. - static const int invertX = 1 << 0; - - /// Whether to invert the application of the y axis. - static const int invertY = 1 << 1; - - /// Whether this Joystick works in world space. - static const int worldSpace = 1 << 2; -} - -class Joystick extends JoystickBase { - double get clampedX => x.clamp(-1, 1); - double get clampedY => y.clamp(-1, 1); - - bool get isComplex => handleSource != null; - - @override - void update(int dirt) { - if (dirt & (ComponentDirt.transform | ComponentDirt.worldTransform) != 0) { - _worldTransform = computeWorldTransform(); - Mat2D.invert(_inverseWorldTransform, _worldTransform); - if (isComplex) { - var pos = _inverseWorldTransform * handleSource!.worldTranslation; - var local = localBounds.factorFrom(pos); - - x = local.x; - y = local.y; - } - } - } - - bool get invertX => (joystickFlags & JoystickFlags.invertX) != 0; - set invertX(bool value) { - if (value) { - joystickFlags |= JoystickFlags.invertX; - } else { - joystickFlags &= ~JoystickFlags.invertX; - } - } - - bool get invertY => (joystickFlags & JoystickFlags.invertY) != 0; - set invertY(bool value) { - if (value) { - joystickFlags |= JoystickFlags.invertY; - } else { - joystickFlags &= ~JoystickFlags.invertY; - } - } - - bool get inWorldSpace => - (joystickFlags & JoystickFlags.worldSpace) != 0 || handleSource != null; - set inWorldSpace(bool value) { - if (value) { - joystickFlags |= JoystickFlags.worldSpace; - } else { - joystickFlags &= ~JoystickFlags.worldSpace; - } - } - - void apply(CoreContext context) { - var animation = _xAnimation; - - if (animation != null) { - var value = invertX ? -x : x; - animation.apply( - (value + 1) / 2 * animation.durationSeconds, - coreContext: context, - ); - } - animation = _yAnimation; - if (animation != null) { - var value = invertY ? -y : y; - animation.apply( - (value + 1) / 2 * animation.durationSeconds, - coreContext: context, - ); - } - } - - @override - void xChanged(double from, double to) { - context.markNeedsAdvance(); - } - - @override - void buildDependencies() { - super.buildDependencies(); - parent?.addDependent(this); - handleSource?.addDependent(this); - } - - Vec2D get position => Vec2D.fromValues(posX, posY); - Mat2D _worldTransform = Mat2D(); - final Mat2D _inverseWorldTransform = Mat2D(); - - Mat2D computeWorldTransform() { - var local = Mat2D.fromTranslation(position); - if (parent is WorldTransformComponent) { - var world = Mat2D.multiply( - Mat2D(), (parent as WorldTransformComponent).worldTransform, local); - if (!inWorldSpace) { - return Mat2D.fromTranslation(world.translation); - } - return world; - } - return local; - } - - Mat2D get worldTransform => - inWorldSpace ? _worldTransform : computeWorldTransform(); - - @override - void yChanged(double from, double to) { - context.markNeedsAdvance(); - } - - @override - void xIdChanged(int from, int to) { - xAnimation = xId == Core.missingId ? null : context.resolve(xId); - } - - @override - void yIdChanged(int from, int to) { - yAnimation = yId == Core.missingId ? null : context.resolve(yId); - } - - LinearAnimation? _xAnimation; - LinearAnimation? _yAnimation; - - LinearAnimation? get xAnimation => _xAnimation; - LinearAnimation? get yAnimation => _yAnimation; - - set xAnimation(LinearAnimation? value) { - if (_xAnimation == value) { - return; - } - - _xAnimation = value; - } - - set yAnimation(LinearAnimation? value) { - if (_yAnimation == value) { - return; - } - - _yAnimation = value; - } - - @override - void onAdded() { - super.onAdded(); - if (xId >= 0 && xId < context.animations.length) { - var found = context.animations[xId]; - if (found is LinearAnimation) { - xAnimation = found; - } - } - if (yId >= 0 && yId < context.animations.length) { - var found = context.animations[yId]; - if (found is LinearAnimation) { - yAnimation = found; - } - } - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - - handleSource = context.resolve(handleSourceId); - } - - void _transformChanged() { - markTransformDirty(); - } - - @override - void heightChanged(double from, double to) {} - - @override - void posXChanged(double from, double to) => _transformChanged(); - - @override - void posYChanged(double from, double to) => _transformChanged(); - - @override - void widthChanged(double from, double to) {} - - static const double minStageSize = 0; - bool get isSliderY => xAnimation == null && yAnimation != null; - bool get isSliderX => yAnimation == null && xAnimation != null; - - double get stageWidth => isSliderY ? minStageSize : width; - double get stageHeight => isSliderX ? minStageSize : height; - - AABB get localBounds => AABB.fromValues( - -stageWidth * originX, - -stageHeight * originY, - -stageWidth * originX + stageWidth, - -stageHeight * originY + stageHeight, - ); - - Mat2D get transform => Mat2D.fromTranslation(position); - - @override - void originXChanged(double from, double to) => _transformChanged(); - - @override - void originYChanged(double from, double to) => _transformChanged(); - - @override - void joystickFlagsChanged(int from, int to) { - context.markNeedsAdvance(); - - markTransformDirty(); - } - - TransformComponent? _handleSource; - TransformComponent? get handleSource => _handleSource; - set handleSource(TransformComponent? value) { - if (_handleSource == value) { - return; - } - - _handleSource = value; - handleSourceId = value?.id ?? Core.missingId; - markTransformDirty(); - } - - @override - void handleSourceIdChanged(int from, int to) { - handleSource = context.resolve(to); - markRebuildDependencies(); - } - - void markTransformDirty() { - if (!inWorldSpace) { - return; - } - if (!addDirt(ComponentDirt.transform)) { - return; - } - addDirt(ComponentDirt.worldTransform, recurse: true); - } -} diff --git a/lib/src/rive_core/layer_state_flags.dart b/lib/src/rive_core/layer_state_flags.dart deleted file mode 100644 index 6b2b479..0000000 --- a/lib/src/rive_core/layer_state_flags.dart +++ /dev/null @@ -1,7 +0,0 @@ -class LayerStateFlags { - /// Whether the state can randomize on exit. - static const int random = 1 << 0; - - /// Whether the blend should include an instance to reset values on apply - static const int reset = 1 << 1; -} diff --git a/lib/src/rive_core/layout/layout_component_style.dart b/lib/src/rive_core/layout/layout_component_style.dart deleted file mode 100644 index 0b5ea06..0000000 --- a/lib/src/rive_core/layout/layout_component_style.dart +++ /dev/null @@ -1,516 +0,0 @@ -import 'package:rive/src/generated/layout/layout_component_style_base.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolation.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/notifier.dart'; -import 'package:rive_common/layout_engine.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/layout/layout_component_style_base.dart'; - -enum LayoutAlignmentType { - topLeft, - topCenter, - topRight, - centerLeft, - center, - centerRight, - bottomLeft, - bottomCenter, - bottomRight, - spaceBetweenStart, - spaceBetweenCenter, - spaceBetweenEnd; -} - -enum ScaleType { - fixed, - fill, - hug; - - String get label => name[0].toUpperCase() + name.substring(1); -} - -enum LayoutAnimationStyle { none, inherit, custom } - -enum LayoutStyleInterpolation { hold, linear, cubic, elastic } - -extension LayoutStyleInterpolationExtension on LayoutStyleInterpolation { - // Converts to KeyFrameInterpolation to we can be compatible with - // InterpolationViewModel - KeyFrameInterpolation toKeyFrameInterpolation() { - switch (this) { - case LayoutStyleInterpolation.hold: - return KeyFrameInterpolation.hold; - case LayoutStyleInterpolation.linear: - return KeyFrameInterpolation.linear; - case LayoutStyleInterpolation.cubic: - return KeyFrameInterpolation.cubic; - case LayoutStyleInterpolation.elastic: - return KeyFrameInterpolation.elastic; - } - } -} - -class LayoutComponentStyle extends LayoutComponentStyleBase { - Notifier valueChanged = Notifier(); - Notifier interpolationChanged = Notifier(); - - KeyFrameInterpolator? _interpolator; - KeyFrameInterpolator? get interpolator => _interpolator; - set interpolator(KeyFrameInterpolator? value) { - if (_interpolator == value) { - return; - } - _interpolator = value; - interpolatorId = value?.id ?? Core.missingId; - } - - LayoutStyleInterpolation get interpolation => - enumAt(LayoutStyleInterpolation.values, interpolationType); - set interpolation(LayoutStyleInterpolation value) { - interpolationType = value.index; - } - - LayoutAnimationStyle get animationStyle => - enumAt(LayoutAnimationStyle.values, animationStyleType); - set animationStyle(LayoutAnimationStyle value) { - animationStyleType = value.index; - } - - static List enumForPropertyKey(int propertyKey) { - switch (propertyKey) { - case LayoutComponentStyleBase.borderLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.borderBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.marginBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.paddingBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionLeftUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionRightUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionTopUnitsValuePropertyKey: - case LayoutComponentStyleBase.positionBottomUnitsValuePropertyKey: - case LayoutComponentStyleBase.gapHorizontalUnitsValuePropertyKey: - case LayoutComponentStyleBase.gapVerticalUnitsValuePropertyKey: - case LayoutComponentStyleBase.minWidthUnitsValuePropertyKey: - case LayoutComponentStyleBase.minHeightUnitsValuePropertyKey: - case LayoutComponentStyleBase.maxWidthUnitsValuePropertyKey: - case LayoutComponentStyleBase.maxHeightUnitsValuePropertyKey: - case LayoutComponentStyleBase.widthUnitsValuePropertyKey: - case LayoutComponentStyleBase.heightUnitsValuePropertyKey: - return LayoutUnit.values; - case LayoutComponentStyleBase.alignContentValuePropertyKey: - case LayoutComponentStyleBase.alignItemsValuePropertyKey: - case LayoutComponentStyleBase.alignSelfValuePropertyKey: - return LayoutAlign.values; - case LayoutComponentStyleBase.justifyContentValuePropertyKey: - return LayoutJustify.values; - case LayoutComponentStyleBase.directionValuePropertyKey: - return LayoutDirection.values; - case LayoutComponentStyleBase.flexDirectionValuePropertyKey: - return LayoutFlexDirection.values; - case LayoutComponentStyleBase.positionTypeValuePropertyKey: - return LayoutPosition.values; - case LayoutComponentStyleBase.flexWrapValuePropertyKey: - return LayoutWrap.values; - case LayoutComponentStyleBase.overflowValuePropertyKey: - return LayoutOverflow.values; - case LayoutComponentStyleBase.displayValuePropertyKey: - return LayoutDisplay.values; - case LayoutComponentStyleBase.layoutAlignmentTypePropertyKey: - return LayoutAlignmentType.values; - default: - return []; - } - } - - static const BitFieldLoc widthScaleTypeBits = BitFieldLoc(0, 3); - static const BitFieldLoc heightScaleTypeBits = BitFieldLoc(4, 7); - - LayoutDisplay get display => LayoutDisplay.values[displayValue]; - set display(LayoutDisplay value) => displayValue = value.index; - - LayoutPosition get positionType => LayoutPosition.values[positionTypeValue]; - set positionType(LayoutPosition value) => positionTypeValue = value.index; - - LayoutFlexDirection get flexDirection => - LayoutFlexDirection.values[flexDirectionValue]; - set flexDirection(LayoutFlexDirection value) => - flexDirectionValue = value.index; - - LayoutDirection get direction => LayoutDirection.values[directionValue]; - set direction(LayoutDirection value) => directionValue = value.index; - - LayoutWrap get flexWrap => LayoutWrap.values[flexWrapValue]; - set flexWrap(LayoutWrap value) => flexWrapValue = value.index; - - LayoutAlign get alignItems => LayoutAlign.values[alignItemsValue]; - set alignItems(LayoutAlign value) => alignItemsValue = value.index; - - LayoutAlign get alignSelf => LayoutAlign.values[alignSelfValue]; - set alignSelf(LayoutAlign value) => alignSelfValue = value.index; - - LayoutAlign get alignContent => LayoutAlign.values[alignContentValue]; - set alignContent(LayoutAlign value) => alignContentValue = value.index; - - LayoutJustify get justifyContent => LayoutJustify.values[justifyContentValue]; - set justifyContent(LayoutJustify value) => justifyContentValue = value.index; - - bool get intrinsicallySized => intrinsicallySizedValue; - set intrinsicallySized(bool value) => intrinsicallySizedValue = value; - - LayoutUnit get widthUnits => LayoutUnit.values[widthUnitsValue]; - set widthUnits(LayoutUnit value) => widthUnitsValue = value.index; - - LayoutUnit get heightUnits => LayoutUnit.values[heightUnitsValue]; - set heightUnits(LayoutUnit value) => heightUnitsValue = value.index; - - LayoutUnit get borderLeftUnits => LayoutUnit.values[borderLeftUnitsValue]; - set borderLeftUnits(LayoutUnit value) => borderLeftUnitsValue = value.index; - - LayoutUnit get borderRightUnits => LayoutUnit.values[borderRightUnitsValue]; - set borderRightUnits(LayoutUnit value) => borderRightUnitsValue = value.index; - - LayoutUnit get borderTopUnits => LayoutUnit.values[borderTopUnitsValue]; - set borderTopUnits(LayoutUnit value) => borderTopUnitsValue = value.index; - - LayoutUnit get borderBottomUnits => LayoutUnit.values[borderBottomUnitsValue]; - set borderBottomUnits(LayoutUnit value) => - borderBottomUnitsValue = value.index; - - LayoutUnit get marginLeftUnits => LayoutUnit.values[marginLeftUnitsValue]; - set marginLeftUnits(LayoutUnit value) => marginLeftUnitsValue = value.index; - - LayoutUnit get marginRightUnits => LayoutUnit.values[marginRightUnitsValue]; - set marginRightUnits(LayoutUnit value) => marginRightUnitsValue = value.index; - - LayoutUnit get marginTopUnits => LayoutUnit.values[marginTopUnitsValue]; - set marginTopUnits(LayoutUnit value) => marginTopUnitsValue = value.index; - - LayoutUnit get marginBottomUnits => LayoutUnit.values[marginBottomUnitsValue]; - set marginBottomUnits(LayoutUnit value) => - marginBottomUnitsValue = value.index; - - LayoutUnit get paddingLeftUnits => LayoutUnit.values[paddingLeftUnitsValue]; - set paddingLeftUnits(LayoutUnit value) => paddingLeftUnitsValue = value.index; - - LayoutUnit get paddingRightUnits => LayoutUnit.values[paddingRightUnitsValue]; - set paddingRightUnits(LayoutUnit value) => - paddingRightUnitsValue = value.index; - - LayoutUnit get paddingTopUnits => LayoutUnit.values[paddingTopUnitsValue]; - set paddingTopUnits(LayoutUnit value) => paddingTopUnitsValue = value.index; - - LayoutUnit get paddingBottomUnits => - LayoutUnit.values[paddingBottomUnitsValue]; - set paddingBottomUnits(LayoutUnit value) => - paddingBottomUnitsValue = value.index; - - LayoutUnit get positionLeftUnits => LayoutUnit.values[positionLeftUnitsValue]; - set positionLeftUnits(LayoutUnit value) => - positionLeftUnitsValue = value.index; - - LayoutUnit get positionRightUnits => - LayoutUnit.values[positionRightUnitsValue]; - set positionRightUnits(LayoutUnit value) => - positionRightUnitsValue = value.index; - - LayoutUnit get positionTopUnits => LayoutUnit.values[positionTopUnitsValue]; - set positionTopUnits(LayoutUnit value) => positionTopUnitsValue = value.index; - - LayoutUnit get positionBottomUnits => - LayoutUnit.values[positionBottomUnitsValue]; - set positionBottomUnits(LayoutUnit value) => - positionBottomUnitsValue = value.index; - - LayoutUnit get gapHorizontalUnits => - LayoutUnit.values[gapHorizontalUnitsValue]; - set gapHorizontalUnits(LayoutUnit value) => - gapHorizontalUnitsValue = value.index; - - LayoutUnit get gapVerticalUnits => LayoutUnit.values[gapVerticalUnitsValue]; - set gapVerticalUnits(LayoutUnit value) => gapVerticalUnitsValue = value.index; - - LayoutUnit get minWidthUnits => LayoutUnit.values[minWidthUnitsValue]; - set minWidthUnits(LayoutUnit value) => minWidthUnitsValue = value.index; - - LayoutUnit get minHeightUnits => LayoutUnit.values[minHeightUnitsValue]; - set minHeightUnits(LayoutUnit value) => minHeightUnitsValue = value.index; - - LayoutUnit get maxWidthUnits => LayoutUnit.values[maxWidthUnitsValue]; - set maxWidthUnits(LayoutUnit value) => maxWidthUnitsValue = value.index; - - LayoutUnit get maxHeightUnits => LayoutUnit.values[maxHeightUnitsValue]; - set maxHeightUnits(LayoutUnit value) => maxHeightUnitsValue = value.index; - - ScaleType get widthScaleType => - ScaleType.values[widthScaleTypeBits.read(scaleType)]; - - set widthScaleType(ScaleType value) => - scaleType = widthScaleTypeBits.write(scaleType, value.index); - - ScaleType get heightScaleType => - ScaleType.values[heightScaleTypeBits.read(scaleType)]; - - set heightScaleType(ScaleType value) => - scaleType = heightScaleTypeBits.write(scaleType, value.index); - - LayoutAlignmentType get alignmentType => - LayoutAlignmentType.values[layoutAlignmentType]; - - set alignmentType(LayoutAlignmentType value) => - layoutAlignmentType = value.index; - - void markLayoutNodeDirty() { - valueChanged.notify(); - } - - void markLayoutStyleDirty() { - interpolationChanged.notify(); - } - - @override - void buildDependencies() { - super.buildDependencies(); - parent?.addDependent(this); - } - - @override - void onAdded() {} - - @override - void onAddedDirty() { - interpolator = context.resolve(interpolatorId); - } - - @override - void flexChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void flexGrowChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void flexShrinkChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void flexBasisChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void aspectRatioChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void minWidthChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void maxWidthChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void minHeightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void maxHeightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void gapHorizontalChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void gapVerticalChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void borderLeftChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void borderTopChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void borderRightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void borderBottomChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void marginLeftChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void marginTopChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void marginRightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void marginBottomChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void paddingLeftChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void paddingTopChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void paddingRightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void paddingBottomChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void positionLeftChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void positionTopChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void positionRightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void positionBottomChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void positionTypeValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void displayValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void flexDirectionValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void directionValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void alignContentValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void alignItemsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void alignSelfValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void justifyContentValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void flexWrapValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void overflowValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void intrinsicallySizedValueChanged(bool from, bool to) => - markLayoutNodeDirty(); - - @override - void widthUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void heightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void borderLeftUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void borderRightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void borderTopUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void borderBottomUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void marginLeftUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void marginRightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void marginTopUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void marginBottomUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void paddingLeftUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void paddingRightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void paddingTopUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void paddingBottomUnitsValueChanged(int from, int to) => - markLayoutNodeDirty(); - - @override - void positionLeftUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void positionRightUnitsValueChanged(int from, int to) => - markLayoutNodeDirty(); - - @override - void positionTopUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void positionBottomUnitsValueChanged(int from, int to) => - markLayoutNodeDirty(); - - @override - void gapHorizontalUnitsValueChanged(int from, int to) => - markLayoutNodeDirty(); - - @override - void gapVerticalUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void minWidthUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void minHeightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void maxWidthUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void maxHeightUnitsValueChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void animationStyleTypeChanged(int from, int to) { - markLayoutNodeDirty(); - } - - @override - void interpolationTypeChanged(int from, int to) { - markLayoutStyleDirty(); - markLayoutNodeDirty(); - } - - @override - void interpolatorIdChanged(int from, int to) { - interpolator = context.resolve(interpolatorId); - markLayoutStyleDirty(); - markLayoutNodeDirty(); - } - - @override - void interpolationTimeChanged(double from, double to) { - markLayoutStyleDirty(); - markLayoutNodeDirty(); - } - - @override - void scaleTypeChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void layoutAlignmentTypeChanged(int from, int to) => markLayoutNodeDirty(); - - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/layout_component.dart b/lib/src/rive_core/layout_component.dart deleted file mode 100644 index a407c23..0000000 --- a/lib/src/rive_core/layout_component.dart +++ /dev/null @@ -1,700 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/rendering.dart'; -import 'package:rive/src/generated/layout_component_base.dart'; -import 'package:rive/src/rive_core/animation/keyframe_interpolator.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/layout/layout_component_style.dart'; -import 'package:rive/src/rive_core/node.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; -import 'package:rive_common/layout_engine.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/layout_component_base.dart'; - -extension ComponentExtension on Component { - LayoutComponent? get layoutParent { - var p = parent; - while (p != null) { - if (p is LayoutComponent) { - return p; - } - p = p.parent; - } - return artboard; - } -} - -class LayoutAnimationData { - double elapsedSeconds = 0; - AABB fromBounds; - AABB toBounds; - LayoutAnimationData(this.fromBounds, this.toBounds); -} - -class LayoutComponent extends LayoutComponentBase with ShapePaintContainer { - bool _forceUpdateLayoutBounds = false; - - LayoutComponentStyle? _style; - LayoutComponentStyle? get style => _style; - set style(LayoutComponentStyle? style) { - _style = style; - styleId = style?.id ?? Core.missingId; - if (style != null) { - setupStyle(style); - } - } - - // Layout Engine provides these - final LayoutStyle _layoutStyle = LayoutStyle.make(); - LayoutStyle get layoutStyle => _layoutStyle; - final LayoutNode _layoutNode = LayoutNode.make(); - LayoutNode get layoutNode => _layoutNode; - - LayoutAnimationData animationData = LayoutAnimationData(AABB(), AABB()); - - KeyFrameInterpolator? _inheritedInterpolator; - LayoutStyleInterpolation? _inheritedInterpolation; - double _inheritedInterpolationTime = 0; - - LayoutAnimationStyle get animationStyle => - style?.animationStyle ?? LayoutAnimationStyle.none; - - KeyFrameInterpolator? get interpolator { - switch (style?.animationStyle) { - case LayoutAnimationStyle.inherit: - return _inheritedInterpolator ?? style?.interpolator; - case LayoutAnimationStyle.custom: - return style?.interpolator; - default: - return null; - } - } - - LayoutStyleInterpolation get interpolation { - var defaultStyle = LayoutStyleInterpolation.hold; - switch (style?.animationStyle) { - case LayoutAnimationStyle.inherit: - return _inheritedInterpolation ?? style?.interpolation ?? defaultStyle; - case LayoutAnimationStyle.custom: - return style?.interpolation ?? defaultStyle; - default: - return defaultStyle; - } - } - - double get interpolationTime { - switch (style?.animationStyle) { - case LayoutAnimationStyle.inherit: - return _inheritedInterpolationTime; - case LayoutAnimationStyle.custom: - return style?.interpolationTime ?? 0; - default: - return 0; - } - } - - void cascadeAnimationStyle( - LayoutStyleInterpolation inheritedInterpolation, - KeyFrameInterpolator? inheritedInterpolator, - double inheritedInterpolationTime) { - if (style?.animationStyle == LayoutAnimationStyle.inherit) { - setInheritedInterpolation(inheritedInterpolation, inheritedInterpolator, - inheritedInterpolationTime); - } else { - clearInheritedInterpolation(); - } - forEachChild((child) { - if (child is LayoutComponent) { - child.cascadeAnimationStyle( - interpolation, interpolator, interpolationTime); - } - return false; - }); - } - - // Parent layout component can push their interpolation into the child layout - // which may be more performant than having the child look up the tree - void setInheritedInterpolation(LayoutStyleInterpolation interpolation, - KeyFrameInterpolator? interpolator, double interpolationTime) { - _inheritedInterpolation = interpolation; - _inheritedInterpolator = interpolator; - _inheritedInterpolationTime = interpolationTime; - } - - void clearInheritedInterpolation() { - _inheritedInterpolation = null; - _inheritedInterpolator = null; - _inheritedInterpolationTime = 0; - } - - bool get animates { - return style?.positionType == LayoutPosition.relative && - style?.animationStyle != LayoutAnimationStyle.none && - interpolation != LayoutStyleInterpolation.hold && - interpolationTime > 0; - } - - @override - void onPaintMutatorChanged(ShapePaintMutator mutator) { - // The transform affects stroke property may have changed as we have a new - // mutator. - paintChanged(); - } - - @override - void onStrokesChanged() => paintChanged(); - - @override - void onFillsChanged() => paintChanged(); - - void paintChanged() { - addDirt(ComponentDirt.path); - - // Add world transform dirt to the direct dependents (don't recurse) as - // things like ClippingShape directly depend on their referenced Shape. This - // allows them to recompute any stored values which can change when the - // transformAffectsStroke property changes (whether the path is in world - // space or not). Consider using a different dirt type if this pattern is - // repeated. - for (final d in dependents) { - d.addDirt(ComponentDirt.worldTransform); - } - } - - void markLayoutNodeDirty() { - _layoutNode.markDirty(); - artboard?.markLayoutDirty(this); - } - - void markLayoutStyleDirty() { - clearInheritedInterpolation(); - addDirt(ComponentDirt.layoutStyle); - if (this != artboard) { - artboard?.markLayoutStyleDirty(); - } - } - - @override - bool isValidParent(Component parent) => parent is LayoutComponent; - - @override - void changeArtboard(Artboard? value) { - super.changeArtboard(value); - artboard?.markLayoutDirty(this); - if (parent is LayoutComponent) { - (parent as LayoutComponent).syncLayoutChildren(); - } - } - - @override - void clipChanged(bool from, bool to) => markLayoutNodeDirty(); - - @override - void heightChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void widthChanged(double from, double to) => markLayoutNodeDirty(); - - @override - void styleIdChanged(int from, int to) { - style = context.resolve(to); - markLayoutStyleDirty(); - markLayoutNodeDirty(); - } - - bool advance(double elapsedSeconds) { - return _applyInterpolation(elapsedSeconds); - } - - bool _applyInterpolation(double elapsedSeconds) { - if (!animates || style == null || animationData.toBounds == layoutBounds) { - return false; - } - if (animationData.elapsedSeconds >= interpolationTime) { - _layoutLocation = - Offset(animationData.toBounds.left, animationData.toBounds.top); - _layoutSize = - Size(animationData.toBounds.width, animationData.toBounds.height); - animationData.elapsedSeconds = 0; - markWorldTransformDirty(); - return false; - } - double f = 1; - if (interpolationTime > 0) { - f = animationData.elapsedSeconds / interpolationTime; - } - - bool needsAdvance = false; - var left = _layoutLocation.dx; - var top = _layoutLocation.dy; - var width = _layoutSize.width; - var height = _layoutSize.height; - if (animationData.toBounds.left != left || - animationData.toBounds.top != top) { - if (interpolation == LayoutStyleInterpolation.linear) { - left = animationData.fromBounds.left + - f * (animationData.toBounds.left - animationData.fromBounds.left); - top = animationData.fromBounds.top + - f * (animationData.toBounds.top - animationData.fromBounds.top); - } else { - if (interpolator != null) { - left = interpolator!.transformValue( - animationData.fromBounds.left, animationData.toBounds.left, f); - top = interpolator!.transformValue( - animationData.fromBounds.top, animationData.toBounds.top, f); - } - } - needsAdvance = true; - _layoutLocation = Offset(left, top); - markWorldTransformDirty(); - } - if (animationData.toBounds.width != width || - animationData.toBounds.height != height) { - if (interpolation == LayoutStyleInterpolation.linear) { - width = animationData.fromBounds.width + - f * (animationData.toBounds.width - animationData.fromBounds.width); - height = animationData.fromBounds.height + - f * - (animationData.toBounds.height - - animationData.fromBounds.height); - } else { - if (interpolator != null) { - width = interpolator!.transformValue( - animationData.fromBounds.width, animationData.toBounds.width, f); - height = interpolator!.transformValue(animationData.fromBounds.height, - animationData.toBounds.height, f); - } - } - needsAdvance = true; - _layoutSize = Size(width, height); - markWorldTransformDirty(); - } - - animationData.elapsedSeconds += elapsedSeconds; - if (needsAdvance) { - markLayoutNodeDirty(); - } - return needsAdvance; - } - - @override - void update(int dirt) { - if (dirt & ComponentDirt.worldTransform != 0) { - Mat2D parentWorld = parent is WorldTransformComponent - ? (parent as WorldTransformComponent).worldTransform - : Mat2D(); - - var transform = Mat2D(); - transform[4] = _layoutLocation.dx; - transform[5] = _layoutLocation.dy; - - Mat2D.multiply(worldTransform, parentWorld, transform); - } - } - - void syncStyle() { - if (_style == null) { - return; - } - _syncStyle(_style!); - } - - void _syncStyle(LayoutComponentStyle style) { - bool setIntrinsicWidth = false; - bool setIntrinsicHeight = false; - if (style.intrinsicallySized && - (style.widthUnits == LayoutUnit.auto || - style.heightUnits == LayoutUnit.auto)) { - bool foundIntrinsicSize = false; - Size intrinsicSize = Size.zero; - forEachChild((child) { - if (child is LayoutComponent) { - return false; - } - if (child is Sizable) { - var minSize = Size( - style.minWidthUnits == LayoutUnit.point ? style.minWidth : 0, - style.minHeightUnits == LayoutUnit.point ? style.minHeight : 0, - ); - var maxSize = Size( - style.maxWidthUnits == LayoutUnit.point - ? style.maxWidth - : double.infinity, - style.maxHeightUnits == LayoutUnit.point - ? style.maxHeight - : double.infinity, - ); - - var size = (child as Sizable).computeIntrinsicSize(minSize, maxSize); - intrinsicSize = Size(max(intrinsicSize.width, size.width), - max(intrinsicSize.height, size.height)); - foundIntrinsicSize = true; - } - return true; - }); - if (foundIntrinsicSize) { - if (style.widthUnits == LayoutUnit.auto) { - setIntrinsicWidth = true; - layoutStyle.setDimension(LayoutDimension.width, - LayoutValue(unit: LayoutUnit.point, value: intrinsicSize.width)); - } - if (style.heightUnits == LayoutUnit.auto) { - setIntrinsicHeight = true; - layoutStyle.setDimension(LayoutDimension.height, - LayoutValue(unit: LayoutUnit.point, value: intrinsicSize.height)); - } - } - } - if (!setIntrinsicWidth) { - layoutStyle.setDimension(LayoutDimension.width, - LayoutValue(unit: style.widthUnits, value: width)); - } - if (!setIntrinsicHeight) { - layoutStyle.setDimension(LayoutDimension.height, - LayoutValue(unit: style.heightUnits, value: height)); - } - - final isRow = [ - LayoutFlexDirection.row, - LayoutFlexDirection.rowReverse, - ].contains(layoutParent?.style?.flexDirection); - switch (style.widthScaleType) { - case ScaleType.fixed: - if (isRow) { - layoutStyle.flexGrow = 0; - } - break; - case ScaleType.fill: - isRow - ? layoutStyle.flexGrow = 1 - : layoutStyle.alignSelf = LayoutAlign.stretch; - break; - case ScaleType.hug: - isRow - ? layoutStyle.flexGrow = 0 - : layoutStyle.alignSelf = LayoutAlign.auto; - break; - default: - break; - } - final isColumn = [ - LayoutFlexDirection.column, - LayoutFlexDirection.columnReverse, - ].contains(layoutParent?.style?.flexDirection); - switch (style.heightScaleType) { - case ScaleType.fixed: - if (isColumn) { - layoutStyle.flexGrow = 0; - } - break; - case ScaleType.fill: - isColumn - ? layoutStyle.flexGrow = 1 - : layoutStyle.alignSelf = LayoutAlign.stretch; - break; - case ScaleType.hug: - isColumn - ? layoutStyle.flexGrow = 0 - : layoutStyle.alignSelf = LayoutAlign.auto; - break; - default: - break; - } - - final isRowForAlignment = [ - LayoutFlexDirection.row, - LayoutFlexDirection.rowReverse, - ].contains(style.flexDirection); - switch (style.alignmentType) { - case LayoutAlignmentType.topLeft: - case LayoutAlignmentType.topCenter: - case LayoutAlignmentType.topRight: - case LayoutAlignmentType.spaceBetweenStart: - if (isRowForAlignment) { - layoutStyle.alignItems = LayoutAlign.flexStart; - } else { - layoutStyle.justifyContent = LayoutJustify.flexStart; - } - break; - case LayoutAlignmentType.centerLeft: - case LayoutAlignmentType.center: - case LayoutAlignmentType.centerRight: - case LayoutAlignmentType.spaceBetweenCenter: - if (isRowForAlignment) { - layoutStyle.alignItems = LayoutAlign.center; - } else { - layoutStyle.justifyContent = LayoutJustify.center; - } - break; - case LayoutAlignmentType.bottomLeft: - case LayoutAlignmentType.bottomCenter: - case LayoutAlignmentType.bottomRight: - case LayoutAlignmentType.spaceBetweenEnd: - if (isRowForAlignment) { - layoutStyle.alignItems = LayoutAlign.flexEnd; - } else { - layoutStyle.justifyContent = LayoutJustify.flexEnd; - } - break; - } - switch (style.alignmentType) { - case LayoutAlignmentType.topLeft: - case LayoutAlignmentType.centerLeft: - case LayoutAlignmentType.bottomLeft: - if (isRowForAlignment) { - layoutStyle.justifyContent = LayoutJustify.flexStart; - } else { - layoutStyle.alignItems = LayoutAlign.flexStart; - } - break; - case LayoutAlignmentType.topCenter: - case LayoutAlignmentType.center: - case LayoutAlignmentType.bottomCenter: - if (isRowForAlignment) { - layoutStyle.justifyContent = LayoutJustify.center; - } else { - layoutStyle.alignItems = LayoutAlign.center; - } - break; - case LayoutAlignmentType.topRight: - case LayoutAlignmentType.centerRight: - case LayoutAlignmentType.bottomRight: - if (isRowForAlignment) { - layoutStyle.justifyContent = LayoutJustify.flexEnd; - } else { - layoutStyle.alignItems = LayoutAlign.flexEnd; - } - break; - case LayoutAlignmentType.spaceBetweenStart: - case LayoutAlignmentType.spaceBetweenCenter: - case LayoutAlignmentType.spaceBetweenEnd: - layoutStyle.justifyContent = LayoutJustify.spaceBetween; - break; - } - - layoutStyle.setMinDimension(LayoutDimension.width, - LayoutValue(unit: style.minWidthUnits, value: style.minWidth)); - layoutStyle.setMinDimension(LayoutDimension.height, - LayoutValue(unit: style.minHeightUnits, value: style.minHeight)); - layoutStyle.setMaxDimension(LayoutDimension.width, - LayoutValue(unit: style.maxWidthUnits, value: style.maxWidth)); - layoutStyle.setMaxDimension(LayoutDimension.height, - LayoutValue(unit: style.maxHeightUnits, value: style.maxHeight)); - - layoutStyle.setGap( - LayoutGutter.column, - LayoutValue( - unit: style.gapHorizontalUnits, value: style.gapHorizontal)); - layoutStyle.setGap(LayoutGutter.row, - LayoutValue(unit: style.gapVerticalUnits, value: style.gapVertical)); - - layoutStyle.setBorder(LayoutEdge.left, - LayoutValue(unit: style.borderLeftUnits, value: style.borderLeft)); - layoutStyle.setBorder(LayoutEdge.top, - LayoutValue(unit: style.borderTopUnits, value: style.borderTop)); - layoutStyle.setBorder(LayoutEdge.right, - LayoutValue(unit: style.borderRightUnits, value: style.borderRight)); - layoutStyle.setBorder(LayoutEdge.bottom, - LayoutValue(unit: style.borderBottomUnits, value: style.borderBottom)); - - layoutStyle.setMargin(LayoutEdge.left, - LayoutValue(unit: style.marginLeftUnits, value: style.marginLeft)); - layoutStyle.setMargin(LayoutEdge.top, - LayoutValue(unit: style.marginTopUnits, value: style.marginTop)); - layoutStyle.setMargin(LayoutEdge.right, - LayoutValue(unit: style.marginRightUnits, value: style.marginRight)); - layoutStyle.setMargin(LayoutEdge.bottom, - LayoutValue(unit: style.marginBottomUnits, value: style.marginBottom)); - - layoutStyle.setPadding(LayoutEdge.left, - LayoutValue(unit: style.paddingLeftUnits, value: style.paddingLeft)); - layoutStyle.setPadding(LayoutEdge.top, - LayoutValue(unit: style.paddingTopUnits, value: style.paddingTop)); - layoutStyle.setPadding(LayoutEdge.right, - LayoutValue(unit: style.paddingRightUnits, value: style.paddingRight)); - layoutStyle.setPadding( - LayoutEdge.bottom, - LayoutValue( - unit: style.paddingBottomUnits, value: style.paddingBottom)); - - layoutStyle.setPosition(LayoutEdge.left, - LayoutValue(unit: style.positionLeftUnits, value: style.positionLeft)); - layoutStyle.setPosition(LayoutEdge.top, - LayoutValue(unit: style.positionTopUnits, value: style.positionTop)); - layoutStyle.setPosition( - LayoutEdge.right, - LayoutValue( - unit: style.positionRightUnits, value: style.positionRight)); - layoutStyle.setPosition( - LayoutEdge.bottom, - LayoutValue( - unit: style.positionBottomUnits, value: style.positionBottom)); - - layoutStyle.display = style.display; - layoutStyle.positionType = style.positionType; - layoutStyle.flex = style.flex; - //layoutStyle.flexGrow = style.flexGrow; - //layoutStyle.flexShrink = style.flexShrink; - //layoutStyle.flexBasis = style.flexBasis; - layoutStyle.flexDirection = style.flexDirection; - layoutStyle.flexWrap = style.flexWrap; - //layoutStyle.alignItems = style.alignItems; - //layoutStyle.alignContent = style.alignContent; - //layoutStyle.alignSelf = style.alignSelf; - //layoutStyle.justifyContent = style.justifyContent; - - layoutNode.setStyle(layoutStyle); - } - - void syncLayoutChildren() { - final layoutChildren = children.whereType(); - layoutNode.clearChildren(); - for (var i = 0; i < layoutChildren.length; i++) { - layoutNode.insertChild(layoutChildren.elementAt(i).layoutNode, i); - } - } - - @override - void onAdded() { - super.onAdded(); - markLayoutStyleDirty(); - markLayoutNodeDirty(); - syncLayoutChildren(); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - markLayoutStyleDirty(); - markLayoutNodeDirty(); - style = context.resolve(styleId); - } - - void setupStyle(LayoutComponentStyle style) { - appendChild(style); - style.valueChanged.addListener(styleValueChanged); - style.interpolationChanged.addListener(styleInterpolationChanged); - } - - Offset _layoutLocation = Offset.zero; - Size _layoutSize = Size.zero; - - bool hasLayoutMeasurements() { - return _layoutLocation != Offset.zero || _layoutSize != Size.zero; - } - - AABB get localBounds { - return AABB.fromValues( - 0, - 0, - _layoutSize.width, - _layoutSize.height, - ); - } - - AABB get layoutBounds { - return AABB.fromValues( - _layoutLocation.dx, - _layoutLocation.dy, - _layoutLocation.dx + _layoutSize.width, - _layoutLocation.dy + _layoutSize.height, - ); - } - - AABB get worldBounds { - return AABB.fromValues( - worldTransform[4], - worldTransform[5], - worldTransform[4] + _layoutSize.width, - worldTransform[5] + _layoutSize.height, - ); - } - - @override - AABB get constraintBounds => localBounds; - - void propagateSize() { - // add option for this. - if (artboard == this) { - return; - } - forEachChild((child) { - // Don't propagate down to children of nested layout components - // or groups - if (child is LayoutComponent || child.coreType == NodeBase.typeKey) { - return false; - } - if (child is Sizable) { - (child as Sizable).controlSize(animates && _layoutSize == Size.zero - ? Size(animationData.toBounds.width, animationData.toBounds.height) - : _layoutSize); - } - return true; - }); - } - - void updateLayoutBounds() { - final newLayoutBounds = AABB.fromValues( - layoutNode.layout.left, - layoutNode.layout.top, - layoutNode.layout.left + layoutNode.layout.width, - layoutNode.layout.top + layoutNode.layout.height); - if (animates) { - if (!AABB.areEqual(animationData.toBounds, newLayoutBounds) || - _forceUpdateLayoutBounds) { - // This is where we want to set the start/end data for the animation - // As we advance the animation, update _layoutLocation and _layoutSize - animationData.fromBounds = layoutBounds; - animationData.toBounds = newLayoutBounds; - propagateSize(); - markWorldTransformDirty(); - } - } else if (!AABB.areEqual(layoutBounds, newLayoutBounds) || - _forceUpdateLayoutBounds) { - _layoutLocation = Offset(newLayoutBounds.left, newLayoutBounds.top); - _layoutSize = Size(newLayoutBounds.width, newLayoutBounds.height); - propagateSize(); - markWorldTransformDirty(); - } - _forceUpdateLayoutBounds = false; - } - - void styleValueChanged() { - markLayoutNodeDirty(); - } - - // Only changes to layout animation styles mark style dirty - // In the future we may want other styles to cascade down to child layouts - void styleInterpolationChanged() { - markLayoutStyleDirty(); - } - - void _removeLayoutNode() { - markLayoutStyleDirty(); - var parent = this.parent; - if (parent is LayoutComponent) { - parent.markLayoutNodeDirty(); - } - } - - @override - void onRemoved() { - _style?.valueChanged.removeListener(styleValueChanged); - _style?.interpolationChanged.removeListener(styleInterpolationChanged); - _removeLayoutNode(); - super.onRemoved(); - } - - @override - void buildDependencies() { - super.buildDependencies(); - parent?.addDependent(this); - } -} diff --git a/lib/src/rive_core/nested_animation.dart b/lib/src/rive_core/nested_animation.dart deleted file mode 100644 index 5c3a0e7..0000000 --- a/lib/src/rive_core/nested_animation.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:rive/src/generated/nested_animation_base.dart'; -import 'package:rive/src/rive_core/animation/animation.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; - -export 'package:rive/src/generated/nested_animation_base.dart'; - -abstract class NestedAnimation - extends NestedAnimationBase { - NestedArtboard? get nestedArtboard => - parent is NestedArtboard ? parent as NestedArtboard : null; - - @override - void animationIdChanged(int from, int to) {} - - bool get isEnabled; - - /// Returns true when the NestedAnimation needs to keep advancing. Returning - /// false doesn't guarantee another advance won't be called, it just means - /// that it's no longer necessary to call advance again as the reesults will - /// be the same. - bool advance(double elapsedSeconds, MountedArtboard mountedArtboard); - - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/nested_artboard.dart b/lib/src/rive_core/nested_artboard.dart deleted file mode 100644 index 5b2becb..0000000 --- a/lib/src/rive_core/nested_artboard.dart +++ /dev/null @@ -1,355 +0,0 @@ -import 'dart:math'; -import 'dart:ui'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/nested_artboard_base.dart'; -import 'package:rive/src/rive_core/animation/nested_remap_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_simple_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/backboard.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind.dart'; -import 'package:rive/src/rive_core/data_bind/data_context.dart'; -import 'package:rive/src/rive_core/nested_animation.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/nested_artboard_base.dart'; - -enum NestedArtboardFitType { - // ignore: lines_longer_than_80_chars - fill, // Default value - scales to fill available view without maintaining aspect ratio - contain, - cover, - fitWidth, - fitHeight, - resizeArtboard, - none, -} - -enum NestedArtboardAlignmentType { - center, // Default value - topLeft, - topCenter, - topRight, - centerLeft, - centerRight, - bottomLeft, - bottomCenter, - bottomRight, -} - -/// Represents the nested Artboard that'll actually be mounted and placed into -/// the [NestedArtboard] component. -abstract class MountedArtboard { - void draw(Canvas canvas); - Mat2D get worldTransform; - set worldTransform(Mat2D value); - AABB get bounds; - double get renderOpacity; - set renderOpacity(double value); - bool advance(double seconds, {bool nested}); - set artboardWidth(double width); - double get artboardWidth; - set artboardHeight(double height); - double get artboardHeight; - double get originalArtboardWidth; - double get originalArtboardHeight; - void artboardWidthOverride(double width, int widthUnitValue, bool isRow); - void artboardHeightOverride(double height, int heightUnitValue, bool isRow); - void artboardWidthIntrinsicallySizeOverride(bool intrinsic); - void artboardHeightIntrinsicallySizeOverride(bool intrinsic); - void updateLayoutBounds(bool animate); - void dispose(); - void bindViewModelInstance(ViewModelInstance viewModelInstance, - DataContext? dataContextValue, bool isRoot); - void internalDataContext(DataContext dataContextValue, - DataContext? parentDataContext, bool isRoot); - void populateDataBinds(List globalDataBinds); -} - -class NestedArtboard extends NestedArtboardBase implements Sizable { - /// [NestedAnimation]s applied to this [NestedArtboard]. - final List _animations = []; - Iterable get animations => _animations; - - List dataBindPath = []; - - NestedArtboardFitType get fitType => NestedArtboardFitType.values[fit]; - NestedArtboardAlignmentType get alignmentType => - NestedArtboardAlignmentType.values[alignment]; - - bool get hasNestedStateMachine => - _animations.any((animation) => animation is NestedStateMachine); - - List get nestedStateMachines => - _animations.whereType().toList(growable: false); - - /// Used by nested animations/state machines to let the nesting artboard know - /// it needs to redraw/advance time. - void markNeedsAdvance() => context.markNeedsAdvance(); - - MountedArtboard? _mountedArtboard; - MountedArtboard? get mountedArtboard => _mountedArtboard; - set mountedArtboard(MountedArtboard? value) { - if (value == _mountedArtboard) { - return; - } - _mountedArtboard?.dispose(); - _mountedArtboard = value; - _updateMountedTransform(); - _mountedArtboard?.renderOpacity = renderOpacity; - _mountedArtboard?.advance(0); - addDirt(ComponentDirt.paint); - - if (cachedSize != null) { - controlSize(cachedSize!); - } - } - - @override - void onRemoved() { - super.onRemoved(); - _mountedArtboard?.dispose(); - } - - @override - void artboardIdChanged(int from, int to) {} - - @override - void dataBindPathIdsChanged(List from, List to) {} - - @override - void fitChanged(int from, int to) { - _updateMountedTransform(); - } - - @override - void alignmentChanged(int from, int to) { - _updateMountedTransform(); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - var reader = BinaryReader.fromList(dataBindPathIds); - while (!reader.isEOF) { - dataBindPath.add(reader.readVarUint()); - } - } - - @override - void childAdded(Component child) { - super.childAdded(child); - switch (child.coreType) { - case NestedRemapAnimationBase.typeKey: - case NestedSimpleAnimationBase.typeKey: - case NestedStateMachineBase.typeKey: - _animations.add(child as NestedAnimation); - break; - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - switch (child.coreType) { - case NestedRemapAnimationBase.typeKey: - case NestedSimpleAnimationBase.typeKey: - case NestedStateMachineBase.typeKey: - _animations.remove(child as NestedAnimation); - - break; - } - } - - // When used with layouts, we cache the size of the NestedArtboard - // because the mountedArtboard gets replaced when changes are made to the - // NestedArtboard's artboard, and we need to maintain size when that happens - Size? cachedSize; - - @override - Size computeIntrinsicSize(Size min, Size max) { - final bounds = mountedArtboard?.bounds; - if (bounds == null) { - return min; - } - return Size(bounds.width * scaleX, bounds.height * scaleY); - } - - @override - void controlSize(Size size) { - cachedSize = size; - if (mountedArtboard == null) { - return; - } - // Since NestedArtboards only use scale, not width/height, we have to do - // a bit of a conversion here. There may be a better way. - - scaleX = size.width / mountedArtboard!.originalArtboardWidth; - scaleY = size.height / mountedArtboard!.originalArtboardHeight; - - updateTransform(); - updateWorldTransform(); - } - - void _updateMountedTransform() { - var mountedArtboard = _mountedArtboard; - if (mountedArtboard != null) { - Mat2D transform = Mat2D(); - Mat2D.copy(transform, worldTransform); - if (fitType == NestedArtboardFitType.resizeArtboard) { - // resizeArtboard is a special case because we actually change the - // width/height of the RuntimeArtboard rather than scaling it - mountedArtboard.artboardWidth = - scaleX * mountedArtboard.originalArtboardWidth; - mountedArtboard.artboardHeight = - scaleY * mountedArtboard.originalArtboardHeight; - double computedScaleX = scaleX == 0 ? 0 : (1 / scaleX); - double computedScaleY = scaleY == 0 ? 0 : (1 / scaleY); - Mat2D.scaleByValues(transform, computedScaleX, computedScaleY); - } else { - // For all others we scale - mountedArtboard.artboardWidth = mountedArtboard.originalArtboardWidth; - mountedArtboard.artboardHeight = mountedArtboard.originalArtboardHeight; - double? scaleMultiplier; - switch (fitType) { - case NestedArtboardFitType.cover: - scaleMultiplier = max(scaleX, scaleY); - break; - case NestedArtboardFitType.contain: - scaleMultiplier = min(scaleX, scaleY); - break; - case NestedArtboardFitType.fitWidth: - scaleMultiplier = scaleX; - break; - case NestedArtboardFitType.fitHeight: - scaleMultiplier = scaleY; - break; - case NestedArtboardFitType.none: - scaleMultiplier = 1; - break; - default: - break; - } - if (scaleMultiplier != null) { - double computedScaleX = - scaleX == 0 ? 0 : (1 / scaleX) * scaleMultiplier; - double computedScaleY = - scaleY == 0 ? 0 : (1 / scaleY) * scaleMultiplier; - Mat2D.scaleByValues(transform, computedScaleX, computedScaleY); - // Only do alignment if we are not using fit type Fill - double translateX = 0; - double translateY = 0; - double artboardWidth = mountedArtboard.originalArtboardWidth; - double artboardHeight = mountedArtboard.originalArtboardHeight; - // Adjust x position if we're aligned center or right - if (alignmentType == NestedArtboardAlignmentType.topCenter || - alignmentType == NestedArtboardAlignmentType.center || - alignmentType == NestedArtboardAlignmentType.bottomCenter) { - translateX = - (artboardWidth * scaleX - artboardWidth * scaleMultiplier) / 2; - } else if (alignmentType == NestedArtboardAlignmentType.topRight || - alignmentType == NestedArtboardAlignmentType.centerRight || - alignmentType == NestedArtboardAlignmentType.bottomRight) { - translateX = - artboardWidth * scaleX - artboardWidth * scaleMultiplier; - } - // Adjust y position if we're aligned center or bottom - if (alignmentType == NestedArtboardAlignmentType.centerLeft || - alignmentType == NestedArtboardAlignmentType.center || - alignmentType == NestedArtboardAlignmentType.centerRight) { - translateY = - (artboardHeight * scaleY - artboardHeight * scaleMultiplier) / - 2; - } else if (alignmentType == NestedArtboardAlignmentType.bottomLeft || - alignmentType == NestedArtboardAlignmentType.bottomCenter || - alignmentType == NestedArtboardAlignmentType.bottomRight) { - translateY = - artboardHeight * scaleY - artboardHeight * scaleMultiplier; - } - if (translateX != 0) { - transform[4] += translateX; - } - if (translateY != 0) { - transform[5] += translateY; - } - } - } - mountedArtboard.worldTransform = transform; - } - } - - /// Convert a world position to local for the mounted artboard. - Vec2D? worldToLocal(Vec2D position) { - var mounted = mountedArtboard; - if (mounted == null) { - return null; - } - var toMountedArtboard = Mat2D(); - if (!Mat2D.invert(toMountedArtboard, mounted.worldTransform)) { - return null; - } - return Vec2D.transformMat2D(Vec2D(), position, toMountedArtboard); - } - - @override - void updateWorldTransform() { - super.updateWorldTransform(); - _updateMountedTransform(); - } - - bool advance(double elapsedSeconds) { - if (mountedArtboard == null || isCollapsed) { - return false; - } - - bool keepGoing = false; - for (final animation in _animations) { - if (animation.isEnabled) { - if (animation.advance(elapsedSeconds, mountedArtboard!)) { - keepGoing = true; - } - } - } - if (mountedArtboard!.advance(elapsedSeconds)) { - keepGoing = true; - } - return keepGoing; - } - - @override - void update(int dirt) { - super.update(dirt); - // RenderOpacity gets updated with the worldTransform (accumulates through - // hierarchy), so if we see worldTransform is dirty, update our internal - // render opacities. - if (dirt & ComponentDirt.worldTransform != 0) { - mountedArtboard?.renderOpacity = renderOpacity; - } - } - - @override - void draw(Canvas canvas) { - bool clipped = clip(canvas); - mountedArtboard?.draw(canvas); - - if (clipped) { - canvas.restore(); - } - } - - @override - bool import(ImportStack stack) { - var backboardImporter = - stack.latest(BackboardBase.typeKey); - if (backboardImporter != null) { - backboardImporter.addNestedArtboard(this); - } - - return super.import(stack); - } -} diff --git a/lib/src/rive_core/node.dart b/lib/src/rive_core/node.dart deleted file mode 100644 index 91ee79c..0000000 --- a/lib/src/rive_core/node.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:rive/src/generated/node_base.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/node_base.dart'; - -class _UnknownNode extends Node {} - -class Node extends NodeBase { - static final Node unknown = _UnknownNode(); - - /// Sets the position of the Node - set translation(Vec2D pos) { - x = pos.x; - y = pos.y; - } - - @override - void xChanged(double from, double to) { - markTransformDirty(); - } - - @override - void yChanged(double from, double to) { - markTransformDirty(); - } -} diff --git a/lib/src/rive_core/notifier.dart b/lib/src/rive_core/notifier.dart deleted file mode 100644 index b046ab5..0000000 --- a/lib/src/rive_core/notifier.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter/foundation.dart'; - -// Just a way to get around the protected notifyListeners so we can use trigger -// multiple events from a single object. -class Notifier extends ChangeNotifier { - void notify() => notifyListeners(); -} diff --git a/lib/src/rive_core/open_url_event.dart b/lib/src/rive_core/open_url_event.dart deleted file mode 100644 index b2bbfb9..0000000 --- a/lib/src/rive_core/open_url_event.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:rive/src/generated/open_url_event_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/open_url_target.dart'; - -export 'package:rive/src/generated/open_url_event_base.dart'; - -class OpenUrlEvent extends OpenUrlEventBase { - @override - void update(int dirt) {} - - @override - void changeArtboard(Artboard? value) { - artboard?.internalRemoveEvent(this); - super.changeArtboard(value); - artboard?.internalAddEvent(this); - } - - @override - void targetValueChanged(int from, int to) {} - - @override - void urlChanged(String from, String to) {} - - OpenUrlTarget get target => OpenUrlTarget.values[targetValue]; - set target(OpenUrlTarget value) => targetValue = value.index; -} diff --git a/lib/src/rive_core/open_url_target.dart b/lib/src/rive_core/open_url_target.dart deleted file mode 100644 index 2c7eefe..0000000 --- a/lib/src/rive_core/open_url_target.dart +++ /dev/null @@ -1,2 +0,0 @@ -/// Open URL event target types. -enum OpenUrlTarget { blank, parent, self, top } diff --git a/lib/src/rive_core/rive_animation_controller.dart b/lib/src/rive_core/rive_animation_controller.dart deleted file mode 100644 index 13b379c..0000000 --- a/lib/src/rive_core/rive_animation_controller.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/foundation.dart'; - -/// Abstraction for receiving a per frame callback while isPlaying is true to -/// apply animation based on an elapsed amount of time. -abstract class RiveAnimationController { - final _isActive = ValueNotifier(false); - ValueListenable get isActiveChanged => _isActive; - - bool get isActive => _isActive.value; - set isActive(bool value) { - if (_isActive.value != value) { - _isActive.value = value; - if (value) { - onActivate(); - } else { - onDeactivate(); - } - } - } - - @protected - void onActivate() {} - @protected - void onDeactivate() {} - - /// Apply animation to objects registered in [core]. Note that a [core] - /// context is specified as animations can be applied to instances. - void apply(T core, double elapsedSeconds); - - bool init(T core) => true; - void dispose() {} -} diff --git a/lib/src/rive_core/rive_core_singleton_test.dart b/lib/src/rive_core/rive_core_singleton_test.dart deleted file mode 100644 index 40ae810..0000000 --- a/lib/src/rive_core/rive_core_singleton_test.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:rive/src/rive_core/animation/linear_animation.dart'; - -class RiveCoreSingletonTest { - static final RiveCoreSingletonTest _instance = - RiveCoreSingletonTest._internal(); - - final double num = 1.23; - // bool isDebug = false; - bool isAnimation = false; - bool isArtboard = false; - bool isLayer = false; - bool isColorType = false; - int currentTime = 0; - LinearAnimation? la; - - // using a factory is important - // because it promises to return _an_ object of this type - // but it doesn't promise to make a new one. - factory RiveCoreSingletonTest() { - return _instance; - } - - // This named constructor is the "real" constructor - // It'll be called exactly once, by the static property assignment above - // it's also private, so it can only be called in this class - RiveCoreSingletonTest._internal() { - // initialization logic - } - - // This named constructor is the "real" constructor - // It'll be called exactly once, by the static property assignment above - // it's also private, so it can only be called in this class - bool isDebug() { - return isArtboard && isAnimation && isLayer; - } -} diff --git a/lib/src/rive_core/runtime/exceptions/rive_format_error_exception.dart b/lib/src/rive_core/runtime/exceptions/rive_format_error_exception.dart deleted file mode 100644 index e90bb00..0000000 --- a/lib/src/rive_core/runtime/exceptions/rive_format_error_exception.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:meta/meta.dart'; - -/// Thrown when a file being read doesn't match the Rive format. -@immutable -class RiveFormatErrorException implements Exception { - final String cause; - const RiveFormatErrorException(this.cause); -} diff --git a/lib/src/rive_core/runtime/exceptions/rive_unsupported_version_exception.dart b/lib/src/rive_core/runtime/exceptions/rive_unsupported_version_exception.dart deleted file mode 100644 index 2c0ebf4..0000000 --- a/lib/src/rive_core/runtime/exceptions/rive_unsupported_version_exception.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:meta/meta.dart'; - -/// Error that occurs when a file being loaded doesn't match the importer's -/// supported version. -@immutable -class RiveUnsupportedVersionException implements Exception { - final int majorVersion; - final int minorVersion; - final int fileMajorVersion; - final int fileMinorVersion; - const RiveUnsupportedVersionException(this.majorVersion, this.minorVersion, - this.fileMajorVersion, this.fileMinorVersion); - - @override - String toString() { - return 'File contains version $fileMajorVersion.$fileMinorVersion. ' - 'This runtime supports version $majorVersion.$minorVersion'; - } -} diff --git a/lib/src/rive_core/runtime/runtime_header.dart b/lib/src/rive_core/runtime/runtime_header.dart deleted file mode 100644 index 17ea90d..0000000 --- a/lib/src/rive_core/runtime/runtime_header.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/runtime/exceptions/rive_format_error_exception.dart'; -import 'package:rive/src/rive_core/runtime/exceptions/rive_unsupported_version_exception.dart'; -import 'package:rive_common/utilities.dart'; - -/// Stores the minor and major version of Rive. Versions with the same major -/// value are backwards and forwards compatible. -class RuntimeVersion { - final int major; - final int minor; - - const RuntimeVersion(this.major, this.minor); - String versionString() { - return '$major.$minor'; - } -} - -const riveVersion = RuntimeVersion(7, 0); - -class RuntimeHeader { - static const String fingerprint = 'RIVE'; - final RuntimeVersion version; - - final int fileId; - - final HashMap propertyToFieldIndex; - - RuntimeHeader({ - required this.fileId, - required this.version, - required this.propertyToFieldIndex, - }); - - /// Read the header from a binary [reader]. Specify [version] to check - /// compatibility while loading the header. You can also opt to provide null - /// to skip version checking. Note that in this case the header can only be - /// read if it's of a known major version (<= [riveVersion.major]). - factory RuntimeHeader.read( - BinaryReader reader, { - RuntimeVersion? version = riveVersion, - }) { - var fingerprint = RuntimeHeader.fingerprint.codeUnits; - - for (int i = 0; i < fingerprint.length; i++) { - if (reader.readUint8() != fingerprint[i]) { - throw const RiveFormatErrorException('Fingerprint doesn\'t match.'); - } - } - - int readMajorVersion = reader.readVarUint(); - int readMinorVersion = reader.readVarUint(); - - if (version == null && readMajorVersion > riveVersion.major) { - throw RiveUnsupportedVersionException(riveVersion.major, - riveVersion.minor, readMajorVersion, readMinorVersion); - } else if (version != null && readMajorVersion != version.major) { - throw RiveUnsupportedVersionException( - version.major, version.minor, readMajorVersion, readMinorVersion); - } - if (readMajorVersion == 6) { - reader.readVarUint(); - } - int fileId = reader.readVarUint(); - - var propertyFields = HashMap(); - - var propertyKeys = []; - for (int propertyKey = reader.readVarUint(); - propertyKey != 0; - propertyKey = reader.readVarUint()) { - propertyKeys.add(propertyKey); - } - int currentInt = 0; - int currentBit = 8; - for (final propertyKey in propertyKeys) { - if (currentBit == 8) { - currentInt = reader.readUint32(); - currentBit = 0; - } - int fieldIndex = (currentInt >> currentBit) & 3; - propertyFields[propertyKey] = fieldIndex; - currentBit += 2; - } - - return RuntimeHeader( - fileId: fileId, - version: RuntimeVersion(readMajorVersion, readMinorVersion), - propertyToFieldIndex: propertyFields, - ); - } -} diff --git a/lib/src/rive_core/shapes/clipping_shape.dart b/lib/src/rive_core/shapes/clipping_shape.dart deleted file mode 100644 index a4de57f..0000000 --- a/lib/src/rive_core/shapes/clipping_shape.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/clipping_shape_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/node.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; - -export 'package:rive/src/generated/shapes/clipping_shape_base.dart'; - -class ClippingShape extends ClippingShapeBase { - final Path clippingPath = Path(); - final List _shapes = []; - PathFillType get fillType => enumAt(PathFillType.values, fillRule); - set fillType(PathFillType type) => fillRule = type.index; - - Node _source = Node.unknown; - Node get source => _source; - set source(Node value) { - if (_source == value) { - return; - } - - _source = value; - sourceId = value.id; - } - - @override - void fillRuleChanged(int from, int to) { - // In the future, if clipOp can change at runtime (animation), we may want - // the shapes that use this as a clipping source to make them depend on this - // clipping shape so we can add dirt to them directly. - parent?.addDirt(ComponentDirt.clip, recurse: true); - - addDirt(ComponentDirt.path); - } - - @override - void sourceIdChanged(int from, int to) { - source = context.resolveWithDefault(to, Node.unknown); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - source = context.resolveWithDefault(sourceId, Node.unknown); - } - - @override - void buildDependencies() { - super.buildDependencies(); - _shapes.clear(); - _source.forAll((component) { - if (component is Shape) { - _shapes.add(component); - //component.addDependent(this); - component.pathComposer.addDependent(this); - } - return true; - }); - - // make sure we rebuild the clipping path. - addDirt(ComponentDirt.path); - } - - @override - void onRemoved() { - super.onRemoved(); - _shapes.clear(); - } - - @override - void update(int dirt) { - if (dirt & (ComponentDirt.worldTransform | ComponentDirt.path) != 0) { - // Build the clipping path as one of our dependent shapes changes or we - // added a shape. - clippingPath.reset(); - clippingPath.fillType = fillType; - for (final shape in _shapes) { - if (!shape.fillInWorld) { - clippingPath.addPath(shape.fillPath, Offset.zero, - matrix4: shape.worldTransform.mat4); - } else { - clippingPath.addPath(shape.fillPath, Offset.zero); - } - } - } - } - - @override - void isVisibleChanged(bool from, bool to) { - // Redraw - _source.addDirt(ComponentDirt.paint); - } -} diff --git a/lib/src/rive_core/shapes/contour_mesh_vertex.dart b/lib/src/rive_core/shapes/contour_mesh_vertex.dart deleted file mode 100644 index 9597526..0000000 --- a/lib/src/rive_core/shapes/contour_mesh_vertex.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:rive/src/generated/shapes/contour_mesh_vertex_base.dart'; -export 'package:rive/src/generated/shapes/contour_mesh_vertex_base.dart'; - -class ContourMeshVertex extends ContourMeshVertexBase {} diff --git a/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart b/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart deleted file mode 100644 index 2194f8a..0000000 --- a/lib/src/rive_core/shapes/cubic_asymmetric_vertex.dart +++ /dev/null @@ -1,97 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/shapes/cubic_asymmetric_vertex_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/cubic_asymmetric_vertex_base.dart'; - -class CubicAsymmetricVertex extends CubicAsymmetricVertexBase { - CubicAsymmetricVertex(); - CubicAsymmetricVertex.procedural() { - InternalCoreHelper.markValid(this); - } - - CubicAsymmetricVertex.fromValues({ - required double x, - required double y, - double? inX, - double? inY, - double? outX, - double? outY, - Vec2D? inPoint, - Vec2D? outPoint, - }) { - InternalCoreHelper.markValid(this); - this.x = x; - this.y = y; - this.inPoint = Vec2D.fromValues(inX ?? inPoint!.x, inY ?? inPoint!.y); - this.outPoint = Vec2D.fromValues(outX ?? outPoint!.x, outY ?? outPoint!.y); - } - - Vec2D? _inPoint; - Vec2D? _outPoint; - - @override - Vec2D get outPoint { - return _outPoint ??= Vec2D.fromValues( - translation.x + cos(rotation) * outDistance, - translation.y + sin(rotation) * outDistance); - } - - @override - set outPoint(Vec2D value) { - _outPoint = Vec2D.clone(value); - } - - @override - Vec2D get inPoint { - return _inPoint ??= Vec2D.fromValues( - translation.x + cos(rotation) * -inDistance, - translation.y + sin(rotation) * -inDistance); - } - - @override - set inPoint(Vec2D value) { - _inPoint = Vec2D.clone(value); - } - - @override - String toString() { - return 'in $inPoint | $translation | out $outPoint'; - } - - @override - void xChanged(double from, double to) { - super.xChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void yChanged(double from, double to) { - super.yChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void inDistanceChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = _outPoint = null; - path?.markPathDirty(); - } - - @override - void outDistanceChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = _outPoint = null; - path?.markPathDirty(); - } - - @override - void rotationChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = _outPoint = null; - path?.markPathDirty(); - } -} diff --git a/lib/src/rive_core/shapes/cubic_detached_vertex.dart b/lib/src/rive_core/shapes/cubic_detached_vertex.dart deleted file mode 100644 index 8dc9949..0000000 --- a/lib/src/rive_core/shapes/cubic_detached_vertex.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/shapes/cubic_detached_vertex_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/cubic_detached_vertex_base.dart'; - -class CubicDetachedVertex extends CubicDetachedVertexBase { - Vec2D? _inPoint; - Vec2D? _outPoint; - - CubicDetachedVertex(); - CubicDetachedVertex.fromValues({ - required double x, - required double y, - double? inX, - double? inY, - double? outX, - double? outY, - Vec2D? inPoint, - Vec2D? outPoint, - }) { - InternalCoreHelper.markValid(this); - this.x = x; - this.y = y; - this.inPoint = Vec2D.fromValues(inX ?? inPoint!.x, inY ?? inPoint!.y); - this.outPoint = Vec2D.fromValues(outX ?? outPoint!.x, outY ?? outPoint!.y); - } - - @override - Vec2D get outPoint => _outPoint ??= Vec2D.fromValues( - translation.x + cos(outRotation) * outDistance, - translation.y + sin(outRotation) * outDistance); - - @override - set outPoint(Vec2D value) { - _outPoint = Vec2D.clone(value); - } - - @override - Vec2D get inPoint => _inPoint ??= Vec2D.fromValues( - translation.x + cos(inRotation) * inDistance, - translation.y + sin(inRotation) * inDistance); - - @override - set inPoint(Vec2D value) { - _inPoint = Vec2D.clone(value); - } - - @override - String toString() { - return 'in $inPoint | $translation | out $outPoint'; - } - - @override - void xChanged(double from, double to) { - super.xChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void yChanged(double from, double to) { - super.yChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void inDistanceChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = null; - path?.markPathDirty(); - } - - @override - void inRotationChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = null; - path?.markPathDirty(); - } - - @override - void outDistanceChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _outPoint = null; - path?.markPathDirty(); - } - - @override - void outRotationChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _outPoint = null; - path?.markPathDirty(); - } -} diff --git a/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart b/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart deleted file mode 100644 index de2a59c..0000000 --- a/lib/src/rive_core/shapes/cubic_mirrored_vertex.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/shapes/cubic_mirrored_vertex_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/cubic_mirrored_vertex_base.dart'; - -class CubicMirroredVertex extends CubicMirroredVertexBase { - CubicMirroredVertex(); - - /// Makes a vertex that is disconnected from core. - CubicMirroredVertex.procedural() { - InternalCoreHelper.markValid(this); - } - - Vec2D? _inPoint; - Vec2D? _outPoint; - - @override - Vec2D get outPoint { - return _outPoint ??= Vec2D.fromValues( - translation.x + cos(rotation) * distance, - translation.y + sin(rotation) * distance); - } - - @override - set outPoint(Vec2D value) { - _outPoint = Vec2D.clone(value); - } - - @override - Vec2D get inPoint { - return _inPoint ??= Vec2D.fromValues( - translation.x + cos(rotation) * -distance, - translation.y + sin(rotation) * -distance); - } - - @override - set inPoint(Vec2D value) { - var diffIn = Vec2D.fromValues(value.x - x, value.y - y); - outPoint = translation - diffIn; - } - - @override - String toString() { - return 'in $inPoint | $translation | out $outPoint'; - } - - @override - void xChanged(double from, double to) { - super.xChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void yChanged(double from, double to) { - super.yChanged(from, to); - _outPoint = _inPoint = null; - } - - @override - void distanceChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = _outPoint = null; - path?.markPathDirty(); - } - - @override - void rotationChanged(double from, double to) { - addDirt(ComponentDirt.worldTransform); - _inPoint = _outPoint = null; - path?.markPathDirty(); - } -} diff --git a/lib/src/rive_core/shapes/cubic_vertex.dart b/lib/src/rive_core/shapes/cubic_vertex.dart deleted file mode 100644 index b0466e6..0000000 --- a/lib/src/rive_core/shapes/cubic_vertex.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'dart:typed_data'; - -import 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/cubic_vertex_base.dart'; - -abstract class CubicVertex extends CubicVertexBase { - Vec2D get outPoint; - Vec2D get inPoint; - - set outPoint(Vec2D value); - set inPoint(Vec2D value); - - @override - Vec2D get renderTranslation => weight?.translation ?? super.renderTranslation; - - Vec2D get renderIn => weight?.inTranslation ?? inPoint; - Vec2D get renderOut => weight?.outTranslation ?? outPoint; - - @override - void deform(Mat2D world, Float32List boneTransforms) { - super.deform(world, boneTransforms); - - Weight.deform(outPoint.x, outPoint.y, weight!.outIndices, weight!.outValues, - world, boneTransforms, weight!.outTranslation); - Weight.deform(inPoint.x, inPoint.y, weight!.inIndices, weight!.inValues, - world, boneTransforms, weight!.inTranslation); - } -} diff --git a/lib/src/rive_core/shapes/ellipse.dart b/lib/src/rive_core/shapes/ellipse.dart deleted file mode 100644 index 7e0cce3..0000000 --- a/lib/src/rive_core/shapes/ellipse.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:rive/src/generated/shapes/ellipse_base.dart'; -import 'package:rive/src/rive_core/shapes/cubic_detached_vertex.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/ellipse_base.dart'; - -class Ellipse extends EllipseBase { - @override - List get vertices { - double ox = -originX * width + radiusX; - double oy = -originY * height + radiusY; - - return [ - CubicDetachedVertex.fromValues( - x: ox, - y: oy - radiusY, - inX: ox - radiusX * circleConstant, - inY: oy - radiusY, - outX: ox + radiusX * circleConstant, - outY: oy - radiusY, - ), - CubicDetachedVertex.fromValues( - x: ox + radiusX, - y: oy, - inX: ox + radiusX, - inY: oy + circleConstant * -radiusY, - outX: ox + radiusX, - outY: oy + circleConstant * radiusY, - ), - CubicDetachedVertex.fromValues( - x: ox, - y: oy + radiusY, - inX: ox + radiusX * circleConstant, - inY: oy + radiusY, - outX: ox - radiusX * circleConstant, - outY: oy + radiusY, - ), - CubicDetachedVertex.fromValues( - x: ox - radiusX, - y: oy, - inX: ox - radiusX, - inY: oy + radiusY * circleConstant, - outX: ox - radiusX, - outY: oy - radiusY * circleConstant, - ), - ]; - } - - double get radiusX => width / 2; - double get radiusY => height / 2; -} diff --git a/lib/src/rive_core/shapes/image.dart b/lib/src/rive_core/shapes/image.dart deleted file mode 100644 index f0ab2e6..0000000 --- a/lib/src/rive_core/shapes/image.dart +++ /dev/null @@ -1,160 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:rive/src/generated/shapes/image_base.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/assets/image_asset.dart'; -import 'package:rive/src/rive_core/bones/skinnable.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/shapes/mesh.dart'; -import 'package:rive/src/rive_core/shapes/mesh_vertex.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/image_base.dart'; - -class Image extends ImageBase - with - FileAssetReferencer, - SkinnableProvider, - Sizable { - ui.Image? get image => asset?.image; - Mesh? _mesh; - Mesh? get mesh => _mesh; - bool get hasMesh => _mesh != null; - - double get width => image?.width.toDouble() ?? asset!.width; - double get height => image?.height.toDouble() ?? asset!.height; - - @override - AABB get localBounds { - if (hasMesh && _mesh!.draws) { - return _mesh!.bounds; - } - if (asset == null) { - return AABB.empty(); - } - return AABB.fromValues( - -width * originX, - -height * originY, - -width * originX + width, - -height * originY + height, - ); - } - - @override - void assetIdChanged(int from, int to) {} - - @override - void draw(ui.Canvas canvas) { - var uiImage = asset?.image; - if (uiImage == null) { - return; - } - bool clipped = clip(canvas); - - final paint = ui.Paint() - ..color = ui.Color.fromRGBO(0, 0, 0, renderOpacity) - ..filterQuality = ui.FilterQuality.high - ..blendMode = blendMode; - - canvas.save(); - canvas.transform(renderTransform.mat4); - if (_mesh == null || !_mesh!.draws) { - canvas.drawImage( - uiImage, ui.Offset(-width * originX, -height * originY), paint); - } else { - paint.shader = ui.ImageShader( - uiImage, - ui.TileMode.clamp, - ui.TileMode.clamp, - Float64List.fromList([ - 1 / width, - 0.0, - 0.0, - 0.0, - 0.0, - 1 / height, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ])); - _mesh!.draw(canvas, paint); - } - canvas.restore(); - - if (clipped) { - canvas.restore(); - } - } - - @override - int get assetIdPropertyKey => ImageBase.assetIdPropertyKey; - - @override - bool import(ImportStack stack) { - if (!registerWithImporter(stack)) { - return false; - } - return super.import(stack); - } - - @override - void copy(covariant Image source) { - super.copy(source); - asset = source.asset; - } - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is Mesh) { - _mesh = child; - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - if (child is Mesh && _mesh == child) { - _mesh = null; - } - } - - @override - Skinnable? get skinnable => _mesh; - - @override - void originXChanged(double from, double to) => markTransformDirty(); - - @override - void originYChanged(double from, double to) => markTransformDirty(); - - @override - ui.Size computeIntrinsicSize(ui.Size min, ui.Size max) { - return ui.Size(width * scaleX, height * scaleY); - } - - @override - void controlSize(ui.Size size) { - scaleX = size.width / width; - scaleY = size.height / height; - - markTransformDirty(); - } - - Mat2D get renderTransform { - var mesh = _mesh; - if (mesh != null && mesh.draws) { - return mesh.worldTransform; - } - return worldTransform; - } -} diff --git a/lib/src/rive_core/shapes/mesh.dart b/lib/src/rive_core/shapes/mesh.dart deleted file mode 100644 index b78be5a..0000000 --- a/lib/src/rive_core/shapes/mesh.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui' as ui; - -import 'package:rive/src/generated/shapes/mesh_base.dart'; -import 'package:rive/src/rive_core/bones/skinnable.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/shapes/contour_mesh_vertex.dart'; -import 'package:rive/src/rive_core/shapes/image.dart'; -import 'package:rive/src/rive_core/shapes/mesh_vertex.dart'; -import 'package:rive/src/rive_core/transform_component.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/utilities.dart'; - -export 'package:rive/src/generated/shapes/mesh_base.dart'; - -class Mesh extends MeshBase with Skinnable { - // When bound to bones pathTransform should be the identity as it'll already - // be in world space. - - final List _vertices = []; - - List get vertices => _vertices; - - ui.Vertices? _uiVertices; - Uint16List _triangleIndices = Uint16List(0); - Uint16List get triangleIndices => _triangleIndices; - - int get contourVertexCount { - int i = 0; - while (i < _vertices.length && _vertices[i] is ContourMeshVertex) { - i++; - } - return i; - } - - bool get isValid => _uiVertices != null; - - bool get draws { - return isValid; - } - - TransformComponent get transformComponent => parent as Image; - Drawable get drawable => parent as Drawable; - - @override - bool validate() => - super.validate() && - parent is TransformComponent && - _areTriangleIndicesValid(); - - bool _areTriangleIndicesValid() { - var maxIndex = vertices.length; - if (triangleIndices.length % 3 != 0) { - return false; - } - for (final index in triangleIndices) { - if (index >= maxIndex) { - return false; - } - } - - return true; - } - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is MeshVertex && !_vertices.contains(child)) { - _vertices.add(child); - } - } - - void markDrawableDirty() => addDirt(ComponentDirt.vertices); - - @override - void childRemoved(Component child) { - super.childRemoved(child); - if (child is MeshVertex) { - _vertices.remove(child); - } - } - - @override - void buildDependencies() { - super.buildDependencies(); - parent?.addDependent(this); - skin?.addDependent(this); - } - - AABB bounds = AABB.empty(); - - @override - void update(int dirt) { - if (dirt & ComponentDirt.vertices != 0) { - skin?.deform(_vertices); - - bounds = AABB.empty(); - var vertices = []; - var uv = []; - for (final vertex in _vertices) { - var point = vertex.renderTranslation; - - vertices.add(ui.Offset(point.x, point.y)); - bounds.expandToPoint(point); - uv.add(ui.Offset(vertex.u, vertex.v)); - } - if (_triangleIndices.isEmpty) { - _uiVertices = null; - } else { - _uiVertices = ui.Vertices( - ui.VertexMode.triangles, - vertices, - textureCoordinates: uv, - indices: _triangleIndices, - ); - } - } - } - - void draw(ui.Canvas canvas, ui.Paint paint) { - assert(_uiVertices != null); - canvas.drawVertices(_uiVertices!, ui.BlendMode.srcOver, paint); - } - - void _deserializeTriangleIndices() { - var reader = BinaryReader.fromList(triangleIndexBytes); - List triangles = []; - while (!reader.isEOF) { - triangles.add(reader.readVarUint()); - } - _triangleIndices = Uint16List.fromList(triangles); - - markDrawableDirty(); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - - _deserializeTriangleIndices(); - } - - @override - void markSkinDirty() => addDirt(ComponentDirt.vertices); - - Mat2D get worldTransform => - skin != null ? Mat2D.identity : transformComponent.worldTransform; - - @override - void triangleIndexBytesChanged(List from, List to) => - _deserializeTriangleIndices(); -} diff --git a/lib/src/rive_core/shapes/mesh_vertex.dart b/lib/src/rive_core/shapes/mesh_vertex.dart deleted file mode 100644 index f550d42..0000000 --- a/lib/src/rive_core/shapes/mesh_vertex.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/generated/shapes/mesh_vertex_base.dart'; -import 'package:rive/src/rive_core/shapes/mesh.dart'; - -export 'package:rive/src/generated/shapes/mesh_vertex_base.dart'; - -class MeshVertex extends MeshVertexBase { - Mesh? get mesh => parent as Mesh?; - - @override - bool validate() => super.validate() && parent is Mesh; - - @override - void markGeometryDirty() => mesh?.markDrawableDirty(); - - @override - void uChanged(double from, double to) {} - - @override - void vChanged(double from, double to) {} -} diff --git a/lib/src/rive_core/shapes/paint/fill.dart b/lib/src/rive_core/shapes/paint/fill.dart deleted file mode 100644 index 67756ac..0000000 --- a/lib/src/rive_core/shapes/paint/fill.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/paint/fill_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; - -export 'package:rive/src/generated/shapes/paint/fill_base.dart'; - -/// A fill Shape painter. -class Fill extends FillBase { - @override - Paint makePaint() => Paint()..style = PaintingStyle.fill; - - PathFillType get fillType => PathFillType.values[fillRule]; - set fillType(PathFillType type) => fillRule = type.index; - - @override - void fillRuleChanged(int from, int to) => - parent?.addDirt(ComponentDirt.paint); - - @override - void update(int dirt) { - // Intentionally empty, fill doesn't update. - // Because Fill never adds dependencies, it'll also never get called. - } - - @override - void onAdded() { - super.onAdded(); - if (parent is ShapePaintContainer) { - (parent as ShapePaintContainer).addFill(this); - } - } - - @override - void draw(Canvas canvas, Path path) { - if (!isVisible || renderOpacity == 0) { - return; - } - path.fillType = fillType; - canvas.drawPath(path, paint); - } -} diff --git a/lib/src/rive_core/shapes/paint/gradient_stop.dart b/lib/src/rive_core/shapes/paint/gradient_stop.dart deleted file mode 100644 index 1e6b1d5..0000000 --- a/lib/src/rive_core/shapes/paint/gradient_stop.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart'; - -export 'package:rive/src/generated/shapes/paint/gradient_stop_base.dart'; - -class GradientStop extends GradientStopBase { - LinearGradient? _gradient; - LinearGradient? get gradient => _gradient; - ui.Color get color => ui.Color(colorValue); - set color(ui.Color c) { - colorValue = c.value; - } - - @override - void positionChanged(double from, double to) { - _gradient?.markStopsDirty(); - } - - @override - void colorValueChanged(int from, int to) { - _gradient?.markGradientDirty(); - } - - @override - void update(int dirt) {} - - @override - bool validate() => super.validate() && _gradient != null; - - @override - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - super.parentChanged(from, to); - if (parent is LinearGradient) { - _gradient = parent as LinearGradient; - } else { - _gradient = null; - } - } -} diff --git a/lib/src/rive_core/shapes/paint/linear_gradient.dart b/lib/src/rive_core/shapes/paint/linear_gradient.dart deleted file mode 100644 index 18b62b2..0000000 --- a/lib/src/rive_core/shapes/paint/linear_gradient.dart +++ /dev/null @@ -1,175 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:meta/meta.dart'; -import 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/paint/gradient_stop.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/paint/linear_gradient_base.dart'; - -/// A core linear gradient. Can be added as a child to a [Shape]'s [Fill] or -/// [Stroke] to paint that Fill or Stroke with a gradient. This is the -/// foundation for the RadialGradient which is very similar but also has a -/// radius value. -class LinearGradient extends LinearGradientBase with ShapePaintMutator { - /// Stored list of core gradient stops are in the hierarchy as children of - /// this container. - final List gradientStops = []; - - bool _paintsInWorldSpace = false; - bool get paintsInWorldSpace => _paintsInWorldSpace; - set paintsInWorldSpace(bool value) { - if (_paintsInWorldSpace == value) { - return; - } - _paintsInWorldSpace = value; - addDirt(ComponentDirt.paint); - } - - Vec2D get start => Vec2D.fromValues(startX, startY); - Vec2D get end => Vec2D.fromValues(endX, endY); - - ui.Offset get startOffset => ui.Offset(startX, startY); - ui.Offset get endOffset => ui.Offset(endX, endY); - - /// Gradients depends on their shape. - @override - void buildDependencies() { - super.buildDependencies(); - shapePaintContainer?.addDependent(this); - } - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is GradientStop && !gradientStops.contains(child)) { - gradientStops.add(child); - - markStopsDirty(); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - if (child is GradientStop && gradientStops.contains(child)) { - gradientStops.remove(child); - - markStopsDirty(); - } - } - - /// Mark the gradient stops as changed. This will re-sort the stops and - /// rebuild the necessary gradients in the next update cycle. - void markStopsDirty() { - addDirt(ComponentDirt.stops | ComponentDirt.paint); - markPaintDirty(); - } - - /// Mark the gradient as needing to be rebuilt. This is a more efficient - /// version of markStopsDirty as it won't re-sort the stops. - void markGradientDirty() { - addDirt(ComponentDirt.paint); - markPaintDirty(); - } - - @override - void update(int dirt) { - // Do the stops need to be re-ordered? - bool stopsChanged = dirt & ComponentDirt.stops != 0; - if (stopsChanged) { - gradientStops.sort((a, b) => a.position.compareTo(b.position)); - } - - bool worldTransformed = dirt & ComponentDirt.worldTransform != 0; - bool localTransformed = dirt & ComponentDirt.transform != 0; - - // We rebuild the gradient if the gradient is dirty or we paint in world - // space and the world space transform has changed, or the local transform - // has changed. Local transform changes when a stop moves in local space. - var rebuildGradient = dirt & ComponentDirt.paint != 0 || - localTransformed || - (paintsInWorldSpace && worldTransformed); - if (rebuildGradient) { - // build up the color and positions lists - var colors = []; - var colorPositions = []; - for (final stop in gradientStops) { - colors.add(stop.color); - colorPositions.add(stop.position.clamp(0.0, 1.0)); - } - // Check if we need to update the world space gradient. - if (paintsInWorldSpace) { - // Get the start and end of the gradient in world coordinates (world - // transform of the shape). - var world = shapePaintContainer!.worldTransform; - var worldStart = world * start; - var worldEnd = world * end; - paint.shader = makeGradient(ui.Offset(worldStart.x, worldStart.y), - ui.Offset(worldEnd.x, worldEnd.y), colors, colorPositions); - } else { - paint.shader = - makeGradient(startOffset, endOffset, colors, colorPositions); - } - } - } - - @protected - ui.Gradient makeGradient(ui.Offset start, ui.Offset end, - List colors, List colorPositions) => - ui.Gradient.linear(start, end, colors, colorPositions); - - @override - void startXChanged(double from, double to) { - addDirt(ComponentDirt.transform); - markPaintDirty(); - } - - @override - void startYChanged(double from, double to) { - addDirt(ComponentDirt.transform); - markPaintDirty(); - } - - @override - void endXChanged(double from, double to) { - addDirt(ComponentDirt.transform); - markPaintDirty(); - } - - @override - void endYChanged(double from, double to) { - addDirt(ComponentDirt.transform); - markPaintDirty(); - } - - void markPaintDirty() => shapePaintContainer?.addDirt(ComponentDirt.paint); - - @override - void onAdded() { - super.onAdded(); - syncColor(); - } - - @override - void opacityChanged(double from, double to) { - syncColor(); - // We don't need to rebuild anything, just let our shape know we should - // repaint. - markPaintDirty(); - } - - @override - void syncColor() { - super.syncColor(); - paint.color = const ui.Color(0xFFFFFFFF) - .withOpacity((opacity * renderOpacity).clamp(0, 1).toDouble()); - } - - @override - bool validate() => super.validate() && shapePaintContainer != null; -} diff --git a/lib/src/rive_core/shapes/paint/radial_gradient.dart b/lib/src/rive_core/shapes/paint/radial_gradient.dart deleted file mode 100644 index 1c5baf4..0000000 --- a/lib/src/rive_core/shapes/paint/radial_gradient.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:ui' as ui; -import 'package:rive/src/generated/shapes/paint/radial_gradient_base.dart'; -export 'package:rive/src/generated/shapes/paint/radial_gradient_base.dart'; - -class RadialGradient extends RadialGradientBase { - /// We override the make gradient operation to create a radial gradient - /// instead of a linear one. - @override - ui.Gradient makeGradient(ui.Offset start, ui.Offset end, - List colors, List colorPositions) => - ui.Gradient.radial(start, (end - start).distance, colors, colorPositions); -} diff --git a/lib/src/rive_core/shapes/paint/shape_paint.dart b/lib/src/rive_core/shapes/paint/shape_paint.dart deleted file mode 100644 index 23bc818..0000000 --- a/lib/src/rive_core/shapes/paint/shape_paint.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/paint/shape_paint_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; - -export 'package:rive/src/generated/shapes/paint/shape_paint_base.dart'; - -/// Generic ShapePaint that abstracts Stroke and Fill. Automatically hooks up -/// parent [Shape] to child [ShapePaintMutator]s. -abstract class ShapePaint extends ShapePaintBase { - late Paint _paint; - Paint get paint => _paint; - ShapePaintMutator? _paintMutator; - ShapePaintContainer? get shapePaintContainer => - parent is ShapePaintContainer ? parent as ShapePaintContainer : null; - - ShapePaint() { - _paint = makePaint(); - } - - BlendMode get blendMode => _paint.blendMode; - set blendMode(BlendMode value) => _paint.blendMode = value; - - double get renderOpacity => _paintMutator!.renderOpacity; - set renderOpacity(double value) => _paintMutator!.renderOpacity = value; - - ShapePaintMutator? get paintMutator => _paintMutator; - - void _changeMutator(ShapePaintMutator? mutator) { - _paint = makePaint(); - _paintMutator = mutator; - } - - /// Implementing classes are expected to override this to create a paint - /// object. This gets called whenever the mutator is changed in order to not - /// require each mutator to manually reset the paint to some canonical state. - /// Instead, we simply blow out the old one and make a new one. - @protected - Paint makePaint(); - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is ShapePaintMutator) { - _changeMutator(child as ShapePaintMutator); - if (shapePaintContainer != null) { - _initMutator(); - } - } - } - - @override - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - super.parentChanged(from, to); - if (shapePaintContainer != null) { - _initMutator(); - } - } - - @override - bool validate() => - super.validate() && - parent is ShapePaintContainer && - _paintMutator != null; - - @override - void isVisibleChanged(bool from, bool to) { - shapePaintContainer?.addDirt(ComponentDirt.paint); - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - // Make sure to clean up any references so that they can be garbage - // collected. - if (child is ShapePaintMutator && - _paintMutator == child as ShapePaintMutator) { - _changeMutator(null); - } - } - - void _initMutator() => - _paintMutator?.initializePaintMutator(shapePaintContainer!, paint); - - void draw(Canvas canvas, Path path); -} diff --git a/lib/src/rive_core/shapes/paint/shape_paint_mutator.dart b/lib/src/rive_core/shapes/paint/shape_paint_mutator.dart deleted file mode 100644 index 6062bdd..0000000 --- a/lib/src/rive_core/shapes/paint/shape_paint_mutator.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; - -abstract class ShapePaintMutator { - ShapePaintContainer? _shapePaintContainer; - Paint _paint = Paint(); - - /// Getter for the component's artboard - Artboard? get artboard; - - /// The container is usually either a Shape or an Artboard, basically any of - /// the various ContainerComponents that can contain Fills or Strokes. - ShapePaintContainer? get shapePaintContainer => _shapePaintContainer; - Paint get paint => _paint; - - double _renderOpacity = 1; - double get renderOpacity => _renderOpacity; - set renderOpacity(double value) { - if (_renderOpacity != value) { - _renderOpacity = value; - syncColor(); - } - } - - @mustCallSuper - void syncColor() => _paint.isAntiAlias = artboard?.antialiasing ?? true; - - @mustCallSuper - void initializePaintMutator(ShapePaintContainer container, Paint paint) { - _shapePaintContainer = container; - _paint = paint; - _shapePaintContainer?.onPaintMutatorChanged(this); - syncColor(); - } -} diff --git a/lib/src/rive_core/shapes/paint/solid_color.dart b/lib/src/rive_core/shapes/paint/solid_color.dart deleted file mode 100644 index 0bcd170..0000000 --- a/lib/src/rive_core/shapes/paint/solid_color.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/paint/solid_color_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; - -export 'package:rive/src/generated/shapes/paint/solid_color_base.dart'; - -/// A solid color painter for a shape. Works for both Fill and Stroke. -class SolidColor extends SolidColorBase with ShapePaintMutator { - Color get color => Color(colorValue); - set color(Color c) { - colorValue = c.value; - } - - @override - void colorValueChanged(int from, int to) { - // Since all we need to do is set the color on the paint, we can just do - // this whenever it changes as it's such a lightweight operation. We don't - // need to schedule it for the next update cycle, which saves us from adding - // SolidColor to the dependencies graph. - syncColor(); - - // Since we're not in the dependency tree, chuck dirt onto the shape, which - // is. This just ensures we'll paint as soon as possible to show the updated - // color. - shapePaintContainer?.addDirt(ComponentDirt.paint); - } - - @override - void update(int dirt) { - // Intentionally empty. SolidColor doesn't need an update cycle and doesn't - // depend on anything. - } - - @override - void syncColor() { - super.syncColor(); - paint.color = color - .withOpacity((color.opacity * renderOpacity).clamp(0, 1).toDouble()); - } - - @override - bool validate() => super.validate() && parent is ShapePaint; - - @override - void onAdded() { - super.onAdded(); - syncColor(); - } -} diff --git a/lib/src/rive_core/shapes/paint/stroke.dart b/lib/src/rive_core/shapes/paint/stroke.dart deleted file mode 100644 index ecea4ee..0000000 --- a/lib/src/rive_core/shapes/paint/stroke.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:rive/src/generated/shapes/paint/stroke_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke_effect.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; - -export 'package:rive/src/generated/shapes/paint/stroke_base.dart'; - -/// A stroke Shape painter. -class Stroke extends StrokeBase { - StrokeEffect? _effect; - StrokeEffect? get effect => _effect; - - // Should be @internal when supported. - // ignore: use_setters_to_change_properties - void addStrokeEffect(StrokeEffect effect) { - _effect = effect; - } - - void removeStrokeEffect(StrokeEffect effect) { - if (effect == _effect) { - _effect = null; - } - } - - @override - Paint makePaint() => Paint() - ..style = PaintingStyle.stroke - ..strokeCap = strokeCap - ..strokeJoin = strokeJoin - ..strokeWidth = thickness; - - StrokeCap get strokeCap => enumAt(StrokeCap.values, cap); - set strokeCap(StrokeCap value) => cap = value.index; - - StrokeJoin get strokeJoin => enumAt(StrokeJoin.values, join); - set strokeJoin(StrokeJoin value) => join = value.index; - - @override - void capChanged(int from, int to) { - paint.strokeCap = enumAt(StrokeCap.values, to); - parent?.addDirt(ComponentDirt.paint); - } - - @override - void joinChanged(int from, int to) { - paint.strokeJoin = enumAt(StrokeJoin.values, to); - parent?.addDirt(ComponentDirt.paint); - } - - @override - void thicknessChanged(double from, double to) { - paint.strokeWidth = to; - parent?.addDirt(ComponentDirt.paint); - } - - @override - void transformAffectsStrokeChanged(bool from, bool to) { - var parentShape = parent; - if (parentShape is Shape) { - parentShape.paintChanged(); - } - } - - @override - void update(int dirt) { - // Intentionally empty, fill doesn't update. - // Because Fill never adds dependencies, it'll also never get called. - } - - @override - void onAdded() { - super.onAdded(); - if (parent is ShapePaintContainer) { - (parent as ShapePaintContainer).addStroke(this); - } - } - - void invalidateEffects() => _effect?.invalidateEffect(); - - @override - void draw(Canvas canvas, Path path) { - if (!isVisible || renderOpacity == 0 || thickness <= 0) { - return; - } - - canvas.drawPath(_effect?.effectPath(path) ?? path, paint); - } -} diff --git a/lib/src/rive_core/shapes/paint/stroke_effect.dart b/lib/src/rive_core/shapes/paint/stroke_effect.dart deleted file mode 100644 index eeb9823..0000000 --- a/lib/src/rive_core/shapes/paint/stroke_effect.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'dart:ui'; - -abstract class StrokeEffect { - Path effectPath(Path source); - void invalidateEffect(); -} diff --git a/lib/src/rive_core/shapes/paint/trim_path.dart b/lib/src/rive_core/shapes/paint/trim_path.dart deleted file mode 100644 index 6a032ec..0000000 --- a/lib/src/rive_core/shapes/paint/trim_path.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/paint/trim_path_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke_effect.dart'; -import 'package:rive/src/rive_core/shapes/paint/trim_path_drawing.dart'; - -export 'package:rive/src/generated/shapes/paint/trim_path_base.dart'; - -enum TrimPathMode { - none, - sequential, - synchronized, -} - -class TrimPath extends TrimPathBase implements StrokeEffect { - final Path _trimmedPath = Path(); - Path? _renderPath; - @override - Path effectPath(Path source) { - if (_renderPath != null) { - return _renderPath!; - } - _trimmedPath.reset(); - var isSequential = mode == TrimPathMode.sequential; - double renderStart = start.clamp(0, 1).toDouble(); - double renderEnd = end.clamp(0, 1).toDouble(); - - bool inverted = renderStart > renderEnd; - if ((renderStart - renderEnd).abs() != 1.0) { - renderStart = (renderStart + offset) % 1.0; - renderEnd = (renderEnd + offset) % 1.0; - - if (renderStart < 0) { - renderStart += 1.0; - } - if (renderEnd < 0) { - renderEnd += 1.0; - } - if (inverted) { - final double swap = renderEnd; - renderEnd = renderStart; - renderStart = swap; - } - if (renderEnd >= renderStart) { - updateTrimPath( - source, _trimmedPath, renderStart, renderEnd, false, isSequential); - } else { - updateTrimPath( - source, _trimmedPath, renderEnd, renderStart, true, isSequential); - } - } else { - return _renderPath = source; - } - return _renderPath = _trimmedPath; - } - - Stroke? get stroke => parent as Stroke?; - - TrimPathMode get mode => TrimPathMode.values[modeValue]; - set mode(TrimPathMode value) => modeValue = value.index; - - @override - void invalidateEffect() { - _renderPath = null; - stroke?.shapePaintContainer?.addDirt(ComponentDirt.paint); - } - - @override - void endChanged(double from, double to) => invalidateEffect(); - - @override - void modeValueChanged(int from, int to) => invalidateEffect(); - - @override - void offsetChanged(double from, double to) => invalidateEffect(); - - @override - void startChanged(double from, double to) => invalidateEffect(); - - @override - void update(int dirt) {} - - @override - void onAdded() { - super.onAdded(); - stroke?.addStrokeEffect(this); - _renderPath = null; - } - - @override - void onRemoved() { - stroke?.removeStrokeEffect(this); - - super.onRemoved(); - } -} diff --git a/lib/src/rive_core/shapes/paint/trim_path_drawing.dart b/lib/src/rive_core/shapes/paint/trim_path_drawing.dart deleted file mode 100644 index 5baf13b..0000000 --- a/lib/src/rive_core/shapes/paint/trim_path_drawing.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'dart:math'; -import 'dart:ui'; - -class _FirstExtractedPath { - final Path path; - double length; - final PathMetric metric; - _FirstExtractedPath(this.path, this.metric, this.length); -} - -// Returns the path it last extracted from (actually the metrics for that path). -_FirstExtractedPath? _appendPathSegmentSequential( - Iterable metrics, - Path result, - double start, - double stop, { - _FirstExtractedPath? first, -}) { - double nextOffset = 0; - double offset = 0; - for (final metric in metrics) { - nextOffset += metric.length; - if (start < nextOffset) { - // Store the last metric extracted from so next ops can use it. - var st = max(0.0, start - offset); - var et = min(metric.length, stop - offset); - var extractLength = et - st; - Path extracted = metric.extractPath(st, et); - - // If we're re-extracting from the first path, make it look - // contiguous. - if (first == null) { - // ignore: parameter_assignments - first = _FirstExtractedPath(extracted, metric, extractLength); - } else if (first.metric == metric) { - first.length += extractLength; - if (metric.isClosed) { - first.path.extendWithPath(extracted, Offset.zero); - } else { - result.addPath(extracted, Offset.zero); - } - } else { - // If we extracted this whole sub-path, close it. - if (metric.isClosed && extractLength == metric.length) { - extracted.close(); - } - result.addPath(extracted, Offset.zero); - } - - if (stop < nextOffset) { - break; - } - } - offset = nextOffset; - } - return first; -} - -void _appendPathSegmentSync( - PathMetric metric, - Path to, - double start, - double stop, { - bool startWithMoveTo = true, -}) { - double nextOffset = metric.length; - if (start < nextOffset) { - Path extracted = metric.extractPath(start, stop); - - if (startWithMoveTo) { - to.addPath(extracted, Offset.zero); - } else { - to.extendWithPath(extracted, Offset.zero); - } - } -} - -void _trimPathSequential( - Path path, Path result, double startT, double stopT, bool complement) { - // Measure length of all the contours. - var metrics = path.computeMetrics().toList(growable: false); - double totalLength = 0.0; - for (final metric in metrics) { - totalLength += metric.length; - } - - double trimStart = totalLength * startT; - double trimStop = totalLength * stopT; - _FirstExtractedPath? first; - if (complement) { - if (trimStop < totalLength) { - first = - _appendPathSegmentSequential(metrics, result, trimStop, totalLength); - } - if (trimStart > 0.0) { - _appendPathSegmentSequential(metrics, result, 0.0, trimStart, - first: first); - } - } else if (trimStart < trimStop) { - first = _appendPathSegmentSequential( - metrics, - result, - trimStart, - trimStop, - ); - } - if (first != null) { - if (first.length == first.metric.length) { - first.path.close(); - } - result.addPath(first.path, Offset.zero); - } -} - -void _trimPathSync( - Path path, Path result, double startT, double stopT, bool complement) { - final metrics = path.computeMetrics().toList(growable: false); - for (final metric in metrics) { - double length = metric.length; - double trimStart = length * startT; - double trimStop = length * stopT; - if (complement) { - bool extractStart = trimStop < length; - if (extractStart) { - _appendPathSegmentSync(metric, result, trimStop, length); - } - if (trimStart > 0.0) { - // Make sure to connect the two paths (startWithMoveTo false) if we - // extracted the start. Force start with a move if the path is open. - _appendPathSegmentSync(metric, result, 0.0, trimStart, - startWithMoveTo: !extractStart || !metric.isClosed); - } - } else if (trimStart < trimStop) { - _appendPathSegmentSync(metric, result, trimStart, trimStop); - } - } -} - -void updateTrimPath(Path path, Path result, double startT, double stopT, - bool complement, bool isSequential) => - isSequential - ? _trimPathSequential(path, result, startT, stopT, complement) - : _trimPathSync(path, result, startT, stopT, complement); diff --git a/lib/src/rive_core/shapes/parametric_path.dart b/lib/src/rive_core/shapes/parametric_path.dart deleted file mode 100644 index 6f37b3c..0000000 --- a/lib/src/rive_core/shapes/parametric_path.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'dart:ui'; - -import 'package:rive/src/generated/shapes/parametric_path_base.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/parametric_path_base.dart'; - -abstract class ParametricPath extends ParametricPathBase implements Sizable { - @override - bool get isClosed => true; - - @override - Size computeIntrinsicSize(Size min, Size max) { - return Size(width, height); - } - - @override - void controlSize(Size size) { - width = size.width; - height = size.height; - - markPathDirty(); - } - - @override - Mat2D get pathTransform => worldTransform; - - @override - Mat2D get inversePathTransform => inverseWorldTransform; - - @override - void widthChanged(double from, double to) => markPathDirty(); - - @override - void heightChanged(double from, double to) => markPathDirty(); - - @override - void xChanged(double from, double to) { - super.xChanged(from, to); - shape?.pathChanged(this); - } - - @override - void yChanged(double from, double to) { - super.yChanged(from, to); - shape?.pathChanged(this); - } - - @override - void rotationChanged(double from, double to) { - super.rotationChanged(from, to); - shape?.pathChanged(this); - } - - @override - void scaleXChanged(double from, double to) { - super.scaleXChanged(from, to); - shape?.pathChanged(this); - } - - @override - void scaleYChanged(double from, double to) { - super.scaleYChanged(from, to); - shape?.pathChanged(this); - } - - @override - void originXChanged(double from, double to) => markPathDirty(); - - @override - void originYChanged(double from, double to) => markPathDirty(); -} diff --git a/lib/src/rive_core/shapes/path.dart b/lib/src/rive_core/shapes/path.dart deleted file mode 100644 index 18121e6..0000000 --- a/lib/src/rive_core/shapes/path.dart +++ /dev/null @@ -1,547 +0,0 @@ -import 'dart:math'; -import 'dart:ui' as ui; - -import 'package:rive/src/generated/shapes/path_base.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/component_flags.dart'; -import 'package:rive/src/rive_core/shapes/cubic_vertex.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/path_base.dart'; - -enum Axis { horizontal, vertical } - -/// An abstract low level path that gets implemented by parametric and point -/// based paths. -abstract class Path extends PathBase implements BoundsProvider { - final Mat2D _inverseWorldTransform = Mat2D(); - - final RenderPath _renderPath = RenderPath(); - ui.Path get uiPath { - if (!_isValid) { - _buildPath(); - } - return _renderPath.uiPath; - } - - bool _isValid = false; - - bool get isClosed; - - Shape? _shape; - - Shape? get shape => _shape; - - Mat2D get pathTransform; - Mat2D get inversePathTransform; - Mat2D get inverseWorldTransform => _inverseWorldTransform; - - @override - bool resolveArtboard() { - _changeShape(null); - return super.resolveArtboard(); - } - - @override - void visitAncestor(Component ancestor) { - super.visitAncestor(ancestor); - if (_shape == null && ancestor is Shape) { - _changeShape(ancestor); - } - } - - void _changeShape(Shape? value) { - if (_shape == value) { - return; - } - _shape?.removePath(this); - value?.addPath(this); - _shape = value; - } - - @override - void onRemoved() { - // We're no longer a child of the shape we may have been under, make sure to - // let it know we're gone. - _changeShape(null); - - super.onRemoved(); - } - - @override - void onDirty(int mask) { - if ((dirt & ComponentDirt.worldTransform) != 0) { - _shape?.pathChanged(this); - } - } - - @override - void updateWorldTransform() { - super.updateWorldTransform(); - - // Paths store their inverse world so that it's available for skinning and - // other operations that occur at runtime. - if (!Mat2D.invert(_inverseWorldTransform, pathTransform)) { - // If for some reason the inversion fails (like we have a 0 scale) just - // store the identity. - Mat2D.setIdentity(_inverseWorldTransform); - } - } - - @override - void update(int dirt) { - super.update(dirt); - - if (dirt & ComponentDirt.path != 0) { - _buildPath(); - } - } - - /// Subclasses should call this whenever a parameter that affects the topology - /// of the path changes in order to allow the system to rebuild the parametric - /// path. - /// should @internal when supported - void markPathDirty() { - addDirt(ComponentDirt.path); - _isValid = false; - _shape?.pathChanged(this); - } - - List get vertices; - - bool _buildPath() { - _isValid = true; - _renderPath.reset(); - return buildPath(_renderPath); - } - - /// Pour the path commands into a PathInterface [path]. - bool buildPath(PathInterface path) { - List vertices = this.vertices; - var length = vertices.length; - if (length < 2) { - return false; - } - - var firstPoint = vertices.first; - double outX, outY; - bool prevIsCubic; - - double startX, startY; - double startInX, startInY; - bool startIsCubic; - - if (firstPoint is CubicVertex) { - startIsCubic = prevIsCubic = true; - var inPoint = firstPoint.renderIn; - startInX = inPoint.x; - startInY = inPoint.y; - var outPoint = firstPoint.renderOut; - outX = outPoint.x; - outY = outPoint.y; - var translation = firstPoint.renderTranslation; - startX = translation.x; - startY = translation.y; - path.moveTo(startX, startY); - } else { - startIsCubic = prevIsCubic = false; - var point = firstPoint as StraightVertex; - - var radius = point.radius; - if (radius > 0) { - var prev = vertices[length - 1]; - - var pos = point.renderTranslation; - - var toPrev = - (prev is CubicVertex ? prev.renderOut : prev.renderTranslation) - - pos; - var toPrevLength = toPrev.length(); - toPrev.x /= toPrevLength; - toPrev.y /= toPrevLength; - - var next = vertices[1]; - - var toNext = - (next is CubicVertex ? next.renderIn : next.renderTranslation) - - pos; - var toNextLength = toNext.length(); - toNext.x /= toNextLength; - toNext.y /= toNextLength; - - var renderRadius = min(toPrevLength / 2, min(toNextLength / 2, radius)); - var idealDistance = - _computeIdealControlPointDistance(toPrev, toNext, renderRadius); - - var translation = Vec2D.scaleAndAdd(Vec2D(), pos, toPrev, renderRadius); - path.moveTo(startInX = startX = translation.x, - startInY = startY = translation.y); - - var outPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toPrev, renderRadius - idealDistance); - - var inPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toNext, renderRadius - idealDistance); - - var posNext = Vec2D.scaleAndAdd(Vec2D(), pos, toNext, renderRadius); - path.cubicTo(outPoint.x, outPoint.y, inPoint.x, inPoint.y, - outX = posNext.x, outY = posNext.y); - prevIsCubic = false; - } else { - var translation = point.renderTranslation; - outX = translation.x; - outY = translation.y; - path.moveTo(startInX = startX = outX, startInY = startY = outY); - } - } - - for (int i = 1; i < length; i++) { - var vertex = vertices[i]; - - if (vertex is CubicVertex) { - var inPoint = vertex.renderIn; - var translation = vertex.renderTranslation; - path.cubicTo( - outX, outY, inPoint.x, inPoint.y, translation.x, translation.y); - - prevIsCubic = true; - var outPoint = vertex.renderOut; - outX = outPoint.x; - outY = outPoint.y; - } else { - var point = vertex as StraightVertex; - - var radius = point.radius; - if (radius > 0) { - var prev = vertices[i - 1]; - - var pos = point.renderTranslation; - var toPrev = - (prev is CubicVertex ? prev.renderOut : prev.renderTranslation) - - pos; - - var toPrevLength = toPrev.length(); - toPrev.x /= toPrevLength; - toPrev.y /= toPrevLength; - - var next = vertices[(i + 1) % length]; - - var toNext = - (next is CubicVertex ? next.renderIn : next.renderTranslation) - - pos; - var toNextLength = toNext.length(); - toNext.x /= toNextLength; - toNext.y /= toNextLength; - - var renderRadius = - min(toPrevLength / 2, min(toNextLength / 2, radius)); - - var idealDistance = - _computeIdealControlPointDistance(toPrev, toNext, renderRadius); - - var translation = - Vec2D.scaleAndAdd(Vec2D(), pos, toPrev, renderRadius); - if (prevIsCubic) { - path.cubicTo(outX, outY, translation.x, translation.y, - translation.x, translation.y); - } else { - path.lineTo(translation.x, translation.y); - } - - var outPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toPrev, renderRadius - idealDistance); - - var inPoint = Vec2D.scaleAndAdd( - Vec2D(), pos, toNext, renderRadius - idealDistance); - - var posNext = Vec2D.scaleAndAdd(Vec2D(), pos, toNext, renderRadius); - path.cubicTo(outPoint.x, outPoint.y, inPoint.x, inPoint.y, - outX = posNext.x, outY = posNext.y); - prevIsCubic = false; - } else if (prevIsCubic) { - var translation = point.renderTranslation; - var x = translation.x; - var y = translation.y; - path.cubicTo(outX, outY, x, y, x, y); - - prevIsCubic = false; - outX = x; - outY = y; - } else { - var translation = point.renderTranslation; - outX = translation.x; - outY = translation.y; - path.lineTo(outX, outY); - } - } - } - if (isClosed) { - if (prevIsCubic || startIsCubic) { - path.cubicTo(outX, outY, startInX, startInY, startX, startY); - } - path.close(); - } - return true; - } - - @override - AABB get localBounds => _renderPath.preciseComputeBounds(); - @override - AABB computeBounds(Mat2D relativeTo) => preciseComputeBounds( - transform: Mat2D.multiply( - Mat2D(), - relativeTo, - pathTransform, - ), - ); - AABB preciseComputeBounds({ - Mat2D? transform, - }) => - _renderPath.preciseComputeBounds( - transform: transform, - ); - bool get hasBounds => _renderPath.hasBounds; - - @override - void pathFlagsChanged(int from, int to) => markPathDirty(); - - bool get isHidden => (pathFlags & ComponentFlags.hidden) != 0; - - @override - bool propagateCollapse(bool collapse) { - bool changed = super.propagateCollapse(collapse); - if (changed && shape != null) { - shape!.pathCollapseChanged(); - } - return changed; - } -} - -enum _PathCommand { moveTo, lineTo, cubicTo, close } - -class RenderPath implements PathInterface { - final ui.Path _uiPath = ui.Path(); - ui.Path get uiPath => _uiPath; - final List<_PathCommand> _commands = []; - final List _positions = []; - - void reset() { - _commands.clear(); - _positions.clear(); - _uiPath.reset(); - } - - @override - void lineTo(double x, double y) { - _commands.add(_PathCommand.lineTo); - _positions.add(x); - _positions.add(y); - _uiPath.lineTo(x, y); - } - - @override - void moveTo(double x, double y) { - _commands.add(_PathCommand.moveTo); - _positions.add(x); - _positions.add(y); - _uiPath.moveTo(x, y); - } - - @override - void cubicTo(double ox, double oy, double ix, double iy, double x, double y) { - _commands.add(_PathCommand.cubicTo); - _positions.add(ox); - _positions.add(oy); - _positions.add(ix); - _positions.add(iy); - _positions.add(x); - _positions.add(y); - _uiPath.cubicTo(ox, oy, ix, iy, x, y); - } - - void move(Vec2D v) { - moveTo(v.x, v.y); - } - - void line(Vec2D v) { - lineTo(v.x, v.y); - } - - void cubic(Vec2D b, Vec2D c, Vec2D d) { - cubicTo(b.x, b.y, c.x, c.y, d.x, d.y); - } - - @override - void close() { - _commands.add(_PathCommand.close); - _uiPath.close(); - } - - bool get isClosed => - _commands.isNotEmpty && _commands.last == _PathCommand.close; - - bool get hasBounds { - return _commands.length > 1; - } - - AABB preciseComputeBounds({ - Mat2D? transform, - }) { - if (_commands.isEmpty) { - return AABB.empty(); - } - // Compute the extremas and use them to expand the bounds as detailed here: - // https://pomax.github.io/bezierinfo/#extremities - - AABB bounds = AABB.empty(); - var idx = 0; - var penPosition = Vec2D(); - for (final command in _commands) { - switch (command) { - case _PathCommand.lineTo: - // Pen position already transformed... - bounds.includePoint(penPosition, null); - - var to = Vec2D.fromValues(_positions[idx++], _positions[idx++]); - if (transform != null) { - to.apply(transform); - } - penPosition = bounds.includePoint(to, null); - - break; - // We only do moveTo at the start, effectively always the start of the - // first line segment (so always include it). - case _PathCommand.moveTo: - penPosition.x = _positions[idx++]; - penPosition.y = _positions[idx++]; - if (transform != null) { - penPosition.apply(transform); - } - - break; - case _PathCommand.cubicTo: - var outPoint = Vec2D.fromValues(_positions[idx++], _positions[idx++]); - var inPoint = Vec2D.fromValues(_positions[idx++], _positions[idx++]); - var point = Vec2D.fromValues(_positions[idx++], _positions[idx++]); - if (transform != null) { - outPoint.apply(transform); - inPoint.apply(transform); - point.apply(transform); - } - _expandBoundsForAxis( - bounds, - Axis.horizontal, - penPosition.x, - outPoint.x, - inPoint.x, - point.x, - ); - _expandBoundsForAxis( - bounds, - Axis.vertical, - penPosition.y, - outPoint.y, - inPoint.y, - point.y, - ); - penPosition = point; - - break; - case _PathCommand.close: - break; - } - } - return bounds; - } -} - -/// Expand our bounds to a point (in normalized T space) on the Cubic. -void _expandBoundsToCubicPoint( - AABB bounds, Axis axis, double t, double a, double b, double c, double d) { - if (t >= 0 && t <= 1) { - var ti = 1 - t; - double extremaY = ((ti * ti * ti) * a) + - ((3 * ti * ti * t) * b) + - ((3 * ti * t * t) * c) + - (t * t * t * d); - __expandBounds(bounds, axis, extremaY); - } -} - -void __expandBounds(AABB bounds, Axis axis, double value) { - if (axis == Axis.horizontal) { - if (value < bounds.left) { - bounds.left = value; - } - if (value > bounds.right) { - bounds.right = value; - } - } else { - if (value < bounds.top) { - bounds.top = value; - } - if (value > bounds.bottom) { - bounds.bottom = value; - } - } -} - -void _expandBoundsForAxis( - AABB bounds, Axis axis, double start, double cp1, double cp2, double end) { - // Check start/end as cubic goes through those. - __expandBounds(bounds, axis, start); - __expandBounds(bounds, axis, end); - // Now check extremas. - - // Find the first derivative - var a = 3 * (cp1 - start); - var b = 3 * (cp2 - cp1); - var c = 3 * (end - cp2); - var d = a - 2 * b + c; - - // Solve roots for first derivative. - if (d != 0) { - var m1 = -sqrt(b * b - a * c); - var m2 = -a + b; - - // First root. - _expandBoundsToCubicPoint( - bounds, axis, -(m1 + m2) / d, start, cp1, cp2, end); - _expandBoundsToCubicPoint( - bounds, axis, -(-m1 + m2) / d, start, cp1, cp2, end); - } else if (b != c && d == 0) { - _expandBoundsToCubicPoint( - bounds, axis, (2 * b - c) / (2 * (b - c)), start, cp1, cp2, end); - } - - // Derive the first derivative to get the 2nd and use the root of - // that (linear). - var d2a = 2 * (b - a); - var d2b = 2 * (c - b); - if (d2a != b) { - _expandBoundsToCubicPoint( - bounds, axis, d2a / (d2a - d2b), start, cp1, cp2, end); - } -} - -/// Compute an ideal control point distance to create a curve of the given -/// radius. -double _computeIdealControlPointDistance( - Vec2D toPrev, Vec2D toNext, double radius) { - // Get the angle between next and prev - var angle = atan2(toPrev.x * toNext.y - toPrev.y * toNext.x, - toPrev.x * toNext.x + toPrev.y * toNext.y) - .abs(); - - return min( - radius, - (4 / 3) * - tan(pi / (2 * ((2 * pi) / angle))) * - radius * - (angle < pi / 2 ? 1 + cos(angle) : 2 - sin(angle))); -} diff --git a/lib/src/rive_core/shapes/path_composer.dart b/lib/src/rive_core/shapes/path_composer.dart deleted file mode 100644 index 848e632..0000000 --- a/lib/src/rive_core/shapes/path_composer.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive_common/math.dart'; - -/// The PathComposer builds the desired world and local paths for the shapes and -/// their fills/strokes. It guarantees that one of local or world path is always -/// available. If the Shape only wants a local path, we'll only build a local -/// one. If the Shape only wants a world path, we'll build only that world path. -/// If it wants both, we build both. If it wants none, we still build a world -/// path. -class PathComposer extends Component { - final Shape shape; - PathComposer(this.shape); - - @override - Artboard? get artboard => shape.artboard; - - final ui.Path worldPath = ui.Path(); - final ui.Path localPath = ui.Path(); - ui.Path _fillPath = ui.Path(); - ui.Path get fillPath => _fillPath; - - void _recomputePath() { - // No matter what we'll need some form of a world path to get our bounds. - // Let's optimize how we build it. - var buildLocalPath = shape.wantLocalPath; - var buildWorldPath = shape.wantWorldPath || !buildLocalPath; - - // The fill path will be whichever one of these two is available. - if (buildLocalPath) { - localPath.reset(); - var world = shape.worldTransform; - Mat2D inverseWorld = Mat2D(); - if (Mat2D.invert(inverseWorld, world)) { - for (final path in shape.paths) { - if (path.isHidden || path.isCollapsed) { - continue; - } - localPath.addPath(path.uiPath, ui.Offset.zero, - matrix4: - Mat2D.multiplySkipIdentity(inverseWorld, path.pathTransform) - .mat4); - } - } - - // If the world path doesn't get built, we should mark the bounds dirty - // here. - if (!buildWorldPath) { - shape.markBoundsDirty(); - } - } - if (buildWorldPath) { - worldPath.reset(); - for (final path in shape.paths) { - if (path.isHidden || path.isCollapsed) { - continue; - } - worldPath.addPath(path.uiPath, ui.Offset.zero, - matrix4: path.pathTransform.mat4); - } - shape.markBoundsDirty(); - } - _fillPath = shape.fillInWorld ? worldPath : localPath; - } - - @override - void buildDependencies() { - super.buildDependencies(); - - // We depend on the shape and all of its paths so that we can update after - // all of them. - shape.addDependent(this); - for (final path in shape.paths) { - path.addDependent(this); - } - } - - @override - void update(int dirt) { - if (dirt & ComponentDirt.path != 0) { - _recomputePath(); - } - } - - void syncCollapse() { - var collapsed = (dirt & ComponentDirt.collapsed) != 0; - if (collapsed == shape.isCollapsed) { - return; - } - if (collapsed) { - dirt |= ComponentDirt.collapsed; - } else { - dirt &= ~ComponentDirt.collapsed; - } - onDirty(dirt); - artboard?.onComponentDirty(this); - } - - // Instead of adding dirt and rely on the recursive behavior of the addDirt - // method, we need to explicitly add dirt to the dependents. The reason is - // that a collapsed shape will not clear its dirty path flag in the current - // frame since it is collapsed. So in a future frame if it is uncollapsed, we - // mark its path flag as dirty again, but since it was already dirty, the - // recursive part will not kick in and the dependents won't update. This - // scenario is not common, but it can happen when a solo toggles between an - // empty group and a path for example. - void pathCollapseChanged() { - addDirt(ComponentDirt.path); - for (final d in dependents) { - d.addDirt(ComponentDirt.path, recurse: true); - } - } -} diff --git a/lib/src/rive_core/shapes/path_vertex.dart b/lib/src/rive_core/shapes/path_vertex.dart deleted file mode 100644 index 4da5585..0000000 --- a/lib/src/rive_core/shapes/path_vertex.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:rive/src/generated/shapes/path_vertex_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/shapes/path.dart'; - -export 'package:rive/src/generated/shapes/path_vertex_base.dart'; - -abstract class PathVertex extends PathVertexBase { - Path? get path => parent as Path?; - - @override - void markGeometryDirty() => path?.markPathDirty(); -} diff --git a/lib/src/rive_core/shapes/points_path.dart b/lib/src/rive_core/shapes/points_path.dart deleted file mode 100644 index 99b2723..0000000 --- a/lib/src/rive_core/shapes/points_path.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:rive/src/generated/shapes/points_path_base.dart'; -import 'package:rive/src/rive_core/bones/skinnable.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/points_path_base.dart'; - -class PointsPath extends PointsPathBase with Skinnable { - final List _vertices = []; - - PointsPath() { - isClosed = false; - } - - // When bound to bones pathTransform should be the identity as it'll already - // be in world space. - @override - Mat2D get pathTransform => skin != null ? Mat2D.identity : worldTransform; - - // When bound to bones inversePathTransform should be the identity. - @override - Mat2D get inversePathTransform => - skin != null ? Mat2D() : inverseWorldTransform; - - @override - List get vertices => _vertices; - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is PathVertex && !_vertices.contains(child)) { - _vertices.add(child); - markPathDirty(); - addDirt(ComponentDirt.vertices); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - if (child is PathVertex && _vertices.remove(child)) { - markPathDirty(); - } - } - - @override - void isClosedChanged(bool from, bool to) { - markPathDirty(); - } - - @override - void buildDependencies() { - super.buildDependencies(); - - // Depend on the skin, if we have it. This works because the skin is not a - // node so we have no dependency on our parent yet (which would cause a - // dependency cycle). - skin?.addDependent(this); - } - - @override - void markPathDirty() { - // Make sure the skin gets marked dirty too. - skin?.addDirt(ComponentDirt.path); - super.markPathDirty(); - } - - @override - void markSkinDirty() => super.markPathDirty(); - - @override - void update(int dirt) { - if (dirt & ComponentDirt.path != 0) { - // Before calling super (which will build the path) make sure to deform - // things if necessary. We depend on the skin which assures us that the - // boneTransforms are up to date. - skin?.deform(_vertices); - } - // Finally call super.update so the path commands can actually be rebuilt - // (when ComponentDirt.path is set). - super.update(dirt); - } -} diff --git a/lib/src/rive_core/shapes/polygon.dart b/lib/src/rive_core/shapes/polygon.dart deleted file mode 100644 index 9c44226..0000000 --- a/lib/src/rive_core/shapes/polygon.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/generated/shapes/polygon_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; - -export 'package:rive/src/generated/shapes/polygon_base.dart'; - -class Polygon extends PolygonBase { - @override - void cornerRadiusChanged(double from, double to) => markPathDirty(); - - @override - void pointsChanged(int from, int to) => markPathDirty(); - - @override - List> get vertices { - double ox = -originX * width + width / 2; - double oy = -originY * height + height / 2; - var vertexList = >[]; - var halfWidth = width / 2; - var halfHeight = height / 2; - var angle = -pi / 2; - var inc = 2 * pi / points; - for (int i = 0; i < points; i++) { - vertexList.add(StraightVertex.procedural() - ..x = ox + cos(angle) * halfWidth - ..y = oy + sin(angle) * halfHeight - ..radius = cornerRadius); - angle += inc; - } - return vertexList; - } -} diff --git a/lib/src/rive_core/shapes/rectangle.dart b/lib/src/rive_core/shapes/rectangle.dart deleted file mode 100644 index a827042..0000000 --- a/lib/src/rive_core/shapes/rectangle.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:rive/src/generated/shapes/rectangle_base.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; - -export 'package:rive/src/generated/shapes/rectangle_base.dart'; - -class Rectangle extends RectangleBase { - // - @override - List get vertices { - double ox = -originX * width; - double oy = -originY * height; - - return [ - StraightVertex.procedural() - ..x = ox - ..y = oy - ..radius = cornerRadiusTL, - StraightVertex.procedural() - ..x = ox + width - ..y = oy - ..radius = linkCornerRadius ? cornerRadiusTL : cornerRadiusTR, - StraightVertex.procedural() - ..x = ox + width - ..y = oy + height - ..radius = linkCornerRadius ? cornerRadiusTL : cornerRadiusBR, - StraightVertex.procedural() - ..x = ox - ..y = oy + height - ..radius = linkCornerRadius ? cornerRadiusTL : cornerRadiusBL, - ]; - } - - @override - void cornerRadiusTLChanged(double from, double to) => markPathDirty(); - - @override - void cornerRadiusTRChanged(double from, double to) => markPathDirty(); - - @override - void cornerRadiusBLChanged(double from, double to) => markPathDirty(); - - @override - void cornerRadiusBRChanged(double from, double to) => markPathDirty(); - - @override - void linkCornerRadiusChanged(bool from, bool to) { - markPathDirty(); - } -} diff --git a/lib/src/rive_core/shapes/shape.dart b/lib/src/rive_core/shapes/shape.dart deleted file mode 100644 index 3572999..0000000 --- a/lib/src/rive_core/shapes/shape.dart +++ /dev/null @@ -1,327 +0,0 @@ -import 'dart:ui' as ui; - -import 'package:collection/collection.dart'; -import 'package:rive/src/generated/shapes/shape_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/paint/linear_gradient.dart' as core; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; -import 'package:rive/src/rive_core/shapes/path.dart'; -import 'package:rive/src/rive_core/shapes/path_composer.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/shape_base.dart'; - -class Shape extends ShapeBase with ShapePaintContainer { - final Set paths = {}; - - bool _wantWorldPath = false; - bool _wantLocalPath = false; - bool get wantWorldPath => _wantWorldPath; - bool get wantLocalPath => _wantLocalPath; - bool _fillInWorld = false; - bool get fillInWorld => _fillInWorld; - - late PathComposer pathComposer; - Shape() { - pathComposer = PathComposer(this); - } - - ui.Path get fillPath => pathComposer.fillPath; - - // Build the bounds on demand, more efficient than re-computing whenever they - // change as bounds rarely have bearing at runtime (they will in some cases - // with constraints eventually). - AABB? _worldBounds; - AABB? _localBounds; - - AABB get worldBounds => _worldBounds ??= computeWorldBounds(); - - @override - AABB get localBounds => _localBounds ??= computeLocalBounds(); - - /// Let the shape know that any further call to get world/local bounds will - /// need to rebuild the cached bounds. - void markBoundsDirty() { - _worldBounds = _localBounds = null; - } - - @override - void onDirty(int mask) { - pathComposer.syncCollapse(); - super.onDirty(mask); - } - - bool addPath(Path path) { - paintChanged(); - var added = paths.add(path); - - return added; - } - - void _markComposerDirty() { - pathComposer.addDirt(ComponentDirt.path, recurse: true); - for (final constraint in constraints) { - constraint.addDirt(ComponentDirt.path); - } - // Stroke effects need to be rebuilt whenever the path composer rebuilds the - // compound path. - invalidateStrokeEffects(); - } - - void pathChanged(Path path) => _markComposerDirty(); - - void pathCollapseChanged() => pathComposer.pathCollapseChanged(); - - void paintChanged() { - addDirt(ComponentDirt.path); - _markBlendModeDirty(); - _markRenderOpacityDirty(); - - // Add world transform dirt to the direct dependents (don't recurse) as - // things like ClippingShape directly depend on their referenced Shape. This - // allows them to recompute any stored values which can change when the - // transformAffectsStroke property changes (whether the path is in world - // space or not). Consider using a different dirt type if this pattern is - // repeated. - for (final d in dependents) { - d.addDirt(ComponentDirt.worldTransform); - } - - // Path composer needs to update if we update the types of paths we want. - _markComposerDirty(); - } - - @override - bool addStroke(Stroke stroke) { - paintChanged(); - return super.addStroke(stroke); - } - - @override - bool removeStroke(Stroke stroke) { - paintChanged(); - return super.removeStroke(stroke); - } - - @override - void update(int dirt) { - super.update(dirt); - - // When the paint gets marked dirty, we need to sync the blend mode with the - // paints. - if (dirt & ComponentDirt.blendMode != 0) { - for (final fill in fills) { - fill.blendMode = blendMode; - } - for (final stroke in strokes) { - stroke.blendMode = blendMode; - } - } - - // RenderOpacity gets updated with the worldTransform (accumulates through - // hierarchy), so if we see worldTransform is dirty, update our internal - // render opacities. - if (dirt & ComponentDirt.worldTransform != 0) { - for (final fill in fills) { - fill.renderOpacity = renderOpacity; - } - for (final stroke in strokes) { - stroke.renderOpacity = renderOpacity; - } - } - // We update before the path composer so let's get our ducks in a row, what - // do we want? PathComposer depends on us so we're safe to update our - // desires here. - if (dirt & ComponentDirt.path != 0) { - // Recompute which paths we want. - _wantWorldPath = false; - _wantLocalPath = false; - for (final stroke in strokes) { - if (stroke.transformAffectsStroke) { - _wantLocalPath = true; - } else { - _wantWorldPath = true; - } - } - - // Update the gradients' paintsInWorldSpace properties based on whether - // the path we'll be feeding that at draw time is in world or local space. - // This is a good opportunity to do it as gradients depend on us so - // they'll update after us. - - // We optmistically first fill in the space we know the stroke will be in. - _fillInWorld = _wantWorldPath || !_wantLocalPath; - - // Gradients almost always fill in local space, unless they are bound to - // bones. - var mustFillLocal = fills.firstWhereOrNull( - (fill) => fill.paintMutator is core.LinearGradient, - ) != - null; - if (mustFillLocal) { - _fillInWorld = false; - _wantLocalPath = true; - } - - for (final fill in fills) { - var mutator = fill.paintMutator; - if (mutator is core.LinearGradient) { - mutator.paintsInWorldSpace = _fillInWorld; - } - } - - for (final stroke in strokes) { - var mutator = stroke.paintMutator; - if (mutator is core.LinearGradient) { - mutator.paintsInWorldSpace = !stroke.transformAffectsStroke; - } - } - } - } - - bool removePath(Path path) { - paintChanged(); - return paths.remove(path); - } - - AABB computeWorldBounds() { - var boundsPaths = paths.where((path) => path.hasBounds); - if (boundsPaths.isEmpty) { - return AABB.fromMinMax(worldTranslation, worldTranslation); - } - var path = boundsPaths.first; - AABB worldBounds = path.preciseComputeBounds(transform: path.pathTransform); - for (final path in boundsPaths.skip(1)) { - AABB.combine(worldBounds, worldBounds, - path.preciseComputeBounds(transform: path.pathTransform)); - } - return worldBounds; - } - - AABB computeBounds(Mat2D relativeTo) { - var boundsPaths = paths.where((path) => path.hasBounds); - if (boundsPaths.isEmpty) { - return AABB(); - } - var path = boundsPaths.first; - - AABB localBounds = path.preciseComputeBounds( - transform: Mat2D.multiply( - Mat2D(), - relativeTo, - path.pathTransform, - ), - ); - - for (final path in paths.skip(1)) { - AABB.combine( - localBounds, - localBounds, - path.preciseComputeBounds( - transform: Mat2D.multiply( - Mat2D(), - relativeTo, - path.pathTransform, - ), - ), - ); - } - return localBounds; - } - - AABB computeLocalBounds() { - var toTransform = Mat2D(); - if (!Mat2D.invert(toTransform, worldTransform)) { - Mat2D.setIdentity(toTransform); - } - return computeBounds(toTransform); - } - - @override - void blendModeValueChanged(int from, int to) => _markBlendModeDirty(); - - @override - void draw(ui.Canvas canvas) { - bool clipped = clip(canvas); - var path = pathComposer.fillPath; - if (!_fillInWorld) { - canvas.save(); - canvas.transform(worldTransform.mat4); - } - for (final fill in fills) { - fill.draw(canvas, path); - } - if (!_fillInWorld) { - canvas.restore(); - } - - // Strokes are slightly more complicated, they may want a local path. Note - // that we've already built this up during our update and processed any - // gradients to have their offsets in the correct transform space (see our - // update method). - for (final stroke in strokes) { - // stroke.draw(canvas, _pathComposer); - var transformAffectsStroke = stroke.transformAffectsStroke; - var path = transformAffectsStroke - ? pathComposer.localPath - : pathComposer.worldPath; - - if (transformAffectsStroke) { - // Get into world space. - canvas.save(); - canvas.transform(worldTransform.mat4); - stroke.draw(canvas, path); - canvas.restore(); - } else { - stroke.draw(canvas, path); - } - } - - if (clipped) { - canvas.restore(); - } - } - - void _markBlendModeDirty() => addDirt(ComponentDirt.blendMode); - void _markRenderOpacityDirty() => addDirt(ComponentDirt.worldTransform); - - @override - void onPaintMutatorChanged(ShapePaintMutator mutator) { - // The transform affects stroke property may have changed as we have a new - // mutator. - paintChanged(); - } - - @override - void onStrokesChanged() => paintChanged(); - - @override - void onFillsChanged() => paintChanged(); - - /// Since the PathComposer isn't in core, we need to let it know when to proxy - /// build dependencies. - @override - void buildDependencies() { - super.buildDependencies(); - pathComposer.buildDependencies(); - } - - /// Prep the [hitTester] for checking collision with the paths inside this - /// shape. - void fillHitTester(TransformingHitTester hitTester) { - for (final path in paths) { - if (!path.isCollapsed) { - hitTester.transform = path.pathTransform; - path.buildPath(hitTester); - } - } - } - - @override - bool propagateCollapse(bool collapse) { - propagateCollapseToChildren(collapse); - return super.propagateCollapse(collapse); - } -} diff --git a/lib/src/rive_core/shapes/shape_paint_container.dart b/lib/src/rive_core/shapes/shape_paint_container.dart deleted file mode 100644 index d7935d6..0000000 --- a/lib/src/rive_core/shapes/shape_paint_container.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:meta/meta.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/shapes/paint/fill.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/paint/stroke.dart'; -import 'package:rive_common/math.dart'; - -/// An abstraction to give a common interface to any component that can contain -/// fills and strokes. -abstract class ShapePaintContainer { - final Set fills = {}; - - final Set strokes = {}; - - /// Called whenever a new paint mutator is added/removed from the shape paints - /// (for example a linear gradient is added to a stroke). - void onPaintMutatorChanged(ShapePaintMutator mutator); - - /// Called when a fill is added or removed. - @protected - void onFillsChanged(); - - /// Called when a stroke is added or remoevd. - @protected - void onStrokesChanged(); - - /// Called whenever the compound path for this shape is changed so that the - /// effects can be invalidated on all the strokes. - void invalidateStrokeEffects() { - for (final stroke in strokes) { - stroke.invalidateEffects(); - } - } - - bool addFill(Fill fill) { - if (fills.add(fill)) { - onFillsChanged(); - return true; - } - return false; - } - - bool removeFill(Fill fill) { - if (fills.remove(fill)) { - onFillsChanged(); - return true; - } - return false; - } - - bool addStroke(Stroke stroke) { - if (strokes.add(stroke)) { - onStrokesChanged(); - return true; - } - return false; - } - - bool removeStroke(Stroke stroke) { - if (strokes.remove(stroke)) { - onStrokesChanged(); - return true; - } - return false; - } - - /// These usually gets auto implemented as this mixin is meant to be added to - /// a ComponentBase. This way the implementor doesn't need to cast - /// ShapePaintContainer to ContainerComponent/Shape/Artboard/etc. - bool addDirt(int value, {bool recurse = false}); - - bool addDependent(Component dependent, {Component? via}); - void appendChild(Component child); - Mat2D get worldTransform; - Vec2D get worldTranslation; -} diff --git a/lib/src/rive_core/shapes/star.dart b/lib/src/rive_core/shapes/star.dart deleted file mode 100644 index accf691..0000000 --- a/lib/src/rive_core/shapes/star.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'dart:math'; - -import 'package:rive/src/generated/shapes/star_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; - -export 'package:rive/src/generated/shapes/star_base.dart'; - -class Star extends StarBase { - @override - void innerRadiusChanged(double from, double to) => markPathDirty(); - - @override - List> get vertices { - double ox = -originX * width + width / 2; - double oy = -originY * height + height / 2; - - var actualPoints = points * 2; - var vertexList = >[]; - var halfWidth = width / 2; - var halfHeight = height / 2; - var innerHalfWidth = width * innerRadius / 2; - var innerHalfHeight = height * innerRadius / 2; - var angle = -pi / 2; - var inc = 2 * pi / actualPoints; - while (vertexList.length < actualPoints) { - vertexList.add(StraightVertex.procedural() - ..x = ox + cos(angle) * halfWidth - ..y = oy + sin(angle) * halfHeight - ..radius = cornerRadius); - angle += inc; - vertexList.add(StraightVertex.procedural() - ..x = ox + cos(angle) * innerHalfWidth - ..y = oy + sin(angle) * innerHalfHeight - ..radius = cornerRadius); - angle += inc; - } - return vertexList; - } -} diff --git a/lib/src/rive_core/shapes/straight_vertex.dart b/lib/src/rive_core/shapes/straight_vertex.dart deleted file mode 100644 index 77265f2..0000000 --- a/lib/src/rive_core/shapes/straight_vertex.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/shapes/straight_vertex_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/straight_vertex_base.dart'; - -class StraightVertex extends StraightVertexBase { - /// Nullable because not all vertices have weight, they only have it when the - /// shape they are in is bound to bones. - Weight? _weight; - - StraightVertex(); - - /// Makes a vertex that is disconnected from core. - StraightVertex.procedural() { - InternalCoreHelper.markValid(this); - } - - @override - String toString() => 'x[$x], y[$y], r[$radius]'; - - @override - void radiusChanged(double from, double to) { - path?.markPathDirty(); - } - - @override - void childAdded(Component component) { - super.childAdded(component); - if (component is Weight) { - _weight = component; - } - } - - @override - void childRemoved(Component component) { - super.childRemoved(component); - if (_weight == component) { - _weight = null; - } - } - - @override - Vec2D get renderTranslation => - _weight?.translation ?? super.renderTranslation; -} diff --git a/lib/src/rive_core/shapes/triangle.dart b/lib/src/rive_core/shapes/triangle.dart deleted file mode 100644 index 7b21422..0000000 --- a/lib/src/rive_core/shapes/triangle.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:rive/src/generated/shapes/triangle_base.dart'; -import 'package:rive/src/rive_core/shapes/path_vertex.dart'; -import 'package:rive/src/rive_core/shapes/straight_vertex.dart'; - -/// Export the Base class for external use (e.g. rive.dart) -export 'package:rive/src/generated/shapes/triangle_base.dart'; - -class Triangle extends TriangleBase { - @override - List get vertices { - double ox = -originX * width; - double oy = -originY * height; - - return [ - StraightVertex.procedural() - ..x = ox + width / 2 - ..y = oy, - StraightVertex.procedural() - ..x = ox + width - ..y = oy + height, - StraightVertex.procedural() - ..x = ox - ..y = oy + height - ]; - } -} diff --git a/lib/src/rive_core/shapes/vertex.dart b/lib/src/rive_core/shapes/vertex.dart deleted file mode 100644 index 9b29cc0..0000000 --- a/lib/src/rive_core/shapes/vertex.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/shapes/vertex_base.dart'; -import 'package:rive/src/rive_core/bones/weight.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/shapes/vertex_base.dart'; - -abstract class Vertex extends VertexBase { - T? _weight; - T? get weight => _weight; - - Vec2D get translation => Vec2D.fromValues(x, y); - Vec2D get renderTranslation => weight?.translation ?? translation; - - set translation(Vec2D value) { - x = value.x; - y = value.y; - } - - @override - void xChanged(double from, double to) { - markGeometryDirty(); - } - - void markGeometryDirty(); - - @override - void yChanged(double from, double to) { - markGeometryDirty(); - } - - @override - String toString() { - return translation.toString(); - } - - @override - void childAdded(Component component) { - super.childAdded(component); - if (component is T) { - _weight = component; - } - } - - @override - void childRemoved(Component component) { - super.childRemoved(component); - if (_weight == component) { - _weight = null; - } - } - - /// Deform only gets called when we are weighted. - void deform(Mat2D world, Float32List boneTransforms) { - Weight.deform(x, y, weight!.indices, weight!.values, world, boneTransforms, - _weight!.translation); - } - - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/solo.dart b/lib/src/rive_core/solo.dart deleted file mode 100644 index 27d2286..0000000 --- a/lib/src/rive_core/solo.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:rive/src/generated/solo_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; - -export 'package:rive/src/generated/solo_base.dart'; - -class Solo extends SoloBase { - Component? _activeComponent; - @override - void activeComponentIdChanged(int from, int to) => - activeComponent = context.resolve(to); - - Component? get activeComponent => _activeComponent; - - set activeComponent(Component? value) { - if (_activeComponent == value) { - return; - } - - _activeComponent = value; - activeComponentId = value?.id ?? Core.missingId; - propagateCollapseToChildren(isCollapsed); - } - - @override - void propagateCollapseToChildren(bool collapse) { - // Some child components shouldn't be considered as part of the solo set - // as they are more aking to properties of the solo itself. For those - // components, simply pass on the collapse value of the solo itself. - for (final child in children) { - if (child is Constraint || child is ClippingShape) { - child.propagateCollapse(collapse); - continue; - } - - // This child is part of the solo set so only make it active if it's the - // currently marked solo object. - child.propagateCollapse(collapse || child != _activeComponent); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - propagateCollapseToChildren(isCollapsed); - } - - @override - void childAdded(Component child) { - super.childAdded(child); - propagateCollapseToChildren(isCollapsed); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - if (activeComponentId != Core.missingId) { - activeComponent = context.resolve(activeComponentId); - } - } - - @override - void onAdded() { - super.onAdded(); - propagateCollapseToChildren(isCollapsed); - } -} diff --git a/lib/src/rive_core/state_machine_controller.dart b/lib/src/rive_core/state_machine_controller.dart deleted file mode 100644 index 1e5ef31..0000000 --- a/lib/src/rive_core/state_machine_controller.dart +++ /dev/null @@ -1,1076 +0,0 @@ -library rive_core; - -import 'dart:collection'; -import 'dart:math'; - -import 'package:collection/collection.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/animation_reset_factory.dart' - as animation_reset_factory; -import 'package:rive/src/rive_core/animation/animation_state.dart'; -import 'package:rive/src/rive_core/animation/animation_state_instance.dart'; -import 'package:rive/src/rive_core/animation/any_state.dart'; -import 'package:rive/src/rive_core/animation/entry_state.dart'; -import 'package:rive/src/rive_core/animation/exit_state.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_instance.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_fire_event.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; -import 'package:rive/src/rive_core/animation/state_machine_listener.dart'; -import 'package:rive/src/rive_core/animation/state_machine_trigger.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/audio_event.dart'; -import 'package:rive/src/rive_core/audio_player.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/layer_state_flags.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/rive_core/node.dart'; -import 'package:rive/src/rive_core/rive_animation_controller.dart'; -import 'package:rive/src/rive_core/shapes/shape.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/runtime_event.dart'; -import 'package:rive_common/math.dart'; - -/// Callback signature for state machine state changes -typedef OnStateChange = void Function( - String stateMachineName, String stateName); - -/// Callback signature for nested input changes -typedef OnInputValueChange = void Function(int id, dynamic value); - -/// Callback signature for layer state changes -typedef OnLayerStateChange = void Function(LayerState); - -/// Callback signature for events firing. -typedef OnEvent = void Function(RiveEvent); - -class LayerController { - final StateMachineLayer layer; - final StateInstance anyStateInstance; - final CoreContext core; - - StateInstance? _currentState; - StateInstance? _stateFrom; - bool _holdAnimationFrom = false; - StateTransition? _transition; - bool _transitionCompleted = false; - double _mix = 1.0; - double _mixFrom = 1.0; - - /// Optional callback which is called when a state changes - /// Takes the state machine name and state name - final OnLayerStateChange? onLayerStateChange; - - final StateMachineController controller; - - animation_reset_factory.AnimationReset? animationReset; - - LayerController( - this.controller, - this.layer, { - required this.core, - this.onLayerStateChange, - }) : assert(layer.anyState != null), - anyStateInstance = layer.anyState!.makeInstance() { - _changeState(layer.entryState); - } - - void _fireEvents(Iterable fireEvents) { - for (final fireEvent in fireEvents) { - var event = core.resolve(fireEvent.eventId); - if (event != null) { - controller.reportEvent(event); - } - } - } - - bool _canChangeState(LayerState? state) { - return state != _currentState?.state; - } - - void _changeState(LayerState? state, {StateTransition? transition}) { - assert(state is! AnyState, - 'We don\'t allow making the AnyState an active state.'); - assert(state != _currentState?.state, 'Cannot change to state to self.'); - var currentState = _currentState; - if (currentState != null) { - _fireEvents(currentState.state.eventsAt(StateMachineFireOccurance.atEnd)); - currentState.dispose(); - } - var nextState = state; - - if (nextState != null) { - _currentState = nextState.makeInstance(); - _fireEvents(nextState.eventsAt(StateMachineFireOccurance.atStart)); - } else { - _currentState = null; - } - } - - void dispose() { - _changeState(null); - anyStateInstance.dispose(); - } - - bool get isTransitioning => - _transition != null && - _stateFrom != null && - _transition!.duration != 0 && - _mix != 1; - - void _updateMix(double elapsedSeconds) { - var transition = _transition; - if (transition != null && _stateFrom != null && transition.duration != 0) { - _mix = (_mix + elapsedSeconds / transition.mixTime(_stateFrom!.state)) - .clamp(0, 1) - .toDouble(); - - if (_mix == 1 && !_transitionCompleted) { - _transitionCompleted = true; - _clearAnimationReset(); - _fireEvents(transition.eventsAt(StateMachineFireOccurance.atEnd)); - } - } else { - _mix = 1; - } - } - - void _apply(CoreContext core) { - animationReset?.apply(core); - if (_holdAnimation != null) { - _holdAnimation!.apply(_holdTime, coreContext: core, mix: _mixFrom); - _holdAnimation = null; - } - - final interpolator = _transition?.interpolator; - - if (_stateFrom != null && _mix < 1) { - final _applyMixFrom = interpolator?.transform(_mixFrom) ?? _mixFrom; - _stateFrom!.apply(core, _applyMixFrom); - } - if (_currentState != null) { - final _applyMix = interpolator?.transform(_mix) ?? _mix; - _currentState!.apply(core, _applyMix); - } - } - - bool apply(CoreContext core, double elapsedSeconds) { - if (_currentState != null) { - _currentState!.advance(elapsedSeconds, controller); - } - - _updateMix(elapsedSeconds); - - if (_stateFrom != null && _mix < 1) { - // This didn't advance during our updateState, but it should now that we - // realize we need to mix it in. - if (!_holdAnimationFrom) { - _stateFrom!.advance(elapsedSeconds, controller); - } - } - _apply(core); - - for (int i = 0; updateState(i != 0); i++) { - _apply(core); - - if (i == 100) { - // Escape hatch, let the user know their logic is causing some kind of - // recursive condition. - print('StateMachineController.apply exceeded max iterations.'); - - return false; - } - } - - // give the current state the oportunity to clear spilled time, so that we - // do not carry this over into another iteration. - _currentState?.clearSpilledTime(); - - // We still need to mix in the current state if mix value is less than one - // as it still contributes to the end result. - // It may not need to advance but it does need to apply. - return _mix != 1 || _waitingForExit || (_currentState?.keepGoing ?? false); - } - - bool _waitingForExit = false; - LinearAnimation? _holdAnimation; - double _holdTime = 0; - - bool updateState(bool ignoreTriggers) { - if (isTransitioning && _transition!.enableEarlyExit == false) { - return false; - } - _waitingForExit = false; - if (tryChangeState(anyStateInstance, ignoreTriggers)) { - return true; - } - - return tryChangeState(_currentState, ignoreTriggers); - } - - StateTransition? _findRandomTransition(StateInstance stateFrom, - bool ignoreTriggers, ViewModelInstance? viewModelInstance) { - double totalWeight = 0; - final transitions = stateFrom.state.transitions; - for (final transition in transitions) { - var allowed = transition.allowed(stateFrom, controller._inputValues, - ignoreTriggers, viewModelInstance); - if (allowed == AllowTransition.yes && - _canChangeState(transition.stateTo)) { - transition.evaluatedRandomWeight = transition.randomWeight; - totalWeight += transition.randomWeight; - // If random is not active we don't search for more candidates - } else { - transition.evaluatedRandomWeight = 0; - if (allowed == AllowTransition.waitingForExit) { - _waitingForExit = true; - } - } - } - if (totalWeight > 0) { - final random = Random().nextDouble() * totalWeight; - double currentWeight = 0; - int index = 0; - while (index < transitions.length) { - final transitionWeight = - transitions.elementAt(index).evaluatedRandomWeight; - if (currentWeight + transitionWeight > random) { - break; - } - currentWeight += transitionWeight; - index += 1; - } - assert(index < transitions.length); - final transition = transitions.elementAt(index); - return transition; - } - return null; - } - - StateTransition? _findAllowedTransition(StateInstance stateFrom, - bool ignoreTriggers, ViewModelInstance? viewModelInstance) { - if (stateFrom.state.flags & LayerStateFlags.random == - LayerStateFlags.random) { - return _findRandomTransition( - stateFrom, ignoreTriggers, viewModelInstance); - } - final transitions = stateFrom.state.transitions; - for (final transition in transitions) { - var allowed = transition.allowed(stateFrom, controller._inputValues, - ignoreTriggers, viewModelInstance); - if (allowed == AllowTransition.yes && - _canChangeState(transition.stateTo)) { - return transition; - } else if (allowed == AllowTransition.waitingForExit) { - _waitingForExit = true; - } - } - return null; - } - - // It provides an instance of AnimationReset that is used to reset values on - // every frame. This generates a more linear and predictable mix of states - // during transitions. - void _buildAnimationResetForTransition() { - animationReset = - animation_reset_factory.fromStates(_stateFrom, _currentState, core); - } - - void _clearAnimationReset() { - if (animationReset != null) { - animation_reset_factory.release(animationReset!); - animationReset = null; - } - } - - bool tryChangeState(StateInstance? stateFrom, bool ignoreTriggers) { - if (stateFrom == null) { - return false; - } - - var outState = _currentState; - final transition = _findAllowedTransition( - stateFrom, ignoreTriggers, controller._artboard?.viewModelInstance); - if (transition != null) { - _clearAnimationReset(); - _changeState(transition.stateTo, transition: transition); - // Take transition - _transition = transition; - - _fireEvents(transition.eventsAt(StateMachineFireOccurance.atStart)); - // Immediately fire end events if transition has no duration. - if (transition.duration == 0) { - _transitionCompleted = true; - _fireEvents(transition.eventsAt(StateMachineFireOccurance.atEnd)); - } else { - _transitionCompleted = false; - } - - _stateFrom = outState; - - if (!_transitionCompleted) { - _buildAnimationResetForTransition(); - } - - // If we had an exit time and wanted to pause on exit, make sure to hold - // the exit time. Delegate this to the transition by telling it that it - // was completed. - if (outState != null && transition.applyExitCondition(outState)) { - // Make sure we apply this state. - var inst = (outState as AnimationStateInstance).animationInstance; - _holdAnimation = inst.animation; - _holdTime = inst.time; - } - _mixFrom = _mix; - - // Keep mixing last animation that was mixed in. - if (_mix != 0) { - _holdAnimationFrom = transition.pauseOnExit; - } - if (outState is AnimationStateInstance) { - var spilledTime = outState.animationInstance.spilledTime; - _currentState?.advance(spilledTime, controller); - } - - _mix = 0; - _updateMix(0); - // Make sure to reset _waitingForExit to false if we succeed at taking a - // transition. - _waitingForExit = false; - // State has changed, fire the callback if there's one - if (_currentState != null) { - onLayerStateChange?.call(_currentState!.state); - } - return true; - } - return false; - } -} - -class StateMachineController extends RiveAnimationController - implements KeyedCallbackReporter { - final StateMachine stateMachine; - final _inputValues = HashMap(); - final layerControllers = []; - final _reportedEvents = []; - // Keep a seperate list of nested events because we also need to store - // the source of the nested event in order to compare to listener target - final Map> _reportedNestedEvents = {}; - - /// Optional callback for state changes - final OnStateChange? onStateChange; - - /// Optional callback for input value changes - OnInputValueChange? onInputValueChange; - - final _eventListeners = {}; - AudioPlayer? _audioPlayer; - - AudioPlayer get audioPlayer => (_audioPlayer ??= AudioPlayer.make())!; - - AudioPlayer? get peekAudioPlayer => _audioPlayer; - - List get reportedEvents => _reportedEvents; - - /// Constructor that takes a state machine and optional state change callback - StateMachineController( - this.stateMachine, { - @Deprecated('Use `addEventListener` instead.') this.onStateChange, - }); - - /// Adds a Rive event listener to this controller. - /// - /// Documentation: https://rive.app/community/doc/rive-events/docbOnaeffgr - void addEventListener(OnEvent callback) => _eventListeners.add(callback); - - /// Removes listener from this controller. - void removeEventListener(OnEvent callback) => - _eventListeners.remove(callback); - - void reportEvent(Event event) { - _reportedEvents.add(event); - - isActive = true; - } - - void reportNestedEvent(Event event, Node source) { - if (_reportedNestedEvents[source.id] == null) { - _reportedNestedEvents[source.id] = []; - } - _reportedNestedEvents[source.id]!.add(event); - } - - bool hasListenerWithTarget(Node target) { - var listeners = stateMachine.listeners.whereType(); - for (final listener in listeners) { - var listenerTarget = artboard?.context.resolve(listener.targetId); - if (listenerTarget == target) { - return true; - } - } - return false; - } - - bool tryChangeState() { - bool didChangeState = false; - for (final layer in layerControllers) { - if (layer.updateState(true)) { - didChangeState = true; - } - } - return didChangeState; - } - - void _clearLayerControllers() { - for (final layer in layerControllers) { - layer.dispose(); - } - layerControllers.clear(); - } - - /// Handles state change callbacks - void _onStateChange(LayerState layerState) => - - /// See https://github.com/flutter/flutter/issues/103561#issuecomment-1129356149 - _ambiguate(SchedulerBinding.instance)?.addPostFrameCallback((_) { - String stateName = 'unknown'; - if (layerState is AnimationState && layerState.animation != null) { - stateName = layerState.animation!.name; - } else if (layerState is EntryState) { - stateName = 'EntryState'; - } else if (layerState is AnyState) { - stateName = 'EntryState'; - } else if (layerState is ExitState) { - stateName = 'ExitState'; - } - - onStateChange?.call(stateMachine.name, stateName); - }); - - late List<_HitComponent> hitComponents = []; - final List<_ListenerGroup> listenerGroups = []; - - Artboard? _artboard; - - /// The artboard that this state machine controller is manipulating. - Artboard? get artboard => _artboard; - - late CoreContext core; - - @override - bool init(CoreContext core) { - this.core = core; - - _clearLayerControllers(); - - for (final layer in stateMachine.layers) { - layerControllers.add(LayerController( - this, - layer, - core: core, - onLayerStateChange: _onStateChange, - )); - } - - // Make sure triggers are all reset. - advanceInputs(); - - // Initialize all events. - HashMap hitShapeLookup = HashMap(); - for (final event in stateMachine.listeners) { - if (event is StateMachineListener) { - if (event.listenerType == ListenerType.event) { - continue; - } - // Resolve target on this artboard instance. - var node = core.resolve(event.targetId); - if (node == null) { - continue; - } - _ListenerGroup listenerGroup = _ListenerGroup(event); - listenerGroups.add(listenerGroup); - - node.forAll((component) { - if (component is Shape) { - var hitShape = hitShapeLookup[component]; - if (hitShape == null) { - hitShapeLookup[component] = hitShape = _HitShape(component, this); - } - hitShape.addListener(listenerGroup); - } - // Keep iterating so we find all shapes. - return true; - }); - } - } - hitShapeLookup.values.toList().forEach(hitComponents.add); - - _artboard = core as RuntimeArtboard; - - if (_artboard != null) { - for (final nestedArtboard in _artboard!.activeNestedArtboards) { - if (nestedArtboard.hasNestedStateMachine) { - hitComponents.add(_HitNestedArtboard(nestedArtboard, this)); - } - } - } - _sortHittableComponents(); - return super.init(core); - } - - @override - void dispose() { - _clearLayerControllers(); - super.dispose(); - - _audioPlayer?.dispose(); - _audioPlayer = null; - } - - @protected - void advanceInputs() { - for (final input in stateMachine.inputs) { - if (input is StateMachineTrigger) { - _inputValues[input.id] = false; - } - } - } - - dynamic getInputValue(int id) => _inputValues[id]; - void setInputValue(int id, dynamic value) { - _inputValues[id] = value; - isActive = true; - - if (onInputValueChange != null) { - onInputValueChange!(id, value); - } - } - - void _sortHittableComponents() { - Drawable? firstDrawable = artboard?.firstDrawable; - if (firstDrawable != null) { - // walk to the end, so we can visit in reverse-order - while (firstDrawable!.prev != null) { - firstDrawable = firstDrawable.prev; - } - - int hitComponentsCount = hitComponents.length; - int currentSortedIndex = 0; - while (firstDrawable != null) { - for (var i = currentSortedIndex; i < hitComponentsCount; i++) { - if (hitComponents.elementAt(i).component == firstDrawable) { - if (currentSortedIndex != i) { - hitComponents.swap(i, currentSortedIndex); - } - currentSortedIndex++; - break; - } - } - if (currentSortedIndex == hitComponentsCount) { - break; - } - firstDrawable = firstDrawable.next; - } - } - } - - @override - void apply(CoreContext core, double elapsedSeconds) { - if (artboard?.hasChangedDrawOrderInLastUpdate ?? false) { - _sortHittableComponents(); - } - - bool keepGoing = false; - for (final layerController in layerControllers) { - if (layerController.apply(core, elapsedSeconds)) { - keepGoing = true; - } - } - advanceInputs(); - isActive = keepGoing; - - applyEvents(); - } - - void applyEvents() { - // Callback for events. - if (_reportedEvents.isNotEmpty || _reportedNestedEvents.isNotEmpty) { - var events = _reportedEvents.toList(growable: false); - var nestedEvents = Map>.from(_reportedNestedEvents); - _reportedEvents.clear(); - _reportedNestedEvents.clear(); - - var listeners = stateMachine.listeners.whereType(); - listeners.forEach((listener) { - var listenerTarget = artboard?.context.resolve(listener.targetId); - if (listener.listenerType == ListenerType.event) { - // Handle events from this artboard if it is the target - if (listenerTarget == artboard) { - events.forEach((event) { - if (listener.eventId == event.id) { - listener.performChanges(this, Vec2D(), Vec2D()); - } - }); - } else { - // Handle events from nested artboards - nestedEvents.forEach((targetId, eventList) { - if (listener.targetId == targetId) { - eventList.forEach((nestedEvent) { - if (listener.eventId == nestedEvent.id) { - listener.performChanges(this, Vec2D(), Vec2D()); - } - }); - } - }); - } - } - }); - - var riveEvents = []; - - for (final event in events) { - if (event is AudioEvent && event.asset != null) { - event.play(audioPlayer); - } - riveEvents.add(RiveEvent.fromCoreEvent(event)); - } - _eventListeners.toList().forEach((listener) { - riveEvents.forEach(listener); - }); - } - } - - HitResult _processEvent( - Vec2D position, { - PointerEvent? pointerEvent, - ListenerType? hitEvent, - }) { - var artboard = this.artboard; - if (artboard == null) { - return HitResult.none; - } - if (artboard.frameOrigin) { - // ignore: parameter_assignments - position = position - - Vec2D.fromValues( - artboard.width * artboard.originX, - artboard.height * artboard.originY, - ); - } - - for (final listenerGroup in listenerGroups) { - listenerGroup.reset(); - } - for (final hitComponent in hitComponents) { - hitComponent.prepareEvent(position, hitEvent); - } - bool hitSomething = false; - bool hitOpaque = false; - HitResult hitResult = HitResult.none; - for (final hitComponent in hitComponents) { - hitResult = hitComponent.processEvent(position, - hitEvent: hitEvent, pointerEvent: pointerEvent, canHit: !hitOpaque); - if (hitResult != HitResult.none) { - hitSomething = true; - if (hitResult == HitResult.hitOpaque) { - hitOpaque = true; - } - } - } - return hitSomething - ? hitOpaque - ? HitResult.hitOpaque - : HitResult.hit - : HitResult.none; - } - - /// Hit testing. If any listeners were hit, returns true. - bool hitTest( - Vec2D position, { - PointerEvent? pointerEvent, - ListenerType? hitEvent, - }) { - var artboard = this.artboard; - if (artboard == null) { - return false; - } - if (artboard.frameOrigin) { - // ignore: parameter_assignments - position = position - - Vec2D.fromValues( - artboard.width * artboard.originX, - artboard.height * artboard.originY, - ); - } - - for (final hitComponent in hitComponents) { - if (hitComponent.hitTest(position)) { - return true; - } - } - - return false; // no hit targets found - } - - HitResult pointerMove(Vec2D position) => _processEvent( - position, - hitEvent: ListenerType.move, - ); - - HitResult pointerDown(Vec2D position, PointerDownEvent event) { - final hitResult = _processEvent( - position, - hitEvent: ListenerType.down, - pointerEvent: event, - ); - return hitResult; - } - - HitResult pointerUp(Vec2D position) => _processEvent( - position, - hitEvent: ListenerType.up, - ); - - HitResult pointerExit(Vec2D position) => _processEvent( - position, - hitEvent: ListenerType.exit, - ); - - HitResult pointerEnter(Vec2D position) => _processEvent( - position, - hitEvent: ListenerType.enter, - ); - - /// Implementation of interface that reports which time based events have - /// elapsed on a timeline within this state machine. - @override - void reportKeyedCallback( - int objectId, int propertyKey, double elapsedSeconds) { - var coreObject = core.resolve(objectId); - if (coreObject != null) { - RiveCoreContext.setCallback( - coreObject, - propertyKey, - CallbackData(this, delay: elapsedSeconds), - ); - } - } -} - -enum HitResult { - none, - hit, - hitOpaque, -} - -class _ListenerGroup { - final StateMachineListener listener; - bool _isConsumed = false; - bool _isHovered = false; - bool _prevIsHovered = false; - GestureClickPhase clickPhase = GestureClickPhase.out; - final Vec2D previousPosition = Vec2D(); - - _ListenerGroup(this.listener); - void consume() { - _isConsumed = true; - } - - void hover() { - _isHovered = true; - } - - void unhover() { - _isHovered = false; - } - - void reset() { - _isConsumed = false; - _prevIsHovered = _isHovered; - _isHovered = false; - if (clickPhase == GestureClickPhase.clicked) { - clickPhase = GestureClickPhase.out; - } - } - - bool isConsumed() { - return _isConsumed; - } - - bool isHovered() { - return _isHovered; - } - - bool prevHovered() { - return _prevIsHovered; - } -} - -class _HitComponent { - final Component component; - final StateMachineController controller; - HitResult processEvent( - Vec2D position, { - PointerEvent? pointerEvent, - ListenerType? hitEvent, - bool canHit = true, - }) { - return HitResult.none; - } - - void prepareEvent(Vec2D position, ListenerType? hitType) {} - - bool hitTest(Vec2D position) { - return false; - } - - _HitComponent(this.component, this.controller); -} - -/// Representation of a Shape from the Artboard Instance and all the events it -/// triggers. Allows tracking hover and performing hit detection only once on -/// shapes that trigger multiple events. -class _HitShape extends _HitComponent { - final Shape shape; - double hitRadius = 2; - bool isHovered = false; - bool canEarlyOut = true; - bool hasDownListener = false; - bool hasUpListener = false; - List<_ListenerGroup> listenerGroups = []; - - _HitShape(this.shape, StateMachineController controller) - : super(shape, controller) { - canEarlyOut = !shape.isTargetOpaque; - } - - @override - bool hitTest(Vec2D position) { - var shape = component as Shape; - var bounds = shape.worldBounds; - - // Quick reject - if (bounds.contains(position)) { - var hitArea = IAABB( - (position.x - hitRadius).round(), - (position.y - hitRadius).round(), - (position.x + hitRadius).round(), - (position.y + hitRadius).round(), - ); - // Make hit tester. - var hitTester = TransformingHitTester(hitArea); - shape.fillHitTester(hitTester); - return hitTester.test(); // exit early - } - return false; - } - - @override - void prepareEvent(Vec2D position, ListenerType? hitType) { - if (canEarlyOut && - (hitType != ListenerType.down || !hasDownListener) && - (hitType != ListenerType.up || !hasUpListener)) { - return; - } - isHovered = hitTest(position); - - // iterate all listeners associated with this hit shape - if (isHovered) { - for (final listenerGroup in listenerGroups) { - listenerGroup.hover(); - } - } - } - - @override - HitResult processEvent( - Vec2D position, { - PointerEvent? pointerEvent, - ListenerType? hitEvent, - bool canHit = true, - }) { - if (canEarlyOut && - (hitEvent != ListenerType.down || !hasDownListener) && - (hitEvent != ListenerType.up || !hasUpListener)) { - return HitResult.none; - } - - var shape = component as Shape; - - // iterate all events associated with this hit shape - for (final listenerGroup in listenerGroups) { - if (listenerGroup.isConsumed()) { - continue; - } - // Because each group is tested individually for its hover state, a group - // could be marked "incorrectly" as hovered at this point. - // But once we iterate each element in the drawing order, that group can - // be occluded by an opaque target on top of it. - // So although it is hovered in isolation, it shouldn't be considered as - // hovered in the full context. - // In this case, we unhover the group so it is not marked as previously - // hovered. - if (!canHit && listenerGroup.isHovered()) { - listenerGroup.unhover(); - } - final isGroupHovered = canHit && listenerGroup.isHovered(); - bool hoverChange = listenerGroup.prevHovered() != isGroupHovered; - // If hover has changes, it means that the element is hovered for the - // first time. Previous positions need to be reset to avoid jumps. - if (hoverChange && isGroupHovered) { - listenerGroup.previousPosition.x = position.x; - listenerGroup.previousPosition.y = position.y; - } - // Handle click gesture phases. A click gesture has two phases. - // First one attached to a pointer down actions, second one attached to a - // pointer up action. Both need to act on a shape of the listener group. - if (isGroupHovered) { - if (hitEvent == ListenerType.down) { - listenerGroup.clickPhase = GestureClickPhase.down; - } else if (hitEvent == ListenerType.up && - listenerGroup.clickPhase == GestureClickPhase.down) { - listenerGroup.clickPhase = GestureClickPhase.clicked; - } - } else { - if (hitEvent == ListenerType.down || hitEvent == ListenerType.up) { - listenerGroup.clickPhase = GestureClickPhase.out; - } - } - // Always update hover states regardless of which specific event type - // we're trying to trigger. - // If hover has changed and: - // - it's hovering and the listener is of type enter - // - it's not hovering and the listener is of type exit - final listener = listenerGroup.listener; - if (hoverChange && - ((isGroupHovered && listener.listenerType == ListenerType.enter) || - (!isGroupHovered && - listener.listenerType == ListenerType.exit))) { - listener.performChanges( - controller, position, listenerGroup.previousPosition); - controller.isActive = true; - listenerGroup.consume(); - } - // Perform changes if: - // - the click gesture is complete and the listener is of type click - // - the event type matches the listener type and it is hovering the group - if ((listenerGroup.clickPhase == GestureClickPhase.clicked && - listener.listenerType == ListenerType.click) || - (isGroupHovered && hitEvent == listener.listenerType)) { - listener.performChanges( - controller, position, listenerGroup.previousPosition); - controller.isActive = true; - listenerGroup.consume(); - } - listenerGroup.previousPosition.x = position.x; - listenerGroup.previousPosition.y = position.y; - } - return isHovered && canHit - ? shape.isTargetOpaque - ? HitResult.hitOpaque - : HitResult.hit - : HitResult.none; - } - - void addListener(_ListenerGroup listenerGroup) { - final listener = listenerGroup.listener; - final listenerType = listener.listenerType; - if (listenerType == ListenerType.enter || - listenerType == ListenerType.exit || - listenerType == ListenerType.move) { - canEarlyOut = false; - } else { - if (listenerType == ListenerType.down || - listenerType == ListenerType.click) { - hasDownListener = true; - } - if (listenerType == ListenerType.up || - listenerType == ListenerType.click) { - hasUpListener = true; - } - } - listenerGroups.add(listenerGroup); - } -} - -class _HitNestedArtboard extends _HitComponent { - final NestedArtboard nestedArtboard; - _HitNestedArtboard(this.nestedArtboard, StateMachineController controller) - : super(nestedArtboard, controller); - - @override - bool hitTest(Vec2D position) { - var nestedPosition = nestedArtboard.worldToLocal(position); - if (nestedArtboard.isCollapsed) { - return false; - } - if (nestedPosition == null) { - // Mounted artboard isn't ready or has a 0 scale transform. - return false; - } - for (final nestedStateMachine - in nestedArtboard.animations.whereType()) { - if (nestedStateMachine.hitTest(nestedPosition)) { - return true; // exit early - } - } - return false; - } - - @override - HitResult processEvent( - Vec2D position, { - PointerEvent? pointerEvent, - ListenerType? hitEvent, - bool canHit = true, - }) { - HitResult hitResult = HitResult.none; - if (nestedArtboard.isCollapsed) { - return hitResult; - } - var nestedPosition = nestedArtboard.worldToLocal(position); - if (nestedPosition == null) { - // Mounted artboard isn't ready or has a 0 scale transform. - return hitResult; - } - for (final nestedStateMachine - in nestedArtboard.animations.whereType()) { - if (canHit) { - switch (hitEvent) { - case ListenerType.down: - hitResult = nestedStateMachine.pointerDown( - nestedPosition, - pointerEvent as PointerDownEvent, - ); - break; - case ListenerType.up: - hitResult = nestedStateMachine.pointerUp(nestedPosition); - break; - default: - hitResult = nestedStateMachine.pointerMove(nestedPosition); - break; - } - } else { - nestedStateMachine.pointerExit(nestedPosition); - } - } - return hitResult; - } -} - -/// This allows a value of type T or T? -/// to be treated as a value of type T?. -/// -/// We use this so that APIs that have become -/// non-nullable can still be used with `!` and `?` -/// to support older versions of the API as well. -T? _ambiguate(T? value) => value; diff --git a/lib/src/rive_core/state_transition_flags.dart b/lib/src/rive_core/state_transition_flags.dart deleted file mode 100644 index 72e220d..0000000 --- a/lib/src/rive_core/state_transition_flags.dart +++ /dev/null @@ -1,20 +0,0 @@ -class StateTransitionFlags { - /// Whether the transition is disabled. - static const int disabled = 1 << 0; - - /// Whether the transition duration is a percentage or time in ms. - static const int durationIsPercentage = 1 << 1; - - /// Whether exit time is enabled. - static const int enableExitTime = 1 << 2; - - /// Whether the exit time is a percentage or time in ms. - static const int exitTimeIsPercentage = 1 << 3; - - /// Whether the animation is held at exit or if it keeps advancing during - /// mixing. - static const int pauseOnExit = 1 << 4; - - /// Whether the transition can exit before it is complete. - static const int enableEarlyExit = 1 << 5; -} diff --git a/lib/src/rive_core/text/styled_text.dart b/lib/src/rive_core/text/styled_text.dart deleted file mode 100644 index 8b9c812..0000000 --- a/lib/src/rive_core/text/styled_text.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:rive_common/rive_text.dart'; -import 'package:rive_common/utilities.dart'; - -/// To allow the text editor to see the cursor placed in a location prior to -/// text entry (like pressing return) we need to introduce a place-holder last -/// character. -const zeroWidthSpace = '\u200B'; - -class StyledText { - final String value; - final List runs; - - factory StyledText(String text, List runs) { - assert(runs.isNotEmpty); - - var extendedRuns = runs.take(runs.length - 1).toList(); - extendedRuns - .add(runs.last.copyWith(unicharCount: runs.last.unicharCount + 1)); - return StyledText.exact(text + zeroWidthSpace, extendedRuns); - } - - factory StyledText.empty(TextRun run) => StyledText('', [run]); - - StyledText withoutLastCharacter() { - assert(value.isNotEmpty); - var shortenedRuns = runs.take(runs.length - 1).toList(); - if (runs.last.unicharCount > 1) { - // Only add the last run if it's not 0 length. - shortenedRuns - .add(runs.last.copyWith(unicharCount: runs.last.unicharCount - 1)); - } - return StyledText.exact( - value.substring(0, value.length - 1), shortenedRuns); - } - - StyledText.exact(this.value, this.runs); - - @override - bool operator ==(Object other) => - other is StyledText && - other.value == value && - iterableEquals(other.runs, runs); - - @override - int get hashCode => Object.hash(value, Object.hashAll(runs)); -} diff --git a/lib/src/rive_core/text/text.dart b/lib/src/rive_core/text/text.dart deleted file mode 100644 index a5f1771..0000000 --- a/lib/src/rive_core/text/text.dart +++ /dev/null @@ -1,935 +0,0 @@ -import 'dart:math'; -import 'dart:ui'; - -import 'package:rive/src/generated/text/text_base.dart'; -import 'package:rive/src/rive_core/bounds_provider.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/layout_component.dart'; -import 'package:rive/src/rive_core/text/styled_text.dart'; -import 'package:rive/src/rive_core/text/text_modifier_group.dart'; -import 'package:rive/src/rive_core/text/text_style.dart' as rive; -import 'package:rive/src/rive_core/text/text_style_container.dart'; -import 'package:rive/src/rive_core/text/text_value_run.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_base.dart'; - -enum TextSizing { - autoWidth, - autoHeight, - fixed, -} - -enum TextOverflow { - visible, - hidden, - clipped, - ellipsis, - fit, -} - -enum TextOrigin { - top, - baseline, -} - -enum VerticalTextAlign { - top, - bottom, - middle, -} - -class Text extends TextBase with TextStyleContainer implements Sizable { - Path? _clipRenderPath; - - double? _layoutWidth; - double? _layoutHeight; - Mat2D _transform = Mat2D(); - - double get effectiveWidth => _layoutWidth ?? super.width; - double get effectiveHeight => _layoutHeight ?? super.height; - - @override - Size computeIntrinsicSize(Size min, Size max) { - var size = _measure(max); - return size; - } - - @override - void controlSize(Size size) { - if (_layoutWidth != size.width || _layoutHeight != size.height) { - _layoutWidth = size.width; - _layoutHeight = size.height; - markShapeDirty(sendToLayout: false); - } - } - - TextShapeResult? _shape; - // A shape result specifically for modifiers. - StyledText? _modifierStyledText; - TextShapeResult? _modifierShape; - BreakLinesResult? _modifierLines; - - // Shapes that should be cleaned before next shaping call. - final List _cleanupShapes = []; - BreakLinesResult? _lines; - // TextShapeResult? get shape => _shape; - BreakLinesResult? get lines => _lines; - - // Used by text effectors. - GlyphLookup? _glyphLookup; - - double tValueOf(LineRunGlyph glyphInfo) { - var index = glyphInfo.run.textIndexAt(glyphInfo.index); - double t; - if (_glyphLookup != null) { - t = index + _glyphLookup!.count(index) / 2; - } else { - t = index + 0.5; - } - return t; - } - - int glyphCodePointCount(LineRunGlyph glyphInfo) { - var index = glyphInfo.run.textIndexAt(glyphInfo.index); - if (_glyphLookup != null) { - return _glyphLookup!.count(index); - } - return 1; - } - - List _modifierGroups = []; - Iterable get modifierGroups => _modifierGroups; - - bool get isEmpty => runs.isEmpty; - - final List auxStyles = []; - - int get unicharCount => _unicharCount; - - Font? getFirstAvailableFont() { - for (final run in runs) { - if (run.style?.font != null) { - return run.style?.font; - } - } - return null; - } - - StyledText makeStyled( - Font defaultFont, { - bool forEditing = false, - bool withModifiers = true, - }) { - List textRuns = []; - final buffer = StringBuffer(); - int runIndex = 0; - for (final run in runs) { - if (run.text.isEmpty) { - runIndex++; - continue; - } - buffer.write(run.text); - textRuns.add(TextRun( - font: run.style?.font ?? defaultFont, - fontSize: run.style?.fontSize ?? 16, - lineHeight: run.style?.lineHeight ?? -1, - letterSpacing: run.style?.letterSpacing ?? 0, - unicharCount: run.text.codeUnits.length, - styleId: runIndex++, - )); - } - if (withModifiers) { - // Make sure to split on glyphs from TextModifiers. - for (final modifierGroup in _modifierGroups) { - textRuns = modifierGroup.applyShapeModifiers(this, textRuns); - } - } - - // Couldn't fit anything? - if (textRuns.isEmpty && runs.isNotEmpty) { - var run = runs.first; - textRuns.add(TextRun( - font: run.style?.font ?? defaultFont, - fontSize: run.style?.fontSize ?? 16, - unicharCount: run.text.codeUnits.length, - styleId: 0, - )); - } - - // We keep an empty space at the end of the buffer if it's for editing - // purposes (we need to know where the final cursor goes and we want some - // sense of shape even when completely empty). - return forEditing || buffer.isEmpty - ? StyledText(buffer.toString(), textRuns) - : StyledText.exact(buffer.toString(), textRuns); - } - - String get text { - final buffer = StringBuffer(); - for (final run in runs) { - buffer.write(run.text); - } - return buffer.toString(); - } - - void _disposeShape() { - for (final shape in _cleanupShapes) { - shape.dispose(); - } - _cleanupShapes.clear(); - _shape = null; - } - - rive.TextStyle? styleFromShaperId(int id) => runFromShaperId(id)?.style; - TextValueRun? runFromShaperId(int id) => id < _runs.length ? _runs[id] : null; - - List _runs = []; - Iterable get runs => _runs; - - void _syncRuns() { - _runs = children.whereType().toList(growable: false); - _modifierGroups = - children.whereType().toList(growable: false); - - updateStyles(); - } - - @override - void onAdded() { - super.onAdded(); - _syncRuns(); - } - - Mat2D get originTransform => Mat2D.multiply( - Mat2D(), - worldTransform, - Mat2D.fromTranslate( - _bounds.minX - _bounds.width * originX, - _bounds.minY - _bounds.height * originY, - ), - ); - - double verticalAlignOffset = 0; - - AABB _bounds = AABB.collapsed(Vec2D()); - // Size _size = Size.zero; - Size get size => Size(_bounds.width, _bounds.height); - - @override - AABB get localBounds => AABB.fromLTWH( - _bounds.minX - _bounds.width * originX, - _bounds.minY - _bounds.height * originY, - _bounds.width, - _bounds.height, - ); - - @override - AABB get constraintBounds => localBounds; - - void forEachGlyph( - bool Function(LineRunGlyph, double, double, GlyphLine) callback) { - var lines = _lines; - var shape = _shape; - if (lines == null || shape == null) { - return; - } - double y = 0; - var paragraphIndex = 0; - - for (final paragraphLines in lines) { - final paragraph = shape.paragraphs[paragraphIndex++]; - for (final line in paragraphLines) { - double x = line.startX; - for (final glyphInfo in line.glyphs(paragraph)) { - var run = glyphInfo.run; - - if (!callback(glyphInfo, x, y, line)) { - return; - } - - x += run.advanceAt(glyphInfo.index); - } - } - - if (paragraphLines.isNotEmpty) { - y += paragraphLines.last.bottom; - } - y += paragraphSpacing; - } - } - - final List _renderStyles = []; - Size _measuredSizeMax = Size.zero; - Size _measuredSize = Size.zero; - Size _measure(Size maxSize) { - if (_measuredSizeMax == maxSize) { - return _measuredSize; - } - var defaultFont = _defaultFont; - if (defaultFont == null) { - return Size.zero; - } - var styled = makeStyled(defaultFont, withModifiers: false); - var shape = defaultFont.shape( - styled.value, - styled.runs, - ); - _cleanupShapes.add(shape); - - var lines = shape.breakLines( - min(maxSize.width, sizing == TextSizing.autoWidth ? -1 : width), - align, - wrap); - - double y = 0; - double computedHeight = 0; - double minY = 0; - var paragraphIndex = 0; - int ellipsisLine = -1; - - double maxWidth = 0; - if (textOrigin == TextOrigin.baseline && - lines.isNotEmpty && - lines.first.isNotEmpty) { - y -= lines.first.first.baseline; - minY = y; - } - - var wantEllipsis = overflow == TextOverflow.ellipsis && - sizing == TextSizing.fixed && - verticalAlign == VerticalTextAlign.top; - - // We iterate in a pre-path building pass to compute dimensions. - outer: - for (final paragraphLines in lines) { - final paragraph = shape.paragraphs[paragraphIndex++]; - for (final line in paragraphLines) { - var width = line.width(paragraph); - if (width > maxWidth) { - maxWidth = width; - } - if (wantEllipsis && y + line.bottom > maxSize.height) { - if (ellipsisLine == -1) { - // Nothing fits, just show the first line and ellipse it. - computedHeight = y + line.bottom; - } - break outer; - } - ellipsisLine++; - computedHeight = y + line.bottom; - } - - if (paragraphLines.isNotEmpty) { - y += paragraphLines.last.bottom; - } - - y += paragraphSpacing; - } - - late AABB bounds; - switch (sizing) { - case TextSizing.autoWidth: - bounds = AABB.fromValues( - 0.0, - minY, - maxWidth, - max(minY, computedHeight), - ); - break; - case TextSizing.autoHeight: - bounds = AABB.fromValues( - 0.0, - minY, - width, - max(minY, computedHeight), - ); - break; - case TextSizing.fixed: - bounds = AABB.fromValues( - 0.0, - minY, - width, - minY + height, - ); - break; - } - lines.dispose(); - - _measuredSizeMax = maxSize; - return _measuredSize = Size(min(maxSize.width, bounds.width.ceilToDouble()), - min(maxSize.height, bounds.height.ceilToDouble())); - } - - void _buildRenderStyles() { - var lines = _lines; - var shape = _shape; - if (lines == null || shape == null) { - return; - } - for (final style in _renderStyles) { - style.resetPath(); - } - _renderStyles.clear(); - - double y = 0; - double minY = 0; - var paragraphIndex = 0; - int ellipsisLine = -1; - bool isEllipsisLineLast = false; - double maxWidth = 0; - if (textOrigin == TextOrigin.baseline && - lines.isNotEmpty && - lines.first.isNotEmpty) { - y -= lines.first.first.baseline; - minY = y; - } - - // If we want an ellipsis we need to find the line to put the - // ellipsis on (line before the one that overflows). - var wantEllipsis = overflow == TextOverflow.ellipsis && - effectiveSizing == TextSizing.fixed && - verticalAlign == VerticalTextAlign.top; - - // We iterate in a pre-path building pass to compute dimensions. - int lastLineIndex = -1; - for (final paragraphLines in lines) { - final paragraph = shape.paragraphs[paragraphIndex++]; - for (final line in paragraphLines) { - var width = line.width(paragraph); - if (width > maxWidth) { - maxWidth = width; - } - lastLineIndex++; - if (wantEllipsis && y + line.bottom <= effectiveHeight) { - ellipsisLine++; - } - } - - if (paragraphLines.isNotEmpty) { - y += paragraphLines.last.bottom; - } - - y += paragraphSpacing; - } - final totalHeight = y; - if (wantEllipsis && ellipsisLine == -1) { - // Nothing fits, just show the first line and ellipse it. - ellipsisLine = 0; - } - isEllipsisLineLast = lastLineIndex == ellipsisLine; - - bool haveModifiers = _modifierGroups.isNotEmpty; - if (haveModifiers) { - for (final modifier in _modifierGroups) { - modifier.computeCoverage(_unicharCount); - } - } - - int lineIndex = 0; - paragraphIndex = 0; - - switch (effectiveSizing) { - case TextSizing.autoWidth: - _bounds = AABB.fromValues( - 0.0, - minY, - maxWidth, - max(minY, y - paragraphSpacing), - ); - break; - case TextSizing.autoHeight: - _bounds = AABB.fromValues( - 0.0, - minY, - effectiveWidth == 0 ? maxWidth : effectiveWidth, - max(minY, y - paragraphSpacing), - ); - break; - case TextSizing.fixed: - _bounds = AABB.fromValues( - 0.0, - minY, - effectiveWidth == 0 ? maxWidth : effectiveWidth, - minY + effectiveHeight, - ); - break; - } - - verticalAlignOffset = 0; - switch (verticalAlign) { - case VerticalTextAlign.middle: - verticalAlignOffset = (totalHeight - _bounds.height) / 2; - break; - case VerticalTextAlign.bottom: - verticalAlignOffset = totalHeight - _bounds.height; - break; - default: - break; - } - - if (overflow == TextOverflow.clipped) { - if (_clipRenderPath != null) { - _clipRenderPath?.reset(); - } else { - _clipRenderPath = Path(); - } - _clipRenderPath?.addRect(localBounds.rect.translate( - _bounds.width * originX, - verticalAlignOffset + _bounds.height * originY)); - } else { - _clipRenderPath?.reset(); - _clipRenderPath = null; - } - - y = 0; - if (textOrigin == TextOrigin.baseline && - lines.isNotEmpty && - lines.first.isNotEmpty) { - y -= lines.first.first.baseline; - } - paragraphIndex = 0; - double minX = double.maxFinite; - bool drawLine = true; - - outer: - for (final paragraphLines in lines) { - final paragraph = shape.paragraphs[paragraphIndex++]; - for (final line in paragraphLines) { - drawLine = true; - switch (overflow) { - case TextOverflow.hidden: - if (effectiveSizing == TextSizing.fixed) { - switch (verticalAlign) { - case VerticalTextAlign.top: - if (y + line.bottom > effectiveHeight) { - break outer; - } - break; - case VerticalTextAlign.middle: - if (y + line.top < totalHeight / 2 - effectiveHeight / 2) { - drawLine = false; - } - if (y + line.bottom > totalHeight / 2 + effectiveHeight / 2) { - drawLine = false; - break outer; - } - break; - case VerticalTextAlign.bottom: - if (y + line.top < totalHeight - effectiveHeight) { - continue; - } - break; - } - } - break; - case TextOverflow.clipped: - if (effectiveSizing == TextSizing.fixed) { - switch (verticalAlign) { - case VerticalTextAlign.top: - if (y + line.top > effectiveHeight) { - break outer; - } - break; - case VerticalTextAlign.middle: - if (y + line.bottom < totalHeight / 2 - effectiveHeight / 2) { - drawLine = false; - } - if (y + line.top > totalHeight / 2 + effectiveHeight / 2) { - break outer; - } - break; - case VerticalTextAlign.bottom: - if (y + line.bottom < totalHeight - effectiveHeight) { - drawLine = false; - } - break; - } - } - break; - default: - break; - } - - double x = line.startX; - minX = min(x, minX); - for (final glyphInfo in lineIndex == ellipsisLine - ? line.glyphsWithEllipsis( - effectiveWidth, - paragraph: paragraph, - isLastLine: isEllipsisLineLast, - cleanupShapes: _cleanupShapes, - ) - : line.glyphs(paragraph)) { - var run = glyphInfo.run; - var font = run.font; - - final glyphId = run.glyphIdAt(glyphInfo.index); - var path = font.getUiPath(glyphId); - - late Float64List pathTransform; - if (haveModifiers) { - var centerX = glyphInfo.center; - var transform = Mat2D.fromScaleAndTranslation( - glyphInfo.run.fontSize, glyphInfo.run.fontSize, -centerX, 0); - for (final modifier in _modifierGroups) { - transform = modifier.transform( - modifier.glyphCoverage(glyphInfo), transform); - } - var offset = glyphInfo.offset; - transform = Mat2D.multiply( - transform, - Mat2D.fromTranslate( - centerX + x + offset.x, y + line.baseline + offset.y), - transform); - pathTransform = transform.mat4; - } else { - pathTransform = glyphInfo.pathTransform(x, y + line.baseline).mat4; - } - var renderPath = path.transform(pathTransform); - var style = styleFromShaperId(run.styleId); - if (style != null) { - double opacity = 1.0; - if (haveModifiers) { - for (final modifier in _modifierGroups) { - if (modifier.modifiesOpacity) { - opacity = modifier.computeOpacity( - opacity, modifier.glyphCoverage(glyphInfo)); - } - } - } - if (drawLine) { - if (style.addPath(renderPath, opacity)) { - _renderStyles.add(style); - } - } - } - - x += run.advanceAt(glyphInfo.index); - } - if (lineIndex == ellipsisLine) { - break outer; - } - lineIndex++; - } - if (paragraphLines.isNotEmpty) { - y += paragraphLines.last.bottom; - } - y += paragraphSpacing; - } - double scale = 1; - double xOffset = -_bounds.width * originX; - double yOffset = -_bounds.height * originY; - if (overflow == TextOverflow.fit) { - double xScale = - (effectiveSizing != TextSizing.autoWidth && maxWidth > _bounds.width) - ? _bounds.width / maxWidth - : 1; - double baseline = fitFromBaseline ? lines[0][0].baseline : 0; - double yScale = - (effectiveSizing == TextSizing.fixed && totalHeight > _bounds.height) - ? (_bounds.height - baseline) / (totalHeight - baseline) - : 1; - if (xScale != 1 || yScale != 1) { - scale = max(0, xScale > yScale ? yScale : xScale); - yOffset += baseline * (1 - scale); - switch (align) { - case TextAlign.center: - xOffset += (_bounds.width - maxWidth * scale) / 2 - minX * scale; - break; - case TextAlign.right: - xOffset += _bounds.width - maxWidth * scale - minX * scale; - break; - default: - break; - } - } - } - if (verticalAlignValue != VerticalTextAlign.top.index) { - if (effectiveSizing == TextSizing.fixed) { - yOffset = -_bounds.height * originY; - if (verticalAlignValue == VerticalTextAlign.middle.index) { - yOffset += (_bounds.height - totalHeight * scale) / 2; - } else if (verticalAlignValue == VerticalTextAlign.bottom.index) { - yOffset += _bounds.height - totalHeight * scale; - } - } - } - _transform = Mat2D.fromScaleAndTranslation(scale, scale, xOffset, yOffset); - } - - @override - void draw(Canvas canvas) { - var lines = _lines; - var shape = _shape; - if (lines == null || shape == null) { - return; - } - - if (!clip(canvas)) { - canvas.save(); - } - canvas.transform(worldTransform.mat4); - canvas.transform(_transform.mat4); - if (overflow == TextOverflow.clipped && _clipRenderPath != null) { - canvas.clipPath(_clipRenderPath!); - } - for (final style in _renderStyles) { - style.draw(canvas); - } - canvas.restore(); - } - - void markShapeDirty({bool sendToLayout = true}) { - _measuredSizeMax = Size.zero; - _disposeShape(); - addDirt(ComponentDirt.path); - for (final group in _modifierGroups) { - group.clearRangeMaps(); - } - markWorldTransformDirty(); - - if (sendToLayout) { - _markLayoutNodeDirty(); - } - } - - void _markLayoutNodeDirty() { - for (ContainerComponent? p = parent; p != null; p = p.parent) { - if (p is LayoutComponent) { - p.markLayoutNodeDirty(); - } - } - } - - /// Called when a modifier causes the text's shape to change. - void modifierShapeDirty() { - _measuredSizeMax = Size.zero; - _disposeShape(); - addDirt(ComponentDirt.path); - } - - // TODO: figure out asset system - static Font? _defaultFont; - int _unicharCount = 0; - - void markPaintDirty() => addDirt(ComponentDirt.paint); - - void computeShape() { - markPaintDirty(); - _shape = null; - _lines?.dispose(); - _lines = null; - if (runs.isEmpty) { - _bounds = AABB.collapsed(Vec2D()); - - return; - } - - double breakWidth = - effectiveSizing == TextSizing.autoWidth ? -1 : effectiveWidth; - - // Question (max): is it safer to simply skip computing Shape if we - // have no default font? - assert(_defaultFont != null); - var defaultFont = _defaultFont!; - _modifierShape?.dispose(); - _modifierLines?.dispose(); - // We have modifiers that need shaping we'll need to compute the coverage - // right before we build the actual shape. - bool precomputeModifierCoverage = modifierRangesNeedShape; - if (precomputeModifierCoverage) { - // TODO: we could not re-compute this shape if the rangeMappers are all - // still valid. We'd only have to run group.computeCoverage below. - _modifierStyledText = makeStyled(defaultFont, withModifiers: false); - _modifierShape = defaultFont.shape( - _modifierStyledText!.value, - _modifierStyledText!.runs, - ); - _modifierLines = _modifierShape?.breakLines(breakWidth, align, wrap); - _glyphLookup = GlyphLookup.fromShape( - _modifierShape!, _modifierStyledText!.value.length); - _unicharCount = _modifierStyledText!.value.length; - for (final group in _modifierGroups) { - group.computeRangeMap(_modifierStyledText!.value, _modifierShape!, - _modifierLines!, _glyphLookup!); - group.computeCoverage(_unicharCount); - } - } else { - _modifierShape = null; - _modifierLines = null; - _glyphLookup = null; - } - - bool haveModifiers = _modifierGroups.isNotEmpty; - - var styled = makeStyled(defaultFont, withModifiers: haveModifiers); - _shape = defaultFont.shape( - styled.value, - styled.runs, - ); - _unicharCount = styled.value.length; - _cleanupShapes.add(_shape!); - _lines = _shape?.breakLines(breakWidth, align, wrap); - - // If we did not pre-compute the range then we can do it now. - if (!precomputeModifierCoverage && haveModifiers && _shape != null) { - _glyphLookup ??= GlyphLookup.fromShape(_shape!, _unicharCount); - for (final group in _modifierGroups) { - group.computeRangeMap(styled.value, _shape, _lines, _glyphLookup!); - } - } - } - - bool get modifierRangesNeedShape => - _modifierGroups.any((group) => group.needsShape); - - bool _computeShapeWhenNecessary(int dirt) { - if (dirt & ComponentDirt.path != 0) { - // TODO: (Luigi) Hardcoded font for now - if (_defaultFont == null) { - _defaultFont = getFirstAvailableFont(); - if (_defaultFont != null) { - markShapeDirty(); - } - } else { - computeShape(); - return true; - } - } - return false; - } - - @override - void update(int dirt) { - super.update(dirt); - bool rebuildRenderStyles = - _computeShapeWhenNecessary(dirt) || (dirt & ComponentDirt.paint != 0); - // Could optimize this to do what the C++ runtime does by propagating - // opacity to the styles instead of rebuilding render styles. - if (dirt & ComponentDirt.worldTransform != 0) { - for (final style in styles) { - for (final paint in style.shapePaints) { - if (paint.renderOpacity != renderOpacity) { - paint.renderOpacity = renderOpacity; - rebuildRenderStyles = true; - } - } - } - } - if (rebuildRenderStyles) { - _buildRenderStyles(); - } - } - - @override - void onRemoved() { - super.onRemoved(); - _disposeShape(); - _modifierShape?.dispose(); - _modifierLines?.dispose(); - _lines?.dispose(); - disposeStyleContainer(); - _lines = null; - } - - @override - void alignValueChanged(int from, int to) { - markShapeDirty(); - } - - @override - void verticalAlignValueChanged(int from, int to) { - markShapeDirty(); - } - - @override - void fitFromBaselineChanged(bool from, bool to) { - markShapeDirty(); - } - - TextAlign get align => enumAt(TextAlign.values, alignValue); - set align(TextAlign value) => alignValue = value.index; - - @override - void heightChanged(double from, double to) { - if (sizing == TextSizing.fixed) { - markShapeDirty(); - } - } - - TextSizing get sizing => TextSizing.values[sizingValue]; - TextSizing get effectiveSizing => - _layoutHeight != null ? TextSizing.fixed : TextSizing.values[sizingValue]; - TextWrap get wrap => TextWrap.values[wrapValue]; - - set sizing(TextSizing value) => sizingValue = value.index; - TextOverflow get overflow { - return enumAt(TextOverflow.values, overflowValue); - } - - VerticalTextAlign get verticalAlign { - return enumAt(VerticalTextAlign.values, verticalAlignValue); - } - - set overflow(TextOverflow value) => overflowValue = value.index; - - @override - void sizingValueChanged(int from, int to) { - markShapeDirty(); - } - - @override - void widthChanged(double from, double to) { - if (sizing != TextSizing.autoWidth) { - markShapeDirty(); - } - } - - @override - void overflowValueChanged(int from, int to) { - if (sizing != TextSizing.autoWidth) { - markShapeDirty(); - } else { - markPaintDirty(); - } - } - - @override - void wrapValueChanged(int from, int to) { - markShapeDirty(); - } - - @override - String toString() => 'Text(id: $id, text: $text)'; - - @override - void originXChanged(double from, double to) { - markPaintDirty(); - // Mostly for constraints. - markWorldTransformDirty(); - } - - @override - void originYChanged(double from, double to) { - markPaintDirty(); - // Mostly for constraints. - markWorldTransformDirty(); - } - - @override - void paragraphSpacingChanged(double from, double to) { - markPaintDirty(); - } - - TextOrigin get textOrigin => TextOrigin.values[originValue]; - - @override - void originValueChanged(int from, int to) { - markPaintDirty(); - markWorldTransformDirty(); - } -} diff --git a/lib/src/rive_core/text/text_modifier.dart b/lib/src/rive_core/text/text_modifier.dart deleted file mode 100644 index 85bed69..0000000 --- a/lib/src/rive_core/text/text_modifier.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/text/text_modifier_base.dart'; -import 'package:rive/src/rive_core/text/text_modifier_group.dart'; - -export 'package:rive/src/generated/text/text_modifier_base.dart'; - -abstract class TextModifier extends TextModifierBase { - TextModifierGroup? get modifierGroup => parent as TextModifierGroup?; -} diff --git a/lib/src/rive_core/text/text_modifier_group.dart b/lib/src/rive_core/text/text_modifier_group.dart deleted file mode 100644 index 67d2239..0000000 --- a/lib/src/rive_core/text/text_modifier_group.dart +++ /dev/null @@ -1,322 +0,0 @@ -import 'dart:collection'; - -import 'package:flutter/foundation.dart'; -import 'package:rive/src/generated/text/text_modifier_group_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive/src/rive_core/text/text_modifier.dart'; -import 'package:rive/src/rive_core/text/text_modifier_range.dart'; -import 'package:rive/src/rive_core/text/text_shape_modifier.dart'; -import 'package:rive/src/rive_core/text/text_variation_modifier.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_modifier_group_base.dart'; - -class TextModifierFlags { - static const int modifyOrigin = 1 << 0; - static const int modifyTranslation = 1 << 2; - static const int modifyRotation = 1 << 3; - static const int modifyScale = 1 << 4; - static const int modifyOpacity = 1 << 5; - static const int invertOpacity = 1 << 6; -} - -class TextModifierGroup extends TextModifierGroupBase { - Text? get textComponent => parent as Text?; - - List _ranges = []; - List _shapeModifiers = []; - List _modifiers = []; - List get modifiers => _modifiers; - Iterable get ranges => _ranges; - - bool get needsShape => - _shapeModifiers.isNotEmpty || _ranges.any((range) => range.needsShape); - - void _syncModifiers() { - _ranges = children.whereType().toList(growable: false); - _modifiers = children.whereType().toList(growable: false); - _shapeModifiers = - _modifiers.whereType().toList(growable: false); - } - - @override - void onAdded() { - super.onAdded(); - _syncModifiers(); - } - - void rangeTypeChanged() { - textComponent?.markShapeDirty(); - addDirt(ComponentDirt.textCoverage); - } - - void rangeChanged() { - /// Marking shape dirty should only be done if this modifer group changes - /// shaping properties (for now we're just testing and we're hardcoding a - /// shaping change). - if (_shapeModifiers.isNotEmpty) { - textComponent?.modifierShapeDirty(); - } else { - textComponent?.markPaintDirty(); - } - addDirt(ComponentDirt.textCoverage); - } - - /// Clear any cached selector range maps so they can be recomputed after next - /// shaping. - void clearRangeMaps() { - for (final range in _ranges) { - range.clearRangeMap(); - } - addDirt(ComponentDirt.textCoverage); - } - - /// Coverage is ultimately always expressed per unicode codepoint. - Float32List _coverage = Float32List(1); - - @visibleForTesting - Float32List get coverageValues => _coverage; - - void computeRangeMap(String text, TextShapeResult? shape, - BreakLinesResult? lines, GlyphLookup glyphLookup) { - for (final range in _ranges) { - range.computeRange(text, shape, lines, glyphLookup); - } - } - - void computeCoverage(int unicharCount) { - if (dirt & ComponentDirt.textCoverage == 0) { - return; - } - // Because we're not dependent on anything we need to reset our dirt - // ourselves. We're not in the DAG so we'll never get reset. - dirt = 0x00; - // When the text re-shapes, we udpate our coverage values. - _coverage = Float32List(unicharCount); - - for (final range in _ranges) { - range.computeCoverage(_coverage); - } - } - - /// Coverage at unicodepoint index. - double coverage(int index) => _coverage[index.clamp(0, _coverage.length - 1)]; - - /// Coverage for a glyph. - double glyphCoverage(LineRunGlyph glyphInfo) { - var count = textComponent?.glyphCodePointCount(glyphInfo) ?? 1; - var index = glyphInfo.run.textIndexAt(glyphInfo.index); - if (count == 1) { - return coverage(index); - } - var c = coverage(index); - - for (int i = 1; i < count; i++) { - c += coverage(index + i); - } - return c /= count; - } - - final List _cleanupFonts = []; - - TextRun modifyShape(Text text, TextRun run, double strength) { - var font = text.styleFromShaperId(run.styleId)?.font; - if (font == null) { - return run; - } - - HashMap axisVariations = run.userData is HashMap - ? run.userData as HashMap - : HashMap(); - double fontSize = run.fontSize; - for (final modifier in _shapeModifiers) { - // ignore: parameter_assignments - fontSize = - modifier.modify(text, font, axisVariations, fontSize, strength); - } - - if (axisVariations.isNotEmpty) { - var varFont = font.withOptions( - axisVariations.entries - .map((entry) => FontAxisCoord(entry.key, entry.value)), - [], - ); - if (varFont != null) { - _cleanupFonts.add(varFont); - font = varFont; - } - } - return run.copyWith( - font: font, - userData: axisVariations, - fontSize: fontSize, - ); - } - - bool get modifiesOpacity => - (modifierFlags & TextModifierFlags.modifyOpacity) != 0; - - bool get opacityInverted => - (modifierFlags & TextModifierFlags.invertOpacity) != 0; - - bool get modifiesTranslation => - (modifierFlags & TextModifierFlags.modifyTranslation) != 0; - - bool get modifiesOrigin => - (modifierFlags & TextModifierFlags.modifyOrigin) != 0; - - bool get modifiesScale => - (modifierFlags & TextModifierFlags.modifyScale) != 0; - - bool get modifiesRotation => - (modifierFlags & TextModifierFlags.modifyRotation) != 0; - - bool get modifiesTransform => - (modifierFlags & - (TextModifierFlags.modifyTranslation | - TextModifierFlags.modifyRotation | - TextModifierFlags.modifyScale | - TextModifierFlags.modifyOrigin)) != - 0; - - bool modifiesAxes(int tag) => modifiers - .whereType() - .any((modifier) => modifier.axisTag == tag); - - double computeOpacity(double current, double t) { - if (opacityInverted) { - return current * (1 - t) + opacity * t; - } else { - return current * opacity * t; - } - } - - Mat2D get originTransform { - Mat2D xform = Mat2D.fromTranslate( - (modifiesOrigin ? -originX : 0.0) + (modifiesTranslation ? x : 0), - (modifiesOrigin ? -originY : 0.0) + (modifiesTranslation ? y : 0), - ); - return xform; - } - - Mat2D transform(double t, Mat2D glyphTransform) { - if (t == 0 || !modifiesTransform) { - return glyphTransform; - } - - var transform = Mat2D(); - var actualRotation = modifiesRotation ? rotation * t : 0.0; - if (actualRotation != 0) { - Mat2D.fromRotation(transform, actualRotation); - } else { - Mat2D.setIdentity(transform); - } - if (modifiesTranslation) { - transform[4] = x * t; - transform[5] = y * t; - } - if (modifiesScale) { - Mat2D.scaleByValues( - transform, (1 - t) + scaleX * t, (1 - t) + scaleY * t); - } - if (modifiesOrigin) { - glyphTransform[4] += originX; - glyphTransform[5] += originY; - } - var result = Mat2D.multiply(Mat2D(), transform, glyphTransform); - if (modifiesOrigin) { - result[4] -= originX; - result[5] -= originY; - } - return result; - } - - List applyShapeModifiers(Text text, List runs) { - for (final font in _cleanupFonts) { - font.dispose(); - } - _cleanupFonts.clear(); - if (_shapeModifiers.isEmpty) { - return runs; - } - - // modify the runs - var nextTextRuns = []; - var index = 0; - var lastCoverage = double.maxFinite; - var extractRunIndex = 0; - - for (final run in runs) { - // Split the run into sub-runs as necessary based on equal coverage - // values. - var end = index + run.unicharCount; - - while (index < end) { - var coverage = _coverage[index]; - if (coverage != lastCoverage) { - if (index - extractRunIndex != 0) { - // Add new run from extractRunStart to index (exclusive) - if (lastCoverage == 0) { - nextTextRuns - .add(run.copyWith(unicharCount: index - extractRunIndex)); - } else { - nextTextRuns.add(modifyShape( - text, - run.copyWith(unicharCount: index - extractRunIndex), - lastCoverage)); - } - } - lastCoverage = coverage; - extractRunIndex = index; - } - index++; - } - - assert(extractRunIndex != end); - // Add new run from extractRunStart to index (exclusive) - if (lastCoverage == 0) { - nextTextRuns.add(run.copyWith(unicharCount: end - extractRunIndex)); - } else { - nextTextRuns.add(modifyShape(text, - run.copyWith(unicharCount: end - extractRunIndex), lastCoverage)); - } - extractRunIndex = end; - } - return nextTextRuns; - } - - @override - void modifierFlagsChanged(int from, int to) { - textComponent?.markPaintDirty(); - } - - @override - void opacityChanged(double from, double to) => - textComponent?.markPaintDirty(); - @override - void originXChanged(double from, double to) => - textComponent?.markPaintDirty(); - - @override - void originYChanged(double from, double to) => - textComponent?.markPaintDirty(); - @override - void rotationChanged(double from, double to) => - textComponent?.markPaintDirty(); - - @override - void scaleXChanged(double from, double to) => textComponent?.markPaintDirty(); - @override - void scaleYChanged(double from, double to) => textComponent?.markPaintDirty(); - - @override - void xChanged(double from, double to) => textComponent?.markPaintDirty(); - - @override - void yChanged(double from, double to) => textComponent?.markPaintDirty(); - - @override - void update(int dirt) {} -} diff --git a/lib/src/rive_core/text/text_modifier_range.dart b/lib/src/rive_core/text/text_modifier_range.dart deleted file mode 100644 index d1a1136..0000000 --- a/lib/src/rive_core/text/text_modifier_range.dart +++ /dev/null @@ -1,434 +0,0 @@ -import 'dart:math'; - -import 'package:collection/collection.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/text/text_modifier_range_base.dart'; -import 'package:rive/src/rive_core/animation/cubic_interpolator_component.dart'; -import 'package:rive/src/rive_core/animation/interpolator.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/enum_helper.dart'; -import 'package:rive/src/rive_core/text/text_modifier_group.dart'; -import 'package:rive/src/rive_core/text/text_value_run.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_modifier_range_base.dart'; - -enum TextRangeUnits { characters, charactersExcludingSpaces, words, lines } - -enum TextRangeMode { add, subtract, multiply, min, max, difference } - -enum TextRangeType { percentage, unitIndex } - -enum TextRangeInterpolator { linear, cubic } - -class TextModifierRange extends TextModifierRangeBase { - TextModifierGroup? get modifierGroup => - parent is TextModifierGroup ? parent as TextModifierGroup : null; - - /// Marking shape dirty should only be done if this modifer group changes - /// shaping properties (for now we're just testing and we're hardcoding a - /// shaping change). - @override - void modifyFromChanged(double from, double to) => - modifierGroup?.rangeChanged(); - - @override - void modifyToChanged(double from, double to) => modifierGroup?.rangeChanged(); - - TextRangeInterpolator get interpolatorType => - _interpolator is CubicInterpolatorComponent - ? TextRangeInterpolator.cubic - : TextRangeInterpolator.linear; - - Interpolator? _interpolator; - Interpolator? get interpolator => _interpolator; - - @override - void update(int dirt) {} - - @override - void onDirty(int mask) { - if ((mask & ComponentDirt.interpolator) != 0) { - modifierGroup?.rangeChanged(); - } - } - - @override - void childAdded(Component child) { - super.childAdded(child); - if (child is Interpolator) { - _interpolator = child as Interpolator; - modifierGroup?.rangeTypeChanged(); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - - if (child is Interpolator && _interpolator == (child as Interpolator)) { - _interpolator = children - .firstWhereOrNull((child) => child is Interpolator) as Interpolator?; - modifierGroup?.rangeTypeChanged(); - } - } - - double get offsetModifyFrom => modifyFrom + offset; - double get offsetModifyTo => modifyTo + offset; - double get offsetFalloffFrom => falloffFrom + offset; - double get offsetFalloffTo => falloffTo + offset; - - @override - void falloffFromChanged(double from, double to) => - modifierGroup?.rangeChanged(); - - @override - void falloffToChanged(double from, double to) => - modifierGroup?.rangeChanged(); - - @override - void offsetChanged(double from, double to) => modifierGroup?.rangeChanged(); - - // Cache indices. - double _indexFrom = 0; - double _indexTo = 0; - double _indexFalloffFrom = 0; - double _indexFalloffTo = 0; - double get indexFrom => _indexFrom; - double get indexTo => _indexTo; - double get indexFalloffFrom => _indexFalloffFrom; - double get indexFalloffTo => _indexFalloffTo; - - bool get needsShape => units == TextRangeUnits.lines; - - RangeMapper? _rangeMapper; - - void clearRangeMap() => _rangeMapper = null; - - void computeRange(String text, TextShapeResult? shape, - BreakLinesResult? lines, GlyphLookup glyphLookup) { - // Check if range mapper is still valid. - if (_rangeMapper != null) { - return; - } - int start = 0; - int end = text.length; - if (run != null) { - start = run!.offset; - end = start + run!.text.length; - } - switch (units) { - case TextRangeUnits.charactersExcludingSpaces: - _rangeMapper = RangeMapper.fromCharacters( - text, - start, - end, - glyphLookup, - withoutSpaces: true, - ); - break; - case TextRangeUnits.words: - _rangeMapper = RangeMapper.fromWords(text, start, end); - break; - case TextRangeUnits.lines: - if (shape != null && lines != null) { - _rangeMapper = RangeMapper.fromLines( - text, start, end, shape, lines, glyphLookup); - } - break; - default: - _rangeMapper = RangeMapper.fromCharacters( - text, - start, - end, - glyphLookup, - ); - break; - } - } - - void computeCoverage(Float32List coverage) { - if (_rangeMapper == null) { - return; - } - - _computeRangeMappedCoverage(coverage, _rangeMapper!); - } - - double _coverageAt(double t) { - var c = 0.0; - if (_indexTo >= _indexFrom) { - if (t < _indexFrom || t > _indexTo) { - c = 0; - } else if (t < _indexFalloffFrom) { - var range = max(0, _indexFalloffFrom - _indexFrom); - c = range == 0 ? 1 : max(0, t - _indexFrom) / range; - if (_interpolator != null) { - c = _interpolator!.transform(c); - } - } else if (t > _indexFalloffTo) { - var range = max(0, _indexTo - _indexFalloffTo); - c = range == 0 ? 1 : 1.0 - min(1, (t - _indexFalloffTo) / range); - if (_interpolator != null) { - c = _interpolator!.transform(c); - } - } else { - c = 1; - } - } - return c; - } - - void _computeRangeMappedCoverage(Float32List coverage, RangeMapper mapper) { - var count = mapper.unitCount; - switch (type) { - case TextRangeType.unitIndex: - _indexFrom = offsetModifyFrom; - _indexTo = offsetModifyTo; - _indexFalloffFrom = offsetFalloffFrom; - _indexFalloffTo = offsetFalloffTo; - break; - case TextRangeType.percentage: - _indexFrom = count * offsetModifyFrom; - _indexTo = count * offsetModifyTo; - _indexFalloffFrom = count * offsetFalloffFrom; - _indexFalloffTo = count * offsetFalloffTo; - break; - } - - var mode = this.mode; - for (int unitIndex = 0; unitIndex < count; unitIndex++) { - var unitLength = mapper.unitLengths[unitIndex]; - var characterIndex = mapper.unitIndices[unitIndex]; - double c = strength * _coverageAt(unitIndex + 0.5); - for (int i = 0; i < unitLength; i++) { - var current = coverage[characterIndex + i]; - switch (mode) { - case TextRangeMode.add: - current += c; - break; - case TextRangeMode.subtract: - current -= c; - break; - case TextRangeMode.max: - current = max(current, c); - break; - case TextRangeMode.min: - current = min(current, c); - break; - case TextRangeMode.multiply: - current *= c; - break; - case TextRangeMode.difference: - current = (current - c).abs(); - break; - } - coverage[characterIndex + i] = clamp ? current.clamp(0, 1) : current; - } - - // Set space between units coverage to 0. - if (unitIndex < mapper.unitIndices.length - 1) { - var nextUnitIndex = mapper.unitIndices[unitIndex + 1]; - for (int i = characterIndex + unitLength; i < nextUnitIndex; i++) { - coverage[i] = 0; - } - } - } - } - - TextRangeUnits get units => enumAt(TextRangeUnits.values, unitsValue); - set units(TextRangeUnits units) => unitsValue = units.index; - - @override - void unitsValueChanged(int from, int to) => modifierGroup?.rangeTypeChanged(); - - TextRangeMode get mode => TextRangeMode.values[modeValue]; - set mode(TextRangeMode mode) => modeValue = mode.index; - - @override - void modeValueChanged(int from, int to) => modifierGroup?.rangeChanged(); - - TextRangeType get type => enumAt(TextRangeType.values, typeValue); - set type(TextRangeType value) => typeValue = value.index; - - @override - void typeValueChanged(int from, int to) => modifierGroup?.rangeChanged(); - - @override - void clampChanged(bool from, bool to) => modifierGroup?.rangeChanged(); - - @override - void strengthChanged(double from, double to) => modifierGroup?.rangeChanged(); - - @override - void runIdChanged(int from, int to) { - run = to == Core.missingId ? null : context.resolve(to); - modifierGroup?.rangeTypeChanged(); - } - - @override - void onAddedDirty() { - run = context.resolve(runId); - super.onAddedDirty(); - } - - TextValueRun? _run; - - TextValueRun? get run => _run; - - set run(TextValueRun? value) { - if (_run == value) { - return; - } - - _run = value; - } -} - -// See word indices and word lengths implementation above, we basically want the -// same thing but for different range types (Glyphs, Characters without spaces, -// lines, etc). -class RangeMapper { - /// Each item in this list represents the index (in unicode codepoints) of the - /// selectable element. Always has length 1+unitLengths.length as it's - /// expected to always include the final index with 0 length. - final Uint32List unitIndices; - - /// Each item in this list represents the length of the matching element at - /// the same index in the _unitIndices list. - final Uint32List unitLengths; - - int get unitCount => unitLengths.length; - - RangeMapper(List indices, List lengths) - : assert(indices.length == lengths.length + 1), - unitIndices = Uint32List.fromList(indices), - unitLengths = Uint32List.fromList(lengths); - - /// Build a RangeMapper from the words in [text]. - static RangeMapper? fromWords(String text, int start, int end) { - if (text.isEmpty) { - return null; - } - List indices = []; - List lengths = []; - bool wantWhiteSpace = false; - - int characterCount = 0; - int index = 0; - int indexFrom = 0; - for (final unit in text.codeUnits) { - if (wantWhiteSpace == isWhiteSpace(unit)) { - if (!wantWhiteSpace) { - indexFrom = index; - } else { - var indexTo = indexFrom + characterCount; - if (indexTo > start && end > indexFrom) { - var actualStart = max(start, indexFrom); - int selected = min(end, indexTo) - actualStart; - if (selected > 0) { - indices.add(actualStart); - lengths.add(selected); - } - } - - characterCount = 0; - } - wantWhiteSpace = !wantWhiteSpace; - } - if (wantWhiteSpace) { - characterCount++; - } - index++; - } - if (characterCount > 0) { - var indexTo = indexFrom + characterCount; - if (indexTo > start && end > indexFrom) { - var actualStart = max(start, indexFrom); - int selected = min(end, indexTo) - actualStart; - if (selected > 0) { - indices.add(actualStart); - lengths.add(selected); - } - } - } - indices.add(end); - return RangeMapper(indices, lengths); - } - - /// Build a RangeMapper from the words in [text]. - static RangeMapper? fromCharacters( - String text, int start, int end, GlyphLookup glyphLookup, - {bool withoutSpaces = false}) { - if (text.isEmpty) { - return null; - } - List indices = []; - List lengths = []; - for (int i = start; i < end;) { - var unit = text.codeUnits[i]; - if (withoutSpaces && isWhiteSpace(unit)) { - i++; - continue; - } - // Don't break ligated glyphs. - var codePoints = glyphLookup.count(i); - indices.add(i); - lengths.add(codePoints); - i += codePoints; - } - - indices.add(end); - return RangeMapper(indices, lengths); - } - - static RangeMapper? fromLines(String text, int start, int end, - TextShapeResult shape, BreakLinesResult lines, GlyphLookup glyphLookup) { - if (text.isEmpty) { - return null; - } - List indices = []; - List lengths = []; - - var paragraphIndex = 0; - for (final paragraphLines in lines) { - final paragraph = shape.paragraphs[paragraphIndex++]; - var glyphRuns = paragraph.runs; - for (final line in paragraphLines) { - var rf = glyphRuns[line.startRun]; - var indexFrom = rf.textIndexAt(line.startIndex); - - var rt = glyphRuns[line.endRun]; - var endGlyphIndex = max(0, line.endIndex - 1); - var indexTo = rt.textIndexAt(endGlyphIndex); - indexTo += glyphLookup.count(indexTo); - - if (indexTo > start && end > indexFrom) { - var actualStart = max(start, indexFrom); - int selected = min(end, indexTo) - actualStart; - if (selected > 0) { - indices.add(actualStart); - lengths.add(selected); - } - } - } - } - indices.add(end); - return RangeMapper(indices, lengths); - } - - double unitToCharacterRange(double word) { - if (unitIndices.isEmpty) { - return 0; - } - var clampedUnit = word.clamp(0, unitIndices.length - 1); - var intUnit = clampedUnit.floor(); - double characters = unitIndices[intUnit].toDouble(); - if (intUnit < unitLengths.length) { - var fraction = clampedUnit - intUnit; - characters += unitLengths[intUnit] * fraction; - } - return characters; - } -} diff --git a/lib/src/rive_core/text/text_shape_modifier.dart b/lib/src/rive_core/text/text_shape_modifier.dart deleted file mode 100644 index 6d1353d..0000000 --- a/lib/src/rive_core/text/text_shape_modifier.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/text/text_shape_modifier_base.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_shape_modifier_base.dart'; - -abstract class TextShapeModifier extends TextShapeModifierBase { - double modify(Text text, Font font, HashMap variations, - double fontSize, double strength); -} diff --git a/lib/src/rive_core/text/text_style.dart b/lib/src/rive_core/text/text_style.dart deleted file mode 100644 index d47d64d..0000000 --- a/lib/src/rive_core/text/text_style.dart +++ /dev/null @@ -1,320 +0,0 @@ -import 'dart:collection'; -import 'dart:ui' as ui; - -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/text/text_style_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/assets/font_asset.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint.dart'; -import 'package:rive/src/rive_core/shapes/paint/shape_paint_mutator.dart'; -import 'package:rive/src/rive_core/shapes/shape_paint_container.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive/src/rive_core/text/text_style_axis.dart'; -import 'package:rive/src/rive_core/text/text_style_feature.dart'; -import 'package:rive/src/rive_core/text/text_value_run.dart'; -import 'package:rive_common/math.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_style_base.dart'; - -class TextVariationHelper extends Component { - final TextStyle style; - Font? _font; - - @override - Artboard? get artboard => style.artboard; - - Font? get font => _font; - - TextVariationHelper(this.style) { - style.markRebuildDependencies(); - } - - @override - void update(int dirt) { - _font?.dispose(); - _font = style._makeFontVariation(); - } - - void dispose() { - _font?.dispose(); - _font = null; - } - - @override - void buildDependencies() { - var text = style.text; - if (text != null) { - text.artboard?.addDependent(this); - addDependent(text); - } - } -} - -class TextStyle extends TextStyleBase - with ShapePaintContainer, FileAssetReferencer { - final Set _referencers = {}; - Text? get text => parent as Text?; - final Set _variations = {}; - final Set _features = {}; - Iterable get variations => _variations; - Iterable get features => _features; - - Iterable get variableAxes => asset?.font?.axes ?? []; - bool get hasVariableAxes => asset?.font?.axes.isNotEmpty ?? false; - - TextVariationHelper? _variationHelper; - TextVariationHelper? get variationHelper => _variationHelper; - - Iterable get fontFeatures => asset?.font?.features ?? []; - - Font? _makeFontVariation() => asset?.font?.withOptions( - _variations.map( - (axis) => FontAxisCoord( - axis.tag, - axis.axisValue, - ), - ), - _features.map( - (feature) => FontFeature( - feature.tag, - feature.featureValue, - ), - ), - ); - - Font? get font => _variationHelper?.font ?? asset?.font; - - List get shapePaints => - fills.cast().toList() + strokes.cast().toList(); - - /// An identifier used by the shaper to remap style ids as text runs are - /// converted to glyph runs. - int shaperId = -1; - - @override - void fontSizeChanged(double from, double to) { - _markShapeDirty(); - } - - @override - void letterSpacingChanged(double from, double to) { - _markShapeDirty(); - } - - void _markShapeDirty() { - for (final run in _referencers) { - run.markShapeDirty(); - } - } - - @override - void update(int dirt) {} - - /// Let the style know that a run references it. - void ref(TextValueRun run) { - _referencers.add(run); - } - - void deref(TextValueRun run) { - _referencers.remove(run); - } - - @override - String toString() => 'TextStyle(id: $id, size: $fontSize' - ')'; - - @override - void buildDependencies() { - parent?.addDependent(this); - _variationHelper?.buildDependencies(); - } - - void removeVariations() => _variations.toSet().forEach(context.removeObject); - - @override - set asset(FontAsset? value) { - if (asset == value) { - return; - } - - super.asset = value; - if (asset?.setFontCallback(_fontDecoded, notifyAlreadySet: false) ?? - false) { - // Already decoded. - _markShapeDirty(); - _variationHelper?.addDirt(ComponentDirt.textShape); - } - } - - @override - void copy(covariant TextStyle source) { - super.copy(source); - asset = source.asset; - } - - @override - void fontAssetIdChanged(int from, int to) { - asset = context.resolve(to); - } - - void _fontDecoded() { - _markShapeDirty(); - _variationHelper?.addDirt(ComponentDirt.textShape); - } - - @override - void onDirty(int mask) { - super.onDirty(mask); - if ((mask & ComponentDirt.paint) != 0) { - text?.markPaintDirty(); - } - if ((mask & ComponentDirt.textShape) != 0) { - text?.markShapeDirty(); - _variationHelper?.addDirt(ComponentDirt.textShape); - } - } - - @override - void onFillsChanged() => text?.markPaintDirty(); - - @override - void onPaintMutatorChanged(ShapePaintMutator mutator) => - text?.markPaintDirty(); - - @override - void onStrokesChanged() => text?.markPaintDirty(); - - @override - Mat2D get worldTransform => text?.worldTransform ?? Mat2D.identity; - - @override - Vec2D get worldTranslation => text?.worldTranslation ?? Vec2D(); - - @override - void childAdded(Component component) { - super.childAdded(component); - if (component is TextStyleAxis) { - if (_variations.add(component)) { - _variationHelper ??= TextVariationHelper(this); - addDirt(ComponentDirt.textShape); - } - } else if (component is TextStyleFeature) { - if (_features.add(component)) { - _variationHelper ??= TextVariationHelper(this); - addDirt(ComponentDirt.textShape); - } - } - } - - @override - void childRemoved(Component component) { - super.childRemoved(component); - bool changed = false; - if (component is TextStyleAxis) { - if (_variations.remove(component)) { - changed = true; - } - } else if (component is TextStyleFeature) { - if (_features.remove(component)) { - changed = true; - } - } - - if (changed) { - addDirt(ComponentDirt.textShape); - if (_variations.isEmpty && _features.isEmpty) { - _variationHelper?.dispose(); - _variationHelper = null; - } - } - } - - @override - void onRemoved() { - super.onRemoved(); - _variationHelper?.dispose(); - _variationHelper = null; - } - - @override - int get assetId => fontAssetId; - - @override - set assetId(int value) => fontAssetId = value; - - @override - int get assetIdPropertyKey => TextStyleBase.fontAssetIdPropertyKey; - - final ui.Path _renderPath = ui.Path(); - final HashMap _opacityPaths = HashMap(); - - bool _hasContents = false; - void resetPath() { - _renderPath.reset(); - _opacityPaths.clear(); - _hasContents = false; - } - - bool addPath(ui.Path path, double opacity) { - var hadContents = _hasContents; - _hasContents = true; - if (opacity == 1) { - _renderPath.addPath(path, ui.Offset.zero); - } else if (opacity > 0) { - var renderPath = _opacityPaths[opacity]; - if (renderPath == null) { - _opacityPaths[opacity] = renderPath = ui.Path(); - } - renderPath.addPath(path, ui.Offset.zero); - } - return !hadContents; - } - - void draw(ui.Canvas canvas) { - for (final shapePaint in shapePaints) { - if (!shapePaint.isVisible) { - continue; - } - var paint = shapePaint.paint; - canvas.drawPath( - _renderPath, - paint, - ); - if (_opacityPaths.entries.isNotEmpty) { - var oldColor = paint.color; - for (final entry in _opacityPaths.entries) { - paint.color = ui.Color.fromRGBO( - oldColor.red, - oldColor.green, - oldColor.blue, - oldColor.opacity * entry.key, - ); - canvas.drawPath( - entry.value, - paint, - ); - } - paint.color = oldColor; - } - } - } - - @override - bool import(ImportStack stack) { - if (!registerWithImporter(stack)) { - return false; - } - return super.import(stack); - } - - @override - void lineHeightChanged(double from, double to) { - _markShapeDirty(); - } - - double get autoLineHeight => font?.lineHeight(fontSize) ?? 0; -} diff --git a/lib/src/rive_core/text/text_style_axis.dart b/lib/src/rive_core/text/text_style_axis.dart deleted file mode 100644 index 9784e2b..0000000 --- a/lib/src/rive_core/text/text_style_axis.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/generated/text/text_style_axis_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_style_axis_base.dart'; - -class TextStyleAxis extends TextStyleAxisBase { - String get tagName => FontTag.tagToName(tag); - - @override - void update(int dirt) {} - - @override - void axisValueChanged(double from, double to) { - parent?.addDirt(ComponentDirt.textShape); - } - - @override - void tagChanged(int from, int to) => parent?.addDirt(ComponentDirt.textShape); -} diff --git a/lib/src/rive_core/text/text_style_container.dart b/lib/src/rive_core/text/text_style_container.dart deleted file mode 100644 index b60336a..0000000 --- a/lib/src/rive_core/text/text_style_container.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/text/text_style.dart'; -import 'package:rive_common/utilities.dart'; - -/// An abstraction to give a common interface to any component that can contain -/// TextStyles. Currently used by the [Text] object but we can later support -/// file-wide styles by making them owned by an [Artboard] or [Backboard]. -abstract class TextStyleContainer { - int _nextShaperId = 0; - final Set styles = {}; - final HashMap _styleLookup = HashMap(); - - // TextStyle? styleFromShaperId(int id) => _styleLookup[id]; - - void disposeStyleContainer() { - _styleLookup.clear(); - styles.clear(); - } - - bool addStyle(TextStyle style) { - if (styles.add(style)) { - _registerStyle(style); - - return true; - } - return false; - } - - void _registerStyle(TextStyle style) { - if (style.shaperId == -1) { - style.shaperId = _nextShaperId++; - _styleLookup[style.shaperId] = style; - } - } - - ContainerChildren get children; - void updateStyles() { - var nextStyles = children.whereType(); - if (!iterableEquals(nextStyles, styles)) { - styles.clear(); - styles.addAll(nextStyles); - styles.forEach(_registerStyle); - } - } - - bool removeStyle(TextStyle style) { - if (styles.remove(style)) { - return true; - } - return false; - } - - /// These usually gets auto implemented as this mixin is meant to be added to - /// a ComponentBase. This way the implementor doesn't need to cast - /// ShapePaintContainer to ContainerComponent/Shape/Artboard/etc. - bool addDirt(int value, {bool recurse = false}); - - bool addDependent(Component dependent, {Component? via}); - void appendChild(Component child); - // Mat2D get worldTransform; - // Vec2D get worldTranslation; -} diff --git a/lib/src/rive_core/text/text_style_feature.dart b/lib/src/rive_core/text/text_style_feature.dart deleted file mode 100644 index 0db70eb..0000000 --- a/lib/src/rive_core/text/text_style_feature.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/generated/text/text_style_feature_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_style_feature_base.dart'; - -class TextStyleFeature extends TextStyleFeatureBase { - String get tagName => FontTag.tagToName(tag); - - @override - void update(int dirt) {} - - @override - void featureValueChanged(int from, int to) { - parent?.addDirt(ComponentDirt.textShape); - } - - @override - void tagChanged(int from, int to) => parent?.addDirt(ComponentDirt.textShape); -} diff --git a/lib/src/rive_core/text/text_value_run.dart b/lib/src/rive_core/text/text_value_run.dart deleted file mode 100644 index d848276..0000000 --- a/lib/src/rive_core/text/text_value_run.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/text/text_value_run_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive/src/rive_core/text/text_style.dart'; - -export 'package:rive/src/generated/text/text_value_run_base.dart'; - -class TextValueRun extends TextValueRunBase { - Text? get textComponent => parent as Text?; - - TextStyle? _style; - TextStyle? get style => _style; - set style(TextStyle? value) { - if (_style == value) { - return; - } - - _style?.deref(this); - _style = value; - styleId = value?.id ?? Core.missingId; - _style?.ref(this); - } - - /// Returns the offset of this run within the text. - int get offset { - var text = textComponent; - if (text == null) { - return 0; - } - int value = 0; - for (final run in text.runs) { - if (run == this) { - break; - } - value += run.text.length; - } - return value; - } - - void markShapeDirty() => textComponent?.markShapeDirty(); - - @override - void onAdded() {} - - @override - void styleIdChanged(int from, int to) { - style = context.resolve(to); - markShapeDirty(); - } - - @override - void onRemoved() { - super.onRemoved(); - _style?.deref(this); - } - - @override - void onAddedDirty() { - super.onAddedDirty(); - style = context.resolve(styleId); - } - - @override - void update(int dirt) {} - - @override - void textChanged(String from, String to) => textComponent?.markShapeDirty(); -} diff --git a/lib/src/rive_core/text/text_variation_modifier.dart b/lib/src/rive_core/text/text_variation_modifier.dart deleted file mode 100644 index 9ef0a83..0000000 --- a/lib/src/rive_core/text/text_variation_modifier.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/generated/text/text_variation_modifier_base.dart'; -import 'package:rive/src/rive_core/text/text.dart'; -import 'package:rive_common/rive_text.dart'; - -export 'package:rive/src/generated/text/text_variation_modifier_base.dart'; - -class TextVariationModifier extends TextVariationModifierBase { - String get tagName => FontTag.tagToName(axisTag); - - @override - void axisTagChanged(int from, int to) => - modifierGroup?.textComponent?.markShapeDirty(); - - @override - void axisValueChanged(double from, double to) => - modifierGroup?.textComponent?.markShapeDirty(); - - @override - void update(int dirt) {} - - @override - double modify(Text text, Font font, HashMap variations, - double fontSize, double strength) { - var fromValue = variations[axisTag] ?? font.axisValue(axisTag); - variations[axisTag] = fromValue * (1 - strength) + axisValue * strength; - - return fontSize; - } -} diff --git a/lib/src/rive_core/transform_component.dart b/lib/src/rive_core/transform_component.dart deleted file mode 100644 index a487338..0000000 --- a/lib/src/rive_core/transform_component.dart +++ /dev/null @@ -1,236 +0,0 @@ -import 'package:rive/src/generated/transform_component_base.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive/src/rive_core/constraints/constraint.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/draw_rules.dart'; -import 'package:rive/src/rive_core/drawable.dart'; -import 'package:rive/src/rive_core/shapes/clipping_shape.dart'; -import 'package:rive/src/rive_core/world_transform_component.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/transform_component_base.dart'; - -abstract class TransformComponent extends TransformComponentBase { - /// Draw rules saved against this transform component, inherited by children. - DrawRules? _drawRules; - - DrawRules? get drawRules => _drawRules; - - final List _clippingShapes = []; - Iterable get clippingShapes => _clippingShapes; - - /// Constraints applied to this TransformComponent. - final List _constraints = []; - Iterable get constraints => _constraints; - - bool get isConstrained { - Component? component = this; - while (component != null) { - if (component is TransformComponent && component.constraints.isNotEmpty) { - return true; - } - component = component.parent; - } - return false; - } - - double _renderOpacity = 1; - double get renderOpacity => _renderOpacity; - - final Mat2D transform = Mat2D(); - - Vec2D get translation => Vec2D.fromValues(x, y); - - double get x; - double get y; - set x(double value); - set y(double value); - - @override - void update(int dirt) { - if (dirt & ComponentDirt.transform != 0) { - updateTransform(); - } - if (dirt & ComponentDirt.worldTransform != 0) { - updateWorldTransform(); - } - } - - void updateTransform() { - if (rotation != 0) { - Mat2D.fromRotation(transform, rotation); - } else { - Mat2D.setIdentity(transform); - } - transform[4] = x; - transform[5] = y; - - Mat2D.scaleByValues(transform, scaleX, scaleY); - } - - // TODO: when we have layer effect renderers, this will need to render 1 for - // layer effects. - @override - double get childOpacity => _renderOpacity; - - Vec2D get scale => Vec2D.fromValues(scaleX, scaleY); - set scale(Vec2D value) { - scaleX = value.x; - scaleY = value.y; - } - - @mustCallSuper - void updateWorldTransform() { - _renderOpacity = opacity; - if (parent is WorldTransformComponent) { - var parentNode = parent as WorldTransformComponent; - _renderOpacity *= parentNode.childOpacity; - Mat2D.multiply(worldTransform, parentNode.worldTransform, transform); - } else { - Mat2D.copy(worldTransform, transform); - } - - if (_constraints.isNotEmpty) { - for (final constraint in _constraints) { - constraint.constrain(this); - } - } - } - - void calculateWorldTransform() { - var parent = this.parent; - final chain = [this]; - - while (parent != null) { - if (parent is TransformComponent) { - chain.insert(0, parent); - } - parent = parent.parent; - } - for (final item in chain) { - item.updateTransform(); - item.updateWorldTransform(); - } - } - - @override - void buildDependencies() { - super.buildDependencies(); - parent?.addDependent(this); - } - - void markTransformDirty() { - if (!addDirt(ComponentDirt.transform)) { - return; - } - markWorldTransformDirty(); - } - - @override - void rotationChanged(double from, double to) { - markTransformDirty(); - } - - @override - void scaleXChanged(double from, double to) { - markTransformDirty(); - } - - @override - void scaleYChanged(double from, double to) { - markTransformDirty(); - } - - @override - void opacityChanged(double from, double to) { - // Intentionally doesn't call super as this will call - // markWorldTransformDirty if necessary. - markTransformDirty(); - } - - @override - void parentChanged(ContainerComponent? from, ContainerComponent? to) { - super.parentChanged(from, to); - markWorldTransformDirty(); - } - - @override - void childAdded(Component child) { - super.childAdded(child); - switch (child.coreType) { - case DrawRulesBase.typeKey: - _drawRules = child as DrawRules; - - break; - case ClippingShapeBase.typeKey: - _clippingShapes.add(child as ClippingShape); - addDirt(ComponentDirt.clip, recurse: true); - - break; - } - if (child is Constraint) { - _constraints.add(child); - } - } - - @override - void childRemoved(Component child) { - super.childRemoved(child); - switch (child.coreType) { - case DrawRulesBase.typeKey: - if (_drawRules == child as DrawRules) { - _drawRules = null; - } - break; - case ClippingShapeBase.typeKey: - if (_clippingShapes.isNotEmpty) { - _clippingShapes.remove(child as ClippingShape); - addDirt(ComponentDirt.clip, recurse: true); - } - break; - } - if (child is Constraint) { - _constraints.remove(child); - } - } - - @override - void buildDrawOrder( - List drawables, DrawRules? rules, List allRules) { - if (drawRules != null) { - // ignore: parameter_assignments - rules = drawRules!; - allRules.add(rules); - } - super.buildDrawOrder(drawables, rules, allRules); - } - - AABB get localBounds => AABB.collapsed(Vec2D()); - - /// Bounds to use for constraining to object space. - @override - AABB get constraintBounds => AABB.collapsed(Vec2D()); - - void markDirtyIfConstrained() { - if (constraints.isNotEmpty) { - addDirt(ComponentDirt.worldTransform, recurse: true); - } - } - - @override - bool propagateCollapse(bool collapse) { - if (!super.propagateCollapse(collapse)) { - return false; - } - - // In the runtime, we have to iterate the dependents - dependents.forEach((element) { - if (element is TransformComponent) { - element.markDirtyIfConstrained(); - } - }); - - return true; - } -} diff --git a/lib/src/rive_core/transform_space.dart b/lib/src/rive_core/transform_space.dart deleted file mode 100644 index 72acc44..0000000 --- a/lib/src/rive_core/transform_space.dart +++ /dev/null @@ -1 +0,0 @@ -enum TransformSpace { world, local } diff --git a/lib/src/rive_core/viewmodel/data_enum.dart b/lib/src/rive_core/viewmodel/data_enum.dart deleted file mode 100644 index 02929c6..0000000 --- a/lib/src/rive_core/viewmodel/data_enum.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/data_enum_base.dart'; - -export 'package:rive/src/generated/viewmodel/data_enum_base.dart'; - -class DataEnum extends DataEnumBase { - @override - void onAdded() {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/viewmodel/data_enum_value.dart b/lib/src/rive_core/viewmodel/data_enum_value.dart deleted file mode 100644 index c2b173a..0000000 --- a/lib/src/rive_core/viewmodel/data_enum_value.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:rive/src/generated/viewmodel/data_enum_value_base.dart'; - -export 'package:rive/src/generated/viewmodel/data_enum_value_base.dart'; - -class DataEnumValue extends DataEnumValueBase { - @override - void valueChanged(String from, String to) {} - - @override - void keyChanged(String from, String to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/viewmodel/viewmodel.dart b/lib/src/rive_core/viewmodel/viewmodel.dart deleted file mode 100644 index 8f36f5e..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_base.dart'; -import 'package:rive/src/rive_core/container_component.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_base.dart'; - -class ViewModel extends ViewModelBase { - ViewModelProperties children = ViewModelProperties(); - List instances = []; - - @override - void onAdded() {} - - @override - void onAddedDirty() { - // TODO: @hernan implement - } - - @override - void defaultInstanceIdChanged(int from, int to) {} - - void addProperty(ViewModelProperty item) { - if (!children.contains(item)) { - children.add(item); - } - } - - T? property(int id) { - for (final property in children) { - if (property.id == id && property is T) { - return property; - } - } - return null; - } - - void removeProperty(ViewModelProperty item) {} - - void internalAddProperty(ViewModelProperty item) { - addProperty(item); - } - - void addInstance(ViewModelInstance value) { - instances.add(value); - } - - bool removeInstance(ViewModelInstance value) { - if (value.id == defaultInstanceId) { - return false; - } - return instances.remove(value); - } - - ViewModelInstance instance(int id) { - return instances.firstWhere((element) => element.id == id); - } - - ViewModelInstance get defaultInstance => instance(defaultInstanceId); - - bool internalRemoveInstance(ViewModelInstance value) { - return removeInstance(value); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_component.dart b/lib/src/rive_core/viewmodel/viewmodel_component.dart deleted file mode 100644 index 881bbb5..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_component.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_component_base.dart'; - -class ViewModelComponent extends ViewModelComponentBase { - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - @override - void nameChanged(String from, String to) {} -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance.dart b/lib/src/rive_core/viewmodel/viewmodel_instance.dart deleted file mode 100644 index ac30330..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_value.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_base.dart'; - -class ViewModelInstance extends ViewModelInstanceBase { - List propertyValues = []; - ViewModel? viewModel; - - @override - void update(int dirt) {} - - @override - bool get canBeOrphaned => true; - - @override - void onAdded() { - viewModel?.addInstance(this); - } - - @override - void viewModelIdChanged(int from, int to) {} - - @override - void nameChanged(String from, String to) {} - - void addPropertyValue(ViewModelInstanceValue value) { - propertyValues.add(value); - } - - bool removePropertyValue(ViewModelInstanceValue value) { - final result = propertyValues.remove(value); - - return result; - } - - void removeValueByPropertyId(int id) { - final propertyValue = propertyValues.firstWhereOrNull((element) { - return element.viewModelPropertyId == id; - }); - if (propertyValue != null) { - propertyValue.remove(); - } - } - - bool internalRemovePropertyValue(ViewModelInstanceValue value) { - return removePropertyValue(value); - } - - ViewModelInstanceValue? - propertyValueByPropertyId( - int propertyId) { - final propertyValue = propertyValues.firstWhereOrNull( - (property) => property.viewModelPropertyId == propertyId); - assert(propertyValue is T?); - return propertyValue; - } - - ViewModelInstanceValue property(int propertyId) { - return propertyValues - .firstWhere((property) => property.viewModelPropertyId == propertyId); - } - - ViewModelInstanceValue? propertyFromPath(List pathIds, int index) { - if (pathIds.isEmpty) { - return null; - } - final _property = property(pathIds[index]); - if (index == pathIds.length - 1) { - return _property; - } else if (_property is ViewModelInstanceViewModel) { - return _property.viewModelInstance?.propertyFromPath(pathIds, index + 1); - } - return null; - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_boolean.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_boolean.dart deleted file mode 100644 index 93646fa..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_boolean.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_boolean_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_boolean_base.dart'; - -class ViewModelInstanceBoolean extends ViewModelInstanceBooleanBase { - @override - void propertyValueChanged(bool from, bool to) { - addDirt(ComponentDirt.bindings); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_color.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_color.dart deleted file mode 100644 index b52a573..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_color.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_color_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_color_base.dart'; - -class ViewModelInstanceColor extends ViewModelInstanceColorBase { - @override - void propertyValueChanged(int from, int to) { - addDirt(ComponentDirt.bindings); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_enum.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_enum.dart deleted file mode 100644 index 174c8c6..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_enum.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_enum_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_enum_base.dart'; - -class ViewModelInstanceEnum extends ViewModelInstanceEnumBase { - @override - void propertyValueChanged(int from, int to) { - addDirt(ComponentDirt.bindings); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_list.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_list.dart deleted file mode 100644 index f216ccf..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_list.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/generated/viewmodel/viewmodel_instance_list_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_list_item.dart'; -export 'package:rive/src/generated/viewmodel/viewmodel_instance_list_base.dart'; - -class ViewModelInstanceList extends ViewModelInstanceListBase { - ViewModelListItems children = ViewModelListItems(); - - void addItem(ViewModelInstanceListItem item) { - if (!children.contains(item)) { - children.add(item); - } - } - - bool removeItem(ViewModelInstanceListItem item) { - return children.remove(item); - } - - void internalAddItem(ViewModelInstanceListItem item) { - addItem(item); - } - - /// Called by rive_core to remove a ListItem from the list. - bool internalRemoveListItem(ViewModelInstanceListItem item) { - var removed = removeItem(item); - - return removed; - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_list_item.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_list_item.dart deleted file mode 100644 index 2b9cb16..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_list_item.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_list_item_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_list_item_base.dart'; - -class ViewModelInstanceListItem extends ViewModelInstanceListItemBase { - @override - void viewModelIdChanged(int from, int to) {} - - @override - void viewModelInstanceIdChanged(int from, int to) {} - - @override - void artboardIdChanged(int from, int to) {} - - @override - void onAdded() {} - - @override - void useLinkedArtboardChanged(bool from, bool to) {} - - @override - void onAddedDirty() {} -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_number.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_number.dart deleted file mode 100644 index 9be89ff..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_number.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_number_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_number_base.dart'; - -class ViewModelInstanceNumber extends ViewModelInstanceNumberBase { - @override - void propertyValueChanged(double from, double to) { - addDirt(ComponentDirt.bindings); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_string.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_string.dart deleted file mode 100644 index af5bd99..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_string.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_string_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_string_base.dart'; - -class ViewModelInstanceString extends ViewModelInstanceStringBase { - @override - void propertyValueChanged(String from, String to) { - addDirt(ComponentDirt.bindings); - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_value.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_value.dart deleted file mode 100644 index 0418ad7..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_value.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_value_base.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind_context.dart'; -import 'package:rive/src/rive_core/dependency_helper.dart'; - -class ViewModelInstanceValue extends ViewModelInstanceValueBase { - final DependencyHelper _dependencyHelper = - DependencyHelper(); - - @override - void viewModelPropertyIdChanged(int from, int to) {} - - @override - void onAdded() {} - - @override - void onAddedDirty() {} - - void addDependent(DataBindContextInterface value) { - _dependencyHelper.addDependent(value); - } - - bool addDirt(int value, {bool recurse = true}) { - _dependencyHelper.addDirt(value); - return true; - } -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart b/lib/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart deleted file mode 100644 index 7758293..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_instance_viewmodel.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_instance_viewmodel_base.dart'; - -class ViewModelInstanceViewModel extends ViewModelInstanceViewModelBase { - ViewModelInstance? referenceViewModelInstance; - - @override - void propertyValueChanged(int from, int to) {} - - @override - void onAddedDirty() { - super.onAddedDirty(); - referenceViewModelInstance = - context.resolve(propertyValue); - } - - ViewModelInstance? get viewModelInstance => context.resolve(propertyValue); -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property.dart b/lib/src/rive_core/viewmodel/viewmodel_property.dart deleted file mode 100644 index f55ac24..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_base.dart'; -import 'package:rive/src/rive_core/backboard.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_base.dart'; - -class ViewModelProperty extends ViewModelPropertyBase { - Backboard? backboard; - - @override - void onAdded() {} -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_boolean.dart b/lib/src/rive_core/viewmodel/viewmodel_property_boolean.dart deleted file mode 100644 index 040e4db..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_boolean.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_boolean_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_boolean_base.dart'; - -class ViewModelPropertyBoolean extends ViewModelPropertyBooleanBase {} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_color.dart b/lib/src/rive_core/viewmodel/viewmodel_property_color.dart deleted file mode 100644 index 3d3487b..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_color.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_color_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_color_base.dart'; - -class ViewModelPropertyColor extends ViewModelPropertyColorBase {} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_enum.dart b/lib/src/rive_core/viewmodel/viewmodel_property_enum.dart deleted file mode 100644 index c7dca12..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_enum.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_enum_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_enum_base.dart'; - -class ViewModelPropertyEnum extends ViewModelPropertyEnumBase { - @override - void enumIdChanged(int from, int to) {} -} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_list.dart b/lib/src/rive_core/viewmodel/viewmodel_property_list.dart deleted file mode 100644 index 9c0dc95..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_list.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_list_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_list_base.dart'; - -class ViewModelPropertyList extends ViewModelPropertyListBase {} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_number.dart b/lib/src/rive_core/viewmodel/viewmodel_property_number.dart deleted file mode 100644 index 86f6731..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_number.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_number_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_number_base.dart'; - -class ViewModelPropertyNumber extends ViewModelPropertyNumberBase {} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_string.dart b/lib/src/rive_core/viewmodel/viewmodel_property_string.dart deleted file mode 100644 index 74a6e04..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_string.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_string_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_string_base.dart'; - -class ViewModelPropertyString extends ViewModelPropertyStringBase {} diff --git a/lib/src/rive_core/viewmodel/viewmodel_property_viewmodel.dart b/lib/src/rive_core/viewmodel/viewmodel_property_viewmodel.dart deleted file mode 100644 index 26316da..0000000 --- a/lib/src/rive_core/viewmodel/viewmodel_property_viewmodel.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:rive/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart'; - -export 'package:rive/src/generated/viewmodel/viewmodel_property_viewmodel_base.dart'; - -class ViewModelPropertyViewModel extends ViewModelPropertyViewModelBase { - @override - void viewModelReferenceIdChanged(int from, int to) { - // TODO: implement viewModelIdChanged - } -} diff --git a/lib/src/rive_core/world_transform_component.dart b/lib/src/rive_core/world_transform_component.dart deleted file mode 100644 index 80dfcd0..0000000 --- a/lib/src/rive_core/world_transform_component.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:rive/src/generated/world_transform_component_base.dart'; -import 'package:rive/src/rive_core/component_dirt.dart'; -import 'package:rive_common/math.dart'; - -export 'package:rive/src/generated/world_transform_component_base.dart'; - -/// A Component with world transform. -abstract class WorldTransformComponent extends WorldTransformComponentBase { - Vec2D get worldTranslation => - Vec2D.fromValues(worldTransform[4], worldTransform[5]); - - /// Bounds to use for constraining to object space. - AABB get constraintBounds => AABB.collapsed(Vec2D()); - - final Mat2D worldTransform = Mat2D(); - double get childOpacity => opacity; - - void markWorldTransformDirty() => - addDirt(ComponentDirt.worldTransform, recurse: true); - - @override - void opacityChanged(double from, double to) { - markWorldTransformDirty(); - } - - /// Returns the world transform of the parent component. Returns the identity - /// if there is no parent (the artboard should be the only case here). - Mat2D get parentWorldTransform => parent is WorldTransformComponent - ? (parent as WorldTransformComponent).worldTransform - : Mat2D.identity; -} diff --git a/lib/src/rive_extensions.dart b/lib/src/rive_extensions.dart new file mode 100644 index 0000000..a282813 --- /dev/null +++ b/lib/src/rive_extensions.dart @@ -0,0 +1,18 @@ +import 'package:rive/rive.dart' as rive; + +extension RiveFileExtension on rive.File { + /// Creates a default view model instance for the given artboard. + /// + /// This is a convenience method that gets the default view model, and + /// creates a default view model instance for the given artboard. + /// + /// Returns `null` if the artboard does not have a default view model. + /// + /// Example: + /// ```dart + /// final viewModelInstance = riveFile.createDefaultViewModelInstance(artboard); + /// ``` + rive.ViewModelInstance? createDefaultViewModelInstance( + rive.Artboard artboard) => + defaultArtboardViewModel(artboard)?.createDefaultInstance(); +} diff --git a/lib/src/rive_file.dart b/lib/src/rive_file.dart deleted file mode 100644 index fbd879d..0000000 --- a/lib/src/rive_file.dart +++ /dev/null @@ -1,508 +0,0 @@ -import 'dart:collection'; - -import 'package:collection/collection.dart'; -import 'package:flutter/services.dart'; -import 'package:http/http.dart' as http; -import 'package:rive/src/asset_loader.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/core/field_types/core_field_type.dart'; -import 'package:rive/src/core/importers/viewmodel_instance_importer.dart'; -import 'package:rive/src/generated/animation/animation_state_base.dart'; -import 'package:rive/src/generated/animation/any_state_base.dart'; -import 'package:rive/src/generated/animation/blend_state_transition_base.dart'; -import 'package:rive/src/generated/animation/entry_state_base.dart'; -import 'package:rive/src/generated/animation/exit_state_base.dart'; -import 'package:rive/src/generated/assets/font_asset_base.dart'; -import 'package:rive/src/generated/nested_artboard_base.dart'; -import 'package:rive/src/generated/text/text_base.dart'; -import 'package:rive/src/local_file_io.dart' - if (dart.library.js_interop) 'package:rive/src/local_file_web.dart'; -import 'package:rive/src/rive_core/animation/blend_state_1d.dart'; -import 'package:rive/src/rive_core/animation/blend_state_direct.dart'; -import 'package:rive/src/rive_core/animation/keyed_object.dart'; -import 'package:rive/src/rive_core/animation/keyed_property.dart'; -import 'package:rive/src/rive_core/animation/layer_state.dart'; -import 'package:rive/src/rive_core/animation/linear_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer.dart'; -import 'package:rive/src/rive_core/animation/state_machine_layer_component.dart'; -import 'package:rive/src/rive_core/animation/state_machine_listener.dart'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -import 'package:rive/src/rive_core/assets/audio_asset.dart'; -import 'package:rive/src/rive_core/assets/file_asset.dart'; -import 'package:rive/src/rive_core/assets/image_asset.dart'; -import 'package:rive/src/rive_core/backboard.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/runtime/exceptions/rive_format_error_exception.dart'; -import 'package:rive/src/rive_core/runtime/runtime_header.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive/src/runtime_nested_artboard.dart'; -import 'package:rive_common/rive_text.dart'; -import 'package:rive_common/utilities.dart'; - -typedef Core? ObjectGenerator(int coreTypeKey); - -Core? _readRuntimeObject(BinaryReader reader, - HashMap propertyToField, ObjectGenerator? generator) { - int coreObjectKey = reader.readVarUint(); - Core? instance = generator?.call(coreObjectKey); - if (instance == null) { - switch (coreObjectKey) { - case ArtboardBase.typeKey: - instance = RuntimeArtboard(); - break; - case NestedArtboardBase.typeKey: - instance = RuntimeNestedArtboard(); - break; - } - } - var object = instance ?? RiveCoreContext.makeCoreInstance(coreObjectKey); - - while (true) { - int propertyKey = reader.readVarUint(); - if (propertyKey == 0) { - // Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif - break; - } - - var fieldType = RiveCoreContext.coreType(propertyKey); - if (fieldType == null || object == null) { - _skipProperty(reader, propertyKey, propertyToField); - } else { - RiveCoreContext.setObjectProperty( - object, propertyKey, fieldType.deserialize(reader)); - } - } - return object; -} - -int _peekRuntimeObjectType( - BinaryReader reader, HashMap propertyToField) { - int coreObjectKey = reader.readVarUint(); - - while (true) { - int propertyKey = reader.readVarUint(); - if (propertyKey == 0) { - // Terminator. https://media.giphy.com/media/7TtvTUMm9mp20/giphy.gif - break; - } - - _skipProperty(reader, propertyKey, propertyToField); - } - return coreObjectKey; -} - -void _skipProperty(BinaryReader reader, int propertyKey, - HashMap propertyToField) { - var field = - RiveCoreContext.coreType(propertyKey) ?? propertyToField[propertyKey]; - if (field == null) { - throw UnsupportedError('Unsupported property key $propertyKey. ' - 'A new runtime is likely necessary to play this file.'); - } - field.skip(reader); -} - -/// Encapsulates a [RiveFile] and provides access to the list of [Artboard] -/// objects it contains. -class RiveFile { - /// Contains the [RiveFile]'s version information. - final RuntimeHeader header; - - Backboard _backboard = Backboard.unknown; - final _artboards = []; - final FileAssetLoader? _assetLoader; - - // List of core file types - static final indexToField = [ - RiveCoreContext.uintType, - RiveCoreContext.stringType, - RiveCoreContext.doubleType, - RiveCoreContext.colorType - ]; - - static HashMap _propertyToFieldLookup( - RuntimeHeader header) { - /// Property fields table of contents - final propertyToField = HashMap(); - - header.propertyToFieldIndex.forEach((key, fieldIndex) { - if (fieldIndex < 0 || fieldIndex >= indexToField.length) { - throw RiveFormatErrorException('unexpected field index $fieldIndex'); - } - - propertyToField[key] = indexToField[fieldIndex]; - }); - return propertyToField; - } - - @Deprecated('This method will always return true and is no longer accurate') - // Peek into the bytes to see if we're going to need to use the text runtime. - static bool needsTextRuntime(ByteData bytes) { - var reader = BinaryReader(bytes); - var header = RuntimeHeader.read(reader); - - /// Property fields table of contents - final propertyToField = _propertyToFieldLookup(header); - - while (!reader.isEOF) { - final coreType = _peekRuntimeObjectType(reader, propertyToField); - switch (coreType) { - case TextBase.typeKey: - // Since all rive_common wasm modules are currently bundled together - // we need to check for existance of any of these. And since Artboard - // extends LayoutComponent, we will always need to load it - case ArtboardBase.typeKey: - case AudioAssetBase.typeKey: - return true; - } - } - return false; - } - - RiveFile._( - BinaryReader reader, - this.header, - ObjectGenerator? generator, - this._assetLoader, - ) { - /// Property fields table of contents - final propertyToField = _propertyToFieldLookup(header); - - int artboardId = 0; - var artboardLookup = HashMap(); - var importStack = ImportStack(); - while (!reader.isEOF) { - final object = _readRuntimeObject(reader, propertyToField, generator); - if (object == null) { - // See if there's an artboard on the stack, need to track the null - // object as it'll still hold an id. - var artboardImporter = - importStack.latest(ArtboardBase.typeKey); - if (artboardImporter != null) { - artboardImporter.addComponent(null); - } - continue; - } - - ImportStackObject? stackObject; - var stackType = object.coreType; - switch (object.coreType) { - case BackboardBase.typeKey: - stackObject = BackboardImporter(artboardLookup, object as Backboard); - break; - case ArtboardBase.typeKey: - stackObject = ArtboardImporter(object as RuntimeArtboard); - break; - case LinearAnimationBase.typeKey: - stackObject = LinearAnimationImporter(object as LinearAnimation); - // helper = _AnimationImportHelper(); - break; - case KeyedObjectBase.typeKey: - stackObject = KeyedObjectImporter(object as KeyedObject); - break; - case KeyedPropertyBase.typeKey: - { - // KeyedProperty importer requires a linear animation importer, so - // make sure there's one on the stack. - var linearAnimationImporter = - importStack.requireLatest( - LinearAnimationBase.typeKey); - stackObject = KeyedPropertyImporter(object as KeyedProperty, - linearAnimationImporter.linearAnimation); - break; - } - case StateMachineBase.typeKey: - stackObject = StateMachineImporter(object as StateMachine); - break; - case StateMachineLayerBase.typeKey: - stackObject = StateMachineLayerImporter(object as StateMachineLayer); - break; - case StateMachineListenerBase.typeKey: - stackObject = - StateMachineListenerImporter(object as StateMachineListener); - break; - case NestedStateMachineBase.typeKey: - stackObject = - NestedStateMachineImporter(object as NestedStateMachine); - break; - case EntryStateBase.typeKey: - case AnyStateBase.typeKey: - case ExitStateBase.typeKey: - case AnimationStateBase.typeKey: - case BlendStateDirectBase.typeKey: - case BlendState1DBase.typeKey: - stackObject = LayerStateImporter(object as LayerState); - stackType = LayerStateBase.typeKey; - break; - case StateTransitionBase.typeKey: - case BlendStateTransitionBase.typeKey: - { - var stateMachineImporter = importStack - .requireLatest(StateMachineBase.typeKey); - stackObject = StateTransitionImporter( - object as StateTransition, stateMachineImporter); - stackType = StateTransitionBase.typeKey; - break; - } - case AudioAssetBase.typeKey: - case ImageAssetBase.typeKey: - case FontAssetBase.typeKey: - // all these stack objects are resolvers. they get resolved. - stackObject = FileAssetImporter( - object as FileAsset, - _assetLoader, - ); - stackType = FileAssetBase.typeKey; - break; - case ViewModelInstanceBase.typeKey: - // all these stack objects are resolvers. they get resolved. - stackObject = ViewModelInstanceImporter( - object as ViewModelInstance, - ); - stackType = ViewModelInstanceBase.typeKey; - break; - default: - if (object is Component) { - // helper = _ArtboardObjectImportHelper(); - } - break; - } - - if (!importStack.makeLatest(stackType, stackObject)) { - throw const RiveFormatErrorException('Rive file is corrupt.'); - } - // Special case for StateMachineLayerComponents as the concrete types also - // add importers. - if (object is StateMachineLayerComponent) { - if (!importStack.makeLatest(StateMachineLayerComponentBase.typeKey, - StateMachineLayerComponentImporter(object))) { - throw const RiveFormatErrorException('Rive file is corrupt.'); - } - } - - // Store all as some may fail to import (will be set to null, but we still - // want them to occupy an id). - if (object.import(importStack)) { - switch (object.coreType) { - case ArtboardBase.typeKey: - artboardLookup[artboardId++] = object as Artboard; - _artboards.add(object); - break; - case BackboardBase.typeKey: - if (_backboard != Backboard.unknown) { - throw const RiveFormatErrorException( - 'Rive file expects only one backboard.'); - } - _backboard = object as Backboard; - break; - } - } else { - switch (object.coreType) { - case ArtboardBase.typeKey: - artboardId++; - break; - } - } - } - if (!importStack.resolve()) { - throw const RiveFormatErrorException('Rive file is corrupt.'); - } - if (_backboard == Backboard.unknown) { - throw const RiveFormatErrorException('Rive file is missing a backboard.'); - } - - for (final artboard in _artboards) { - var runtimeArtboard = artboard as RuntimeArtboard; - for (final object in runtimeArtboard.objects.whereNotNull()) { - if (object.validate()) { - InternalCoreHelper.markValid(object); - } else { - throw RiveFormatErrorException( - 'Rive file is corrupt. Invalid $object.'); - } - } - } - } - - /// Imports a Rive file from an array of bytes. - /// - /// {@template rive_file_asset_loader_params} - /// Provide an [assetLoader] to load assets from a custom location (out of - /// band assets). See [CallbackAssetLoader] for an example. - /// - /// Set [loadCdnAssets] to `false` to disable loading assets from the CDN. - /// - /// Whether an assets is embedded/cdn/referenced is determined by the Rive - /// file - as set in the editor. - /// - /// Loading assets documentation: https://rive.app/community/doc/loading-assets/doct4wVHGPgC - /// {@endtemplate} - /// - /// Provide an [objectGenerator] if you want to override any built-in Rive - /// types. - /// - /// Will throw [RiveFormatErrorException] if data is malformed. Will throw - /// [RiveUnsupportedVersionException] if the version is not supported. - factory RiveFile.import( - ByteData bytes, { - FileAssetLoader? assetLoader, - ObjectGenerator? objectGenerator, - bool loadCdnAssets = true, - }) { - // TODO: in the next major version add an assert here to make this a - // requirement - if (!_initializedText) { - debugPrint('''Rive: RiveFile.import called before RiveFile.initialize() - -Consider calling `await RiveFile.initialize()` before using `RiveFile.import`'''); - } - - var reader = BinaryReader(bytes); - return RiveFile._( - reader, - RuntimeHeader.read(reader), - objectGenerator, - FallbackAssetLoader( - [ - if (assetLoader != null) assetLoader, - if (loadCdnAssets) CDNAssetLoader(), - ], - ), - ); - } - - static bool _initializedText = false; - - /// Initialize Rive's text, audio, and layout engines. - /// - /// This method is automatically called when using `RiveFile.asset`, - /// `RiveFile.network`, and `RiveFile.file`. - /// - /// When using `RiveFile.import` then `RiveFile.initialize()` should be - /// called manually. - /// - /// Consider calling `unawaited(RiveFile.initialize());` in the `main` method - /// to ensure the engine has initialized before displaying the first Rive - /// graphic. - static Future initialize() async { - if (!_initializedText) { - final status = await Font.initialize(); - if (status == FontInitStatus.success || - status == FontInitStatus.alreadyInitialized) { - _initializedText = true; - } - } - } - - /// Initialize Rive's text engine if it hasn't been yet. - @Deprecated('Use `initialize()` instead') - static Future initializeText() async { - await initialize(); - } - - static Future _initTextAndImport( - ByteData bytes, { - FileAssetLoader? assetLoader, - bool loadCdnAssets = true, - ObjectGenerator? objectGenerator, - }) async { - /// If the file looks like it needs the text runtime, let's load it. - if (!_initializedText) { - await initialize(); - } - return RiveFile.import( - bytes, - assetLoader: assetLoader, - loadCdnAssets: loadCdnAssets, - objectGenerator: objectGenerator, - ); - } - - /// Imports a Rive file from an asset bundle. - /// - /// Default uses [rootBundle] from Flutter. Provide a custom [bundle] to load - /// from a different bundle. - /// - /// {@macro rive_file_asset_loader_params} - /// - /// Whether an assets is embedded/cdn/referenced is determined by the Rive - /// file - as set in the editor. - static Future asset( - String bundleKey, { - AssetBundle? bundle, - FileAssetLoader? assetLoader, - bool loadCdnAssets = true, - ObjectGenerator? objectGenerator, - }) async { - final bytes = await (bundle ?? rootBundle).load( - bundleKey, - ); - - return _initTextAndImport( - bytes, - assetLoader: assetLoader, - loadCdnAssets: loadCdnAssets, - objectGenerator: objectGenerator, - ); - } - - /// Imports a Rive file from a [url] over HTTP. - /// - /// Provide [headers] to add custom HTTP headers to the request. - /// - /// {@macro rive_file_asset_loader_params} - /// - /// Whether an assets is embedded/cdn/referenced is determined by the Rive - /// file - as set in the editor. - static Future network( - String url, { - Map? headers, - FileAssetLoader? assetLoader, - bool loadCdnAssets = true, - ObjectGenerator? objectGenerator, - }) async { - final res = await http.get(Uri.parse(url), headers: headers); - final bytes = ByteData.view(res.bodyBytes.buffer); - return _initTextAndImport( - bytes, - assetLoader: assetLoader, - loadCdnAssets: loadCdnAssets, - objectGenerator: objectGenerator, - ); - } - - /// Imports a Rive file from local path - /// - /// {@macro rive_file_asset_loader_params} - /// - /// Whether an assets is embedded/cdn/referenced is determined by the Rive - /// file - as set in the editor. - static Future file( - String path, { - FileAssetLoader? assetLoader, - bool loadCdnAssets = true, - ObjectGenerator? objectGenerator, - }) async { - final bytes = await localFileBytes(path); - return _initTextAndImport( - ByteData.view(bytes!.buffer), - assetLoader: assetLoader, - loadCdnAssets: loadCdnAssets, - objectGenerator: objectGenerator, - ); - } - - /// Returns all artboards in the file - List get artboards => _artboards; - - /// Returns the first (main) artboard - Artboard get mainArtboard => _artboards.first; - - /// Returns an artboard from the specified name, or null if no artboard with - /// that name exists in the file - Artboard? artboardByName(String name) => - _artboards.firstWhereOrNull((a) => a.name == name); -} diff --git a/lib/src/rive_render_box.dart b/lib/src/rive_render_box.dart deleted file mode 100644 index cd3c694..0000000 --- a/lib/src/rive_render_box.dart +++ /dev/null @@ -1,421 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:rive_common/math.dart'; - -abstract class RiveRenderBox extends RenderBox { - Ticker? _ticker; - BoxFit _fit = BoxFit.none; - Alignment _alignment = Alignment.center; - bool _useArtboardSize = false; - Rect? _clipRect; - bool _tickerModeEnabled = true; - bool _enableHitTests = false; - bool _isTouchScrollEnabled = false; - - bool get useArtboardSize => _useArtboardSize; - - set useArtboardSize(bool value) { - if (_useArtboardSize == value) { - return; - } - _useArtboardSize = value; - if (parent != null) { - markNeedsLayoutForSizedByParentChange(); - } - } - - Size _artboardSize = Size.zero; - - Size get artboardSize => _artboardSize; - - set artboardSize(Size value) { - if (_artboardSize == value) { - return; - } - _artboardSize = value; - if (parent != null) { - markNeedsLayoutForSizedByParentChange(); - } - } - - BoxFit get fit => _fit; - - set fit(BoxFit value) { - if (value != _fit) { - _fit = value; - markNeedsPaint(); - } - } - - Alignment get alignment => _alignment; - - set alignment(Alignment value) { - if (value != _alignment) { - _alignment = value; - markNeedsPaint(); - } - } - - Rect? get clipRect => _clipRect; - - set clipRect(Rect? value) { - if (value != _clipRect) { - _clipRect = value; - markNeedsPaint(); - } - } - - bool get tickerModeEnabled => _tickerModeEnabled; - - set tickerModeEnabled(bool value) { - if (value != _tickerModeEnabled) { - _tickerModeEnabled = value; - - if (_tickerModeEnabled) { - _startTicker(); - } else { - _stopTicker(); - } - } - } - - bool get enableHitTests => _enableHitTests; - - set enableHitTests(bool value) { - if (value != _enableHitTests) { - _enableHitTests = value; - } - } - - bool get isTouchScrollEnabled => _isTouchScrollEnabled; - - set isTouchScrollEnabled(bool value) { - if (value != _isTouchScrollEnabled) { - _isTouchScrollEnabled = value; - } - } - - bool _paintedLastFrame = false; - - @override - bool get sizedByParent => !useArtboardSize; - - /// Finds the intrinsic size for the rive render box given the [constraints] - /// and [sizedByParent]. - /// - /// The difference between the intrinsic size returned here and the size we - /// use for [performResize] is that the intrinsics contract does not allow - /// infinite sizes, i.e. we cannot return biggest constraints. - /// Consequently, the smallest constraint is returned in case we are - /// [sizedByParent]. - Size _intrinsicSizeForConstraints(BoxConstraints constraints) { - if (sizedByParent) { - return constraints.smallest; - } - - return constraints - .constrainSizeAndAttemptToPreserveAspectRatio(artboardSize); - } - - @override - double computeMinIntrinsicWidth(double height) { - assert(height >= 0.0); - // If not sized by parent, this returns the constrained (trying to preserve - // aspect ratio) artboard size. - // If sized by parent, this returns 0 (because an infinite width does not - // make sense as an intrinsic width and is therefore not allowed). - return _intrinsicSizeForConstraints( - BoxConstraints.tightForFinite(height: height)) - .width; - } - - @override - double computeMaxIntrinsicWidth(double height) { - assert(height >= 0.0); - // This is equivalent to the min intrinsic width because we cannot provide - // any greater intrinsic width beyond which increasing the width never - // decreases the preferred height. - // When we have an artboard size, the intrinsic min and max width are - // obviously equivalent and if sized by parent, we can also only return the - // smallest width constraint (which is 0 in the case of intrinsic width). - return _intrinsicSizeForConstraints( - BoxConstraints.tightForFinite(height: height)) - .width; - } - - @override - double computeMinIntrinsicHeight(double width) { - assert(width >= 0.0); - // If not sized by parent, this returns the constrained (trying to preserve - // aspect ratio) artboard size. - // If sized by parent, this returns 0 (because an infinite height does not - // make sense as an intrinsic height and is therefore not allowed). - return _intrinsicSizeForConstraints( - BoxConstraints.tightForFinite(width: width)) - .height; - } - - @override - double computeMaxIntrinsicHeight(double width) { - assert(width >= 0.0); - // This is equivalent to the min intrinsic height because we cannot provide - // any greater intrinsic height beyond which increasing the height never - // decreases the preferred width. - // When we have an artboard size, the intrinsic min and max height are - // obviously equivalent and if sized by parent, we can also only return the - // smallest height constraint (which is 0 in the case of intrinsic height). - return _intrinsicSizeForConstraints( - BoxConstraints.tightForFinite(width: width)) - .height; - } - - // This replaces the old performResize method. - @override - Size computeDryLayout(BoxConstraints constraints) { - return constraints.biggest; - } - - @override - void performLayout() { - if (!sizedByParent) { - // We can use the intrinsic size here because the intrinsic size matches - // the constrained artboard size when not sized by parent. - size = _intrinsicSizeForConstraints(constraints); - } - } - - @override - bool hitTestSelf(Offset screenOffset) => true; - - // Override this to false if you don't want the local offset applied to the - // view transform passed to the draw method. - bool get offsetViewTransform => true; - - @override - void detach() { - _stopTicker(); - - super.detach(); - } - - @override - void dispose() { - _ticker?.dispose(); - _ticker = null; - - super.dispose(); - } - - @override - void attach(PipelineOwner owner) { - super.attach(owner); - - _ticker = Ticker(_frameCallback); - if (tickerModeEnabled) { - _startTicker(); - } - } - - void _stopTicker() { - _elapsedSeconds = 0; - _prevTickerElapsedInSeconds = 0; - - _ticker?.stop(); - } - - void _startTicker() { - _elapsedSeconds = 0; - _prevTickerElapsedInSeconds = 0; - - // Always ensure ticker is stopped before starting - if (_ticker?.isActive ?? false) { - _ticker?.stop(); - } - _ticker?.start(); - } - - void _restartTickerIfStopped() { - if (_ticker != null && !_ticker!.isActive && tickerModeEnabled) { - _startTicker(); - } - } - - /// Get the Axis Aligned Bounding Box that encompasses the world space scene - AABB get aabb; - - void draw(Canvas canvas, Mat2D viewTransform); - - void beforeDraw(Canvas canvas, Offset offset) {} - - void afterDraw(Canvas canvas, Offset offset) {} - - /// Time between frame callbacks - double _elapsedSeconds = 0; - - /// The total time [_ticker] has been active in seconds - double _prevTickerElapsedInSeconds = 0; - - void _calculateElapsedSeconds(Duration duration) { - final double tickerElapsedInSeconds = - duration.inMicroseconds.toDouble() / Duration.microsecondsPerSecond; - assert(tickerElapsedInSeconds >= 0.0); - - _elapsedSeconds = tickerElapsedInSeconds - _prevTickerElapsedInSeconds; - _prevTickerElapsedInSeconds = tickerElapsedInSeconds; - } - - void _frameCallback(Duration duration) { - // Under certain conditions Flutter will not call paint (for optimization). - // If the animation did not paint in the last frame, we force - // advance so that the animation can reach a settled state. - - // TODO: Ideally "advance" should only happen inside_`_frameCallback` - // and not inside `paint`. But to support backwards compatibility we - // will continue to advance in `paint` (golden tests), and just introduce - // this as a backup to resolve: - // - https://github.com/rive-app/rive-flutter/issues/409 - // - https://github.com/rive-app/rive-flutter/issues/408 - // - // In the next version of the runtime that uses rive_native we can rework - // this logic. - // - // TODO: We also need to consider standard default behaviour for what - // Rive should do when not visible on the screen - // - Advance and not draw - // - Draw and advance - // - Neither advance nor draw - // - (Optional enum for users to choose) - if (!_paintedLastFrame) { - _advanceFrame(); - } - - _calculateElapsedSeconds(duration); - - _paintedLastFrame = false; - markNeedsPaint(); - } - - void scheduleRepaint() => _restartTickerIfStopped(); - - /// Override this if you want to do custom viewTransform alignment. This will - /// be called after advancing. Return true to prevent regular paint. - bool customPaint(PaintingContext context, Offset offset) => false; - - Vec2D globalToArtboard(Offset globalPosition) { - var local = globalToLocal(globalPosition); - var alignArtboard = computeAlignment(); - var localToArtboard = Mat2D(); - var localAsVec = Vec2D.fromValues(local.dx, local.dy); - if (!Mat2D.invert(localToArtboard, alignArtboard)) { - return localAsVec; - } - return Vec2D.transformMat2D(Vec2D(), localAsVec, localToArtboard); - } - - Mat2D computeAlignment([Offset offset = Offset.zero]) { - AABB frame = AABB.fromValues( - offset.dx, offset.dy, offset.dx + size.width, offset.dy + size.height); - AABB content = aabb; - - double contentWidth = content.width; - double contentHeight = content.height; - - if (contentWidth == 0 || contentHeight == 0) { - return Mat2D(); - } - - double x = -1 * content.left - - contentWidth / 2.0 - - (_alignment.x * contentWidth / 2.0); - double y = -1 * content.top - - contentHeight / 2.0 - - (_alignment.y * contentHeight / 2.0); - - double scaleX = 1.0, scaleY = 1.0; - - switch (_fit) { - case BoxFit.fill: - scaleX = frame.width / contentWidth; - scaleY = frame.height / contentHeight; - break; - case BoxFit.contain: - double minScale = - min(frame.width / contentWidth, frame.height / contentHeight); - scaleX = scaleY = minScale; - break; - case BoxFit.cover: - double maxScale = - max(frame.width / contentWidth, frame.height / contentHeight); - scaleX = scaleY = maxScale; - break; - case BoxFit.fitHeight: - double minScale = frame.height / contentHeight; - scaleX = scaleY = minScale; - break; - case BoxFit.fitWidth: - double minScale = frame.width / contentWidth; - scaleX = scaleY = minScale; - break; - case BoxFit.none: - scaleX = scaleY = 1.0; - break; - case BoxFit.scaleDown: - double minScale = - min(frame.width / contentWidth, frame.height / contentHeight); - scaleX = scaleY = minScale < 1.0 ? minScale : 1.0; - break; - } - - Mat2D transform = Mat2D(); - - transform[4] = frame.width / 2.0 + (_alignment.x * frame.width / 2.0); - transform[5] = frame.height / 2.0 + (_alignment.y * frame.height / 2.0); - if (offsetViewTransform) { - transform[4] += offset.dx; - transform[5] += offset.dy; - } - Mat2D.scale(transform, transform, Vec2D.fromValues(scaleX, scaleY)); - Mat2D center = Mat2D(); - center[4] = x; - center[5] = y; - Mat2D.multiply(transform, transform, center); - return transform; - } - - void _advanceFrame() { - if (!advance(_elapsedSeconds)) { - _stopTicker(); - } - _elapsedSeconds = 0; - } - - @protected - @override - void paint(PaintingContext context, Offset offset) { - _paintedLastFrame = true; - _advanceFrame(); - - if (customPaint(context, offset)) { - return; - } - - final Canvas canvas = context.canvas; - - canvas.save(); - beforeDraw(canvas, offset); - - var transform = computeAlignment(offset); - - draw(canvas, transform); - - canvas.restore(); - afterDraw(canvas, offset); - } - - /// Advance animations, physics, etc by elapsedSeconds, returns true if it - /// wants to run again. - bool advance(double elapsedSeconds); -} diff --git a/lib/src/rive_scene.dart b/lib/src/rive_scene.dart deleted file mode 100644 index 4a2cc89..0000000 --- a/lib/src/rive_scene.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:rive/src/rive_render_box.dart'; -import 'package:rive_common/math.dart'; - -/// An abstraction for controlling the composition and rendering of a Rive -/// scene. -abstract class RiveSceneController { - /// Whether the draw callback's view transform should be translated by the - /// rendering widgets local offset. - bool get offsetViewTransform => false; - - /// SceneController uses this to notify that it needs to be re-drawn. - ChangeNotifier get redraw; - - // Tells the Scene how to align the area nesessary to display the contents. - Size get size; - - /// Called by the scene, return true to keep advancing or false to stop. - bool advance(double elapsedSeconds); - - /// Called by the scene to draw the contents. - void draw(Canvas canvas, Mat2D viewTransform); -} - -/// A widget that interfaces with a RiveSceneController to compose and render a -/// scene of Rive artboards. -class RiveScene extends LeafRenderObjectWidget { - /// The controller for the Rive scene. - final RiveSceneController controller; - - /// Fit for the rendering artboard - final BoxFit fit; - - /// Alignment for the rendering artboard - final Alignment alignment; - - const RiveScene({ - required this.controller, - BoxFit? fit, - Alignment? alignment, - Key? key, - }) : fit = fit ?? BoxFit.contain, - alignment = alignment ?? Alignment.center, - super(key: key); - - @override - RenderObject createRenderObject(BuildContext context) { - return RiveSceneRenderObject(controller) - ..fit = fit - ..alignment = alignment; - } - - @override - void updateRenderObject( - BuildContext context, covariant RiveSceneRenderObject renderObject) { - renderObject - ..controller = controller - ..fit = fit - ..alignment = alignment; - } -} - -class RiveSceneRenderObject extends RiveRenderBox { - RiveSceneController _controller; - RiveSceneRenderObject(this._controller) { - _controller.redraw.addListener(scheduleRepaint); - } - - RiveSceneController get controller => _controller; - - set controller(RiveSceneController value) { - if (_controller == value) { - return; - } - _controller.redraw.removeListener(scheduleRepaint); - _controller = value; - _controller.redraw.addListener(scheduleRepaint); - markNeedsLayout(); - } - - @override - void dispose() { - _controller.redraw.removeListener(scheduleRepaint); - super.dispose(); - } - - @override - AABB get aabb { - var width = _controller.size.width; - var height = _controller.size.height; - return AABB.fromValues(0, 0, width, height); - } - - @override - bool advance(double elapsedSeconds) => _controller.advance(elapsedSeconds); - - @override - void beforeDraw(Canvas canvas, Offset offset) { - canvas.clipRect(offset & size); - } - - @override - void draw(Canvas canvas, Mat2D viewTransform) { - _controller.draw(canvas, viewTransform); - } - - @override - bool get offsetViewTransform => _controller.offsetViewTransform; -} diff --git a/lib/src/runtime_artboard.dart b/lib/src/runtime_artboard.dart deleted file mode 100644 index ca9594a..0000000 --- a/lib/src/runtime_artboard.dart +++ /dev/null @@ -1,260 +0,0 @@ -import 'package:flutter/scheduler.dart'; -import 'package:rive/rive.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/component.dart'; -import 'package:rive/src/rive_core/notifier.dart'; - -/// Adds getters for linear animations and state machines -extension RuntimeArtboardGetters on RuntimeArtboard { - /// Returns an iterable of linear animations in the artboard - Iterable get linearAnimations => - animations.whereType(); - - /// Returns an iterable of state machines in the artboard - Iterable get stateMachines => - animations.whereType(); -} - -extension ArtboardRuntimeExtensions on Artboard { - NestedArtboard? nestedArtboard(String name) { - for (final artboard in activeNestedArtboards) { - if (artboard.name == name) { - return artboard; - } - } - return null; - } - - NestedArtboard? nestedArtboardAtPath(String path) { - const delimiter = '/'; - final dIndex = path.indexOf(delimiter); - final artboardName = dIndex == -1 ? path : path.substring(0, dIndex); - final restOfPath = - dIndex == -1 ? '' : path.substring(dIndex + 1, path.length); - if (artboardName.isNotEmpty) { - final nested = nestedArtboard(artboardName); - if (nested != null) { - if (restOfPath.isEmpty) { - return nested; - } else { - return nested.nestedArtboardAtPath(restOfPath); - } - } - } - return null; - } - - T? findSMI(String name, String path) { - final nested = nestedArtboardAtPath(path); - if (nested != null) { - if (nested.mountedArtboard is RuntimeMountedArtboard) { - final runtimeMountedArtboard = - nested.mountedArtboard as RuntimeMountedArtboard; - final controllers = runtimeMountedArtboard.controllers; - for (final controller in controllers) { - for (final input in controller.inputs) { - if (input is T && input.name == name) { - return input as T; - } - } - } - } - } - return null; - } - - /// Find a boolean input with a given name on a nested artboard at path. - SMIBool? getBoolInput(String name, String path) => - findSMI(name, path); - - /// Find a trigger input with a given name on a nested artboard at path. - SMITrigger? getTriggerInput(String name, String path) => - findSMI(name, path); - - /// Find a number input with a given name on a nested artboard at path. - /// - /// See [triggerInput] to directly fire a trigger by its name. - SMINumber? getNumberInput(String name, String path) => - findSMI(name, path); - - /// Convenience method for firing a trigger input with a given name - /// on a nested artboard at path. - /// - /// Also see [getTriggerInput] to get a reference to the trigger input. If the - /// trigger happens frequently, it's more efficient to get a reference to the - /// trigger input and call `trigger.fire()` directly. - void triggerInput(String name, String path) => - getTriggerInput(name, path)?.fire(); -} - -/// This artboard type is purely for use by the runtime system and should not be -/// directly referenced. Use the Artboard type for any direct interactions with -/// an artboard, and use extension methods to add functionality to Artboard. -class RuntimeArtboard extends Artboard implements CoreContext { - final _redraw = Notifier(); - ChangeNotifier get redraw => _redraw; - - /// Note that objects must be nullable as some may not resolve during load due - /// to format differences. - final List _objects = []; - - Iterable get objects => _objects; - final Set _needDependenciesBuilt = {}; - - // Indicates if this artboard is playing or paused - bool _isPlaying = true; - - @override - T? addObject(T? object) { - object?.context = this; - object?.id = _objects.length; - - _objects.add(object); - return object; - } - - @override - void removeObject(T object) { - _objects.remove(object); - } - - @override - void markDependencyOrderDirty() {} - - @override - bool markDependenciesDirty(covariant Core object) { - if (object is Component) { - _needDependenciesBuilt.add(object); - return true; - } - - return false; - } - - void clean() { - if (_needDependenciesBuilt.isNotEmpty) { - // Copy it in case it is changed during the building (meaning this process - // needs to recurse). - Set needDependenciesBuilt = - Set.from(_needDependenciesBuilt); - _needDependenciesBuilt.clear(); - - // First resolve the artboards - for (final component in needDependenciesBuilt) { - component.resolveArtboard(); - } - - // Then build the dependencies - for (final component in needDependenciesBuilt) { - component.buildDependencies(); - } - - sortDependencies(); - computeDrawOrder(); - } - } - - @override - T? resolve(int id) { - if (id >= _objects.length || id < 0) { - return null; - } - var object = _objects[id]; - if (object is T) { - return object as T; - } - return null; - } - - @override - T resolveWithDefault(int id, T defaultValue) { - if (id < 0 || id >= _objects.length) { - return defaultValue; - } - var object = _objects[id]; - if (object is T) { - return object as T; - } - return defaultValue; - } - - @override - Core? makeCoreInstance(int typeKey) => - RiveCoreContext.makeCoreInstance(typeKey); - - @override - void dirty(void Function() dirt) { - // TODO: Schedule a debounced callback for next frame - } - - @override - void markNeedsAdvance() { - _redraw.notify(); - } - - @override - Artboard instance() { - var artboard = RuntimeArtboard(); - artboard.context = artboard; - artboard.frameOrigin = frameOrigin; - artboard.copy(this); - artboard._objects.add(artboard); - // First copy the objects ensuring onAddedDirty can later find them in the - // _objects list. - for (final object in _objects.skip(1)) { - Core? clone = object?.clone(); - artboard.addObject(clone); - } - - // Then run the onAddedDirty loop. - for (final object in artboard.objects.skip(1)) { - if (object is Component && - object.parentId == ComponentBase.parentIdInitialValue) { - object.parent = artboard; - } - object?.onAddedDirty(); - } - animations.forEach(artboard.animations.add); - for (final object in artboard.objects.toList(growable: false)) { - if (object == null) { - continue; - } - object.onAdded(); - InternalCoreHelper.markValid(object); - } - artboard.clean(); - return artboard; - } - - void addNestedEventListener(StateMachineController controller) { - activeNestedArtboards.forEach((artboard) { - if (artboard.mountedArtboard is RuntimeMountedArtboard) { - (artboard.mountedArtboard as RuntimeMountedArtboard).eventCallback = - (event, target) => _handleNestedEvent(event, target, controller); - } - }); - } - - void _handleNestedEvent( - Event event, NestedArtboard target, StateMachineController controller) { - if (controller.hasListenerWithTarget(target)) { - controller.reportNestedEvent(event, target); - SchedulerBinding.instance - .addPostFrameCallback((_) => controller.isActive = true); - } - } - - @override - void pause() { - _isPlaying = false; - } - - @override - void play() { - _isPlaying = true; - markNeedsAdvance(); - } - - @override - bool get isPlaying => _isPlaying; -} diff --git a/lib/src/runtime_event.dart b/lib/src/runtime_event.dart deleted file mode 100644 index 113c632..0000000 --- a/lib/src/runtime_event.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:rive/src/rive_core/custom_property_boolean.dart'; -import 'package:rive/src/rive_core/custom_property_number.dart'; -import 'package:rive/src/rive_core/custom_property_string.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/open_url_event.dart'; -import 'package:rive/src/rive_core/open_url_target.dart'; - -/// A Rive Event that is reported from an StateMachineController. -/// -/// See: -/// - [RiveGeneralEvent] -/// - [RiveOpenURLEvent] -/// -/// For specific event types. -/// -/// Documentation: https://rive.app/community/doc/rive-events/docbOnaeffgr -@immutable -class RiveEvent { - final String name; - final double secondsDelay; - final Map properties; - - const RiveEvent({ - required this.name, - required this.secondsDelay, - required this.properties, - }); - - factory RiveEvent.fromCoreEvent(Event event) { - final Map properties = {}; - for (final property in event.customProperties) { - dynamic value; - switch (property.coreType) { - case CustomPropertyNumberBase.typeKey: - value = (property as CustomPropertyNumber).propertyValue; - break; - case CustomPropertyStringBase.typeKey: - value = (property as CustomPropertyString).propertyValue; - break; - case CustomPropertyBooleanBase.typeKey: - value = (property as CustomPropertyBoolean).propertyValue; - break; - } - if (value != null) { - properties[property.name] = value; - } - } - if (event.coreType == OpenUrlEventBase.typeKey) { - event = event as OpenUrlEvent; - return RiveOpenURLEvent( - name: event.name, - url: event.url, - target: event.target, - secondsDelay: event.secondsDelay, - properties: properties, - ); - } else { - return RiveGeneralEvent( - name: event.name, - secondsDelay: event.secondsDelay, - properties: properties, - ); - } - } - - @override - String toString() => 'Rive Event - name: $name, properties: $properties'; -} - -/// A general Rive event that provides information about the event. -@immutable -class RiveGeneralEvent extends RiveEvent { - const RiveGeneralEvent({ - required String name, - required double secondsDelay, - required Map properties, - }) : super(name: name, secondsDelay: secondsDelay, properties: properties); - - @override - String toString() => - 'Rive GeneralEvent - name: $name, properties: $properties'; -} - -/// An Open URL Rive event that provides information about the URL and target. -/// -/// See: -/// - [url] -/// - [target] -@immutable -class RiveOpenURLEvent extends RiveEvent { - final String url; - final OpenUrlTarget target; - const RiveOpenURLEvent({ - required String name, - required double secondsDelay, - required Map properties, - required this.target, - required this.url, - }) : super(name: name, secondsDelay: secondsDelay, properties: properties); - - @override - String toString() => - 'Rive OpenURLEvent - name: $name, properties: $properties'; -} diff --git a/lib/src/runtime_mounted_artboard.dart b/lib/src/runtime_mounted_artboard.dart deleted file mode 100644 index 50f1742..0000000 --- a/lib/src/runtime_mounted_artboard.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'package:flutter/rendering.dart'; -import 'package:rive/src/controllers/state_machine_controller.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/data_bind/data_bind.dart'; -import 'package:rive/src/rive_core/data_bind/data_context.dart'; -import 'package:rive/src/rive_core/event.dart'; -import 'package:rive/src/rive_core/nested_artboard.dart'; -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance.dart'; -import 'package:rive_common/math.dart'; - -/// Callback signature for events firing. -typedef OnRuntimeEvent = void Function(Event); - -abstract class RuntimeEventReporter { - void addRuntimeEventListener(OnRuntimeEvent callback); - void removeRuntimeEventListener(OnRuntimeEvent callback); -} - -class RuntimeMountedArtboard extends MountedArtboard { - NestedArtboard nestedArtboard; - final RuntimeArtboard artboardInstance; - final Set _runtimeEventListeners = {}; - Size originalArtboardInstanceSize = const Size(0, 0); - - Set get controllers => - _runtimeEventListeners.whereType().toSet(); - - // The callback used for bubbling events up from nested artboards - Function(Event, NestedArtboard)? eventCallback; - - RuntimeMountedArtboard(this.artboardInstance, this.nestedArtboard) { - // Store the initial w/h of the artboard and use that as the starting point - originalArtboardInstanceSize = - Size(artboardInstance.width, artboardInstance.height); - artboardInstance.frameOrigin = false; - artboardInstance.advance(0, nested: true); - } - - @override - void populateDataBinds(List globalDataBinds) { - artboardInstance.populateDataBinds(globalDataBinds); - } - - @override - void dispose() { - _runtimeEventListeners.clear(); - eventCallback = null; - } - - @override - Mat2D worldTransform = Mat2D(); - - @override - void draw(Canvas canvas) { - canvas.save(); - canvas.transform(worldTransform.mat4); - artboardInstance.draw(canvas); - canvas.restore(); - } - - @override - AABB get bounds { - var width = originalArtboardWidth; - - var height = originalArtboardHeight; - var x = -artboardInstance.originX * width; - var y = -artboardInstance.originY * height; - return AABB.fromValues(x, y, x + width, y + height); - } - - @override - double get renderOpacity => artboardInstance.opacity; - - @override - double get artboardWidth => artboardInstance.width; - - @override - set artboardWidth(double width) { - artboardInstance.width = width; - } - - @override - double get artboardHeight => artboardInstance.height; - - @override - set artboardHeight(double height) { - artboardInstance.height = height; - } - - @override - void artboardWidthOverride(double width, int widthUnitValue, bool isRow) {} - - @override - void artboardHeightOverride(double height, int heightUnitValue, bool isRow) {} - - @override - void artboardWidthIntrinsicallySizeOverride(bool intrinsic) {} - - @override - void artboardHeightIntrinsicallySizeOverride(bool intrinsic) {} - - @override - void updateLayoutBounds(bool animate) {} - - @override - double get originalArtboardWidth => originalArtboardInstanceSize.width; - - @override - double get originalArtboardHeight => originalArtboardInstanceSize.height; - - @override - set renderOpacity(double value) { - artboardInstance.opacity = value; - } - - @override - bool advance(double seconds, {bool nested = true}) => - artboardInstance.advance(seconds, nested: nested); - - void addEventListener(RuntimeEventReporter listener) { - _runtimeEventListeners.add(listener); - listener.addRuntimeEventListener(_handleRuntimeEvent); - // Pass an event callback into the child nested artboard's - // mounted artboard so we get an event bubbled up to us - artboardInstance.activeNestedArtboards.forEach((artboard) { - if (artboard.mountedArtboard is RuntimeMountedArtboard) { - (artboard.mountedArtboard as RuntimeMountedArtboard).eventCallback = - _handleNestedEvent; - } - }); - } - - void removeEventListeners() { - _runtimeEventListeners.forEach( - (listener) => listener.removeRuntimeEventListener(_handleRuntimeEvent)); - _runtimeEventListeners.clear(); - } - - void _handleRuntimeEvent(Event event) { - if (eventCallback != null) { - eventCallback!(event, nestedArtboard); - } - } - - void _handleNestedEvent(Event event, NestedArtboard target) { - _runtimeEventListeners.forEach((listener) { - if (listener is StateMachineController && - listener.hasListenerWithTarget(target)) { - listener.reportNestedEvent(event, target); - listener.isActive = true; - } - }); - } - - @override - void bindViewModelInstance(ViewModelInstance viewModelInstance, - DataContext? dataContextValue, bool isRoot) { - artboardInstance.bindViewModelInstance( - viewModelInstance, dataContextValue, isRoot); - } - - @override - void internalDataContext(DataContext dataContextValue, - DataContext? parentDataContext, bool isRoot) { - artboardInstance.internalDataContext( - dataContextValue, parentDataContext, isRoot); - } -} diff --git a/lib/src/runtime_nested_artboard.dart b/lib/src/runtime_nested_artboard.dart deleted file mode 100644 index f9f648b..0000000 --- a/lib/src/runtime_nested_artboard.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'package:flutter/rendering.dart'; -import 'package:rive/rive.dart'; -import 'package:rive/src/core/core.dart'; -import 'package:rive/src/rive_core/animation/nested_linear_animation.dart'; -import 'package:rive/src/rive_core/animation/nested_state_machine.dart'; -import 'package:rive/src/rive_core/state_machine_controller.dart' - as state_machine_core; -import 'package:rive_common/math.dart'; - -extension NestedArtboardRuntimeExtension on NestedArtboard { - NestedArtboard? nestedArtboardAtPath(String path) { - if (mountedArtboard is RuntimeMountedArtboard) { - final runtimeMountedArtboard = mountedArtboard as RuntimeMountedArtboard; - return runtimeMountedArtboard.artboardInstance.nestedArtboardAtPath(path); - } - return null; - } -} - -class RuntimeNestedArtboard extends NestedArtboard { - Artboard? sourceArtboard; - @override - K? clone>() { - var object = RuntimeNestedArtboard(); - object.copy(this); - if (sourceArtboard != null) { - object.sourceArtboard = sourceArtboard; - var runtimeArtboardInstance = - sourceArtboard!.instance() as RuntimeArtboard; - object.mountedArtboard = - RuntimeMountedArtboard(runtimeArtboardInstance, object); - } - return object as K; - } - - @override - void onAdded() { - super.onAdded(); - if (mountedArtboard is! RuntimeMountedArtboard || - sourceArtboard == null || - animations.isEmpty) { - return; - } - var runtimeLinearAnimations = - sourceArtboard!.linearAnimations.toList(growable: false); - var runtimeStateMachines = - sourceArtboard!.stateMachines.toList(growable: false); - for (final animation in animations) { - if (animation is NestedLinearAnimation) { - var animationId = animation.animationId; - if (animationId >= 0 && animationId < runtimeLinearAnimations.length) { - final linearAnimationInstance = LinearAnimationInstance( - runtimeLinearAnimations[animationId], - context: - (mountedArtboard as RuntimeMountedArtboard).artboardInstance); - animation.linearAnimationInstance = - RuntimeNestedLinearAnimationInstance(linearAnimationInstance); - if (mountedArtboard is RuntimeMountedArtboard) { - (mountedArtboard as RuntimeMountedArtboard) - .addEventListener(linearAnimationInstance); - } - } - } else if (animation is NestedStateMachine) { - var animationId = animation.animationId; - if (animationId >= 0 && animationId < runtimeStateMachines.length) { - final controller = - StateMachineController(runtimeStateMachines[animationId]); - animation.stateMachineInstance = RuntimeNestedStateMachineInstance( - (mountedArtboard as RuntimeMountedArtboard).artboardInstance, - controller, - ); - if (mountedArtboard is RuntimeMountedArtboard) { - final runtimeMountedArtboard = - mountedArtboard as RuntimeMountedArtboard; - runtimeMountedArtboard.addEventListener(controller); - } - } - } - } - } -} - -class RuntimeNestedLinearAnimationInstance - extends NestedLinearAnimationInstance { - final LinearAnimationInstance linearAnimation; - - RuntimeNestedLinearAnimationInstance(this.linearAnimation); - - @override - void apply(RuntimeMountedArtboard artboard, double mix) { - linearAnimation.animation.apply(linearAnimation.time, - coreContext: artboard.artboardInstance, mix: mix); - } - - @override - bool advance(double elapsedSeconds) { - linearAnimation.advance(elapsedSeconds * speed, - callbackReporter: linearAnimation); - return linearAnimation.keepGoing; - } - - @override - double speed = 1; - - @override - void goto(double value) { - var localTime = linearAnimation.animation.globalToLocalTime(value); - if (localTime == linearAnimation.time) { - return; - } - linearAnimation.time = localTime; - } - - @override - double get durationSeconds => linearAnimation.animation.durationSeconds; -} - -class RuntimeNestedStateMachineInstance extends NestedStateMachineInstance { - final StateMachineController stateMachineController; - - RuntimeNestedStateMachineInstance( - RuntimeArtboard artboard, this.stateMachineController) { - stateMachineController.init(artboard); - } - - @override - void apply(RuntimeMountedArtboard artboard, double elapsedSeconds) { - stateMachineController.apply(artboard.artboardInstance, elapsedSeconds); - } - - @override - bool get isActive => stateMachineController.isActive; - - @override - ValueListenable get isActiveChanged => - stateMachineController.isActiveChanged; - - @override - bool hitTest(Vec2D position) => stateMachineController.hitTest(position); - - @override - state_machine_core.HitResult pointerDown( - Vec2D position, PointerDownEvent event) { - final result = stateMachineController.pointerDown(position, event); - - return result; - } - - @override - state_machine_core.HitResult pointerMove(Vec2D position) => - stateMachineController.pointerMove(position); - - @override - state_machine_core.HitResult pointerUp(Vec2D position) => - stateMachineController.pointerUp(position); - - @override - state_machine_core.HitResult pointerExit(Vec2D position) => - stateMachineController.pointerExit(position); - - @override - dynamic getInputValue(int id) => stateMachineController.getInputValue(id); - @override - void setInputValue(int id, dynamic value) { - var inputs = stateMachineController.stateMachine.inputs; - if (id < inputs.length && id >= 0) { - stateMachineController.setInputValue(inputs[id].id, value); - } - } -} diff --git a/lib/src/state_machine_components.dart b/lib/src/state_machine_components.dart deleted file mode 100644 index 927ae98..0000000 --- a/lib/src/state_machine_components.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/animation/state_machine_component.dart'; - -class StateMachineComponents - extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - T operator [](int index) => _values[index]!; - - @override - void operator []=(int index, T value) => _values[index] = value; -} diff --git a/lib/src/state_transition_conditions.dart b/lib/src/state_transition_conditions.dart deleted file mode 100644 index b25d858..0000000 --- a/lib/src/state_transition_conditions.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/animation/transition_condition.dart'; - -class StateTransitionConditions extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - TransitionCondition operator [](int index) => _values[index]!; - - @override - void operator []=(int index, TransitionCondition value) => - _values[index] = value; -} diff --git a/lib/src/state_transitions.dart b/lib/src/state_transitions.dart deleted file mode 100644 index 006203f..0000000 --- a/lib/src/state_transitions.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'dart:collection'; -import 'package:rive/src/rive_core/animation/state_transition.dart'; - -class StateTransitions extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - StateTransition operator [](int index) => _values[index]!; - - @override - void operator []=(int index, StateTransition value) => _values[index] = value; -} diff --git a/lib/src/utilities/utilities.dart b/lib/src/utilities/utilities.dart deleted file mode 100644 index eb1a7fe..0000000 --- a/lib/src/utilities/utilities.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'dart:typed_data'; - -/// Szudzik's function for hashing two ints together -int szudzik(int a, int b) { - // a and b must be >= 0 - int x = a.abs(); - int y = b.abs(); - return x >= y ? x * x + x + y : x + y * y; -} - -String byteToHex(int byte) { - return byte.toRadixString(16).padLeft(2, '0'); -} - -/// Adapted from: -/// https://github.com/daegalus/dart-uuid/blob/main/lib/parsing.dart -/// -/// Unparses a [buffer] of bytes and outputs a proper UUID string. -/// -/// Throws a [RangeError] exception if the [buffer] is not large enough to -/// hold the bytes. -String formatUuid(Uint8List buffer) { - if (buffer.length < 16) { - throw RangeError('buffer too small: need 16: length=${buffer.length}'); - } - var i = 0; - return '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '-' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '-' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '-' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '-' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}' - '${byteToHex(buffer[i++])}${byteToHex(buffer[i++])}'; -} - -Uint8List uuidVariant2(Uint8List uuidBuffer) { - return Uint8List.fromList([ - uuidBuffer[3], - uuidBuffer[2], - uuidBuffer[1], - uuidBuffer[0], - // - - uuidBuffer[5], - uuidBuffer[4], - // - - uuidBuffer[7], - uuidBuffer[6], - // - - uuidBuffer[9], - uuidBuffer[8], - // - - uuidBuffer[15], - uuidBuffer[14], - uuidBuffer[13], - uuidBuffer[12], - uuidBuffer[11], - uuidBuffer[10], - ]); -} diff --git a/lib/src/viewmodel_list_items.dart b/lib/src/viewmodel_list_items.dart deleted file mode 100644 index 6835e83..0000000 --- a/lib/src/viewmodel_list_items.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_instance_list_item.dart'; - -class ViewModelListItems - extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - T operator [](int index) => _values[index]!; - - @override - void operator []=(int index, T value) => _values[index] = value; -} diff --git a/lib/src/viewmodel_properties.dart b/lib/src/viewmodel_properties.dart deleted file mode 100644 index cd9c88c..0000000 --- a/lib/src/viewmodel_properties.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'dart:collection'; - -import 'package:rive/src/rive_core/viewmodel/viewmodel_property.dart'; - -class ViewModelProperties extends ListBase { - final List _values = []; - List get values => _values.cast(); - - @override - int get length => _values.length; - - @override - set length(int value) => _values.length = value; - - @override - T operator [](int index) => _values[index]!; - - @override - void operator []=(int index, T value) => _values[index] = value; -} diff --git a/lib/src/widgets/rive_animation.dart b/lib/src/widgets/rive_animation.dart deleted file mode 100644 index c8d6177..0000000 --- a/lib/src/widgets/rive_animation.dart +++ /dev/null @@ -1,374 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/widgets.dart'; -import 'package:rive/rive.dart'; - -/// Specifies whether a source is from an asset bundle or http -enum _Source { - asset, - network, - file, - direct, -} - -/// The callback signature for onInit -typedef OnInitCallback = void Function(Artboard); - -/// High level widget that plays an animation from a Rive file. If artboard or -/// animation are not specified, the default artboard and first animation found -/// within it are used. -class RiveAnimation extends StatefulWidget { - /// The asset name or url - final String? name; - - /// The Rive File object - final RiveFile? file; - - /// The type of source used to retrieve the asset - final _Source src; - - /// The name of the artboard to use; default artboard if not specified - final String? artboard; - - /// List of animations to play; default animation if not specified - final List animations; - - /// List of state machines to play; none will play if not specified - final List stateMachines; - - /// Fit for the animation in the widget - final BoxFit? fit; - - /// Alignment for the animation in the widget - final Alignment? alignment; - - /// Widget displayed while the rive is loading - final Widget? placeHolder; - - /// Enable/disable antialiasing when rendering - final bool antialiasing; - - /// {@macro Rive.useArtboardSize} - final bool useArtboardSize; - - /// {@macro Rive.clipRect} - final Rect? clipRect; - - /// Controllers for instanced animations and state machines; use this - /// to directly control animation states instead of passing names. - final List controllers; - - /// Callback fired when [RiveAnimation] has initialized - final OnInitCallback? onInit; - - /// Headers for network requests - final Map? headers; - - /// {@macro Rive.behavior} - final RiveHitTestBehavior behavior; - - /// Rive object generator to override built-in types and methods to, for - /// example, interject custom rendering functionality interleaved with Rive - /// rendering. - final ObjectGenerator? objectGenerator; - - /// A multiplier for controlling the speed of the Rive animation playback. - /// - /// Default `1.0`. - final double speedMultiplier; - - /// For Rive Listeners, allows scrolling behavior to still occur on Rive - /// widgets when a touch/drag action is performed on touch-enabled devices. - /// Otherwise, scroll behavior may be prevented on touch/drag actions on the - /// widget by default. - /// - /// Default `false`. - final bool isTouchScrollEnabled; - - /// Creates a new [RiveAnimation] from an asset bundle. - /// - /// *Example:* - /// ```dart - /// return RiveAnimation.asset('assets/truck.riv'); - /// ``` - const RiveAnimation.asset( - String asset, { - this.artboard, - this.animations = const [], - this.stateMachines = const [], - this.fit, - this.alignment, - this.placeHolder, - this.antialiasing = true, - this.useArtboardSize = false, - this.clipRect, - this.controllers = const [], - this.onInit, - this.behavior = RiveHitTestBehavior.opaque, - this.objectGenerator, - this.speedMultiplier = 1, - this.isTouchScrollEnabled = false, - Key? key, - }) : name = asset, - file = null, - headers = null, - src = _Source.asset, - super(key: key); - - /// Creates a new [RiveAnimation] from a URL over HTTP - /// - /// *Example:* - /// ```dart - /// return RiveAnimation.network('https://cdn.rive.app/animations/vehicles.riv'); - /// ``` - const RiveAnimation.network( - String url, { - this.artboard, - this.animations = const [], - this.stateMachines = const [], - this.fit, - this.alignment, - this.placeHolder, - this.antialiasing = true, - this.useArtboardSize = false, - this.clipRect, - this.controllers = const [], - this.onInit, - this.headers, - this.behavior = RiveHitTestBehavior.opaque, - this.objectGenerator, - this.speedMultiplier = 1, - this.isTouchScrollEnabled = false, - Key? key, - }) : name = url, - file = null, - src = _Source.network, - super(key: key); - - /// Creates a new [RiveAnimation] from a local .riv file - /// - /// *Example:* - /// ```dart - /// return RiveAnimation.file('path/to/local/file.riv'); - /// ``` - const RiveAnimation.file( - String path, { - this.artboard, - this.animations = const [], - this.stateMachines = const [], - this.fit, - this.alignment, - this.placeHolder, - this.antialiasing = true, - this.useArtboardSize = false, - this.clipRect, - this.controllers = const [], - this.onInit, - this.behavior = RiveHitTestBehavior.opaque, - this.objectGenerator, - this.speedMultiplier = 1, - this.isTouchScrollEnabled = false, - Key? key, - }) : name = path, - file = null, - headers = null, - src = _Source.file, - super(key: key); - - /// Creates a new [RiveAnimation] from a direct [RiveFile] object - /// - /// *Example:* - /// ```dart - /// final riveFile = await RiveFile.asset('assets/truck.riv'); - /// ... - /// return RiveAnimation.direct(riveFile); - /// ``` - const RiveAnimation.direct( - RiveFile this.file, { - this.artboard, - this.animations = const [], - this.stateMachines = const [], - this.fit, - this.alignment, - this.placeHolder, - this.antialiasing = true, - this.useArtboardSize = false, - this.clipRect, - this.controllers = const [], - this.onInit, - this.speedMultiplier = 1, - this.isTouchScrollEnabled = false, - Key? key, - this.behavior = RiveHitTestBehavior.opaque, - }) : name = null, - headers = null, - objectGenerator = null, - src = _Source.direct, - super(key: key); - - @override - RiveAnimationState createState() => RiveAnimationState(); -} - -@visibleForTesting -class RiveAnimationState extends State { - /// Rive controller - final _controllers = []; - - /// Active artboard - Artboard? _artboard; - - /// Active Rive file loaded in memory. - RiveFile? _riveFile; - - @override - void initState() { - super.initState(); - _configure(); - } - - /// Loads [RiveFile] and calls [_init] - Future _configure() async { - if (!mounted) return; - - _init(await _loadRiveFile()); - } - - /// Loads the correct Rive file depending on [widget.src] - Future _loadRiveFile() { - switch (widget.src) { - case _Source.asset: - return RiveFile.asset( - widget.name!, - objectGenerator: widget.objectGenerator, - ); - case _Source.network: - return RiveFile.network( - widget.name!, - headers: widget.headers, - objectGenerator: widget.objectGenerator, - ); - case _Source.file: - return RiveFile.file( - widget.name!, - objectGenerator: widget.objectGenerator, - ); - case _Source.direct: - return Future.value( - widget.file!, - ); - } - } - - @override - void didUpdateWidget(covariant RiveAnimation oldWidget) { - super.didUpdateWidget(oldWidget); - - if (widget.name != oldWidget.name || - widget.file != oldWidget.file || - widget.src != oldWidget.src) { - _configure(); // Rife file has changed - } else if (_requiresInit(oldWidget)) { - if (_riveFile == null) { - _configure(); // Rife file not yet loaded - } else { - _init(_riveFile!); - } - } - } - - /// Determines if new parameters provided to the widget requires - /// re-initialization of the Rive artboard - bool _requiresInit(RiveAnimation oldWidget) => - widget.artboard != oldWidget.artboard || - !listEquals(widget.animations, oldWidget.animations) || - !listEquals(widget.controllers, oldWidget.controllers) || - !listEquals(widget.stateMachines, oldWidget.stateMachines); - - /// Initializes the artboard, animations, state machines and controllers - void _init(RiveFile file) { - _riveFile = file; - - if (!mounted) { - /// _init is usually called asynchronously, so this is a good time to - /// check if the widget is still mounted. If it's not we can get out of - /// here early. - return; - } - - // Clear current local controllers. - _controllers.forEach((c) { - c.dispose(); - }); - _controllers.clear(); - - final artboard = (widget.artboard != null - ? file.artboardByName(widget.artboard!) - : file.mainArtboard) - ?.instance(); - - if (artboard == null) { - throw const FormatException('Unable to load artboard'); - } - if (artboard.animations.isEmpty) { - throw FormatException('No animations in artboard ${artboard.name}'); - } - - // Create animations. If there are no animations, state machines, or - // controller specified, select a default animation - final animationNames = widget.animations.isEmpty && - widget.stateMachines.isEmpty && - widget.controllers.isEmpty && - widget.onInit == null - ? [artboard.animations.first.name] - : widget.animations; - - animationNames.forEach((name) => artboard - .addController((_controllers..add(SimpleAnimation(name))).last)); - - // Create state machines - final stateMachineNames = widget.stateMachines; - - stateMachineNames.forEach((name) { - final controller = StateMachineController.fromArtboard(artboard, name); - if (controller != null) { - artboard.addController((_controllers..add(controller)).last); - } - }); - - // Add any user-created controllers - widget.controllers.forEach(artboard.addController); - - setState(() => _artboard = artboard); - - // Call the onInit callback if provided - widget.onInit?.call(_artboard!); - } - - @override - void dispose() { - _controllers.forEach((c) => c.dispose()); - super.dispose(); - } - - bool get _shouldAddHitTesting => _artboard!.animationControllers.any( - (controller) => - controller is StateMachineController && - controller.hitComponents.isNotEmpty, - ); - - @override - Widget build(BuildContext context) => _artboard != null - ? Rive( - artboard: _artboard!, - fit: widget.fit ?? BoxFit.contain, - alignment: widget.alignment ?? Alignment.center, - antialiasing: widget.antialiasing, - useArtboardSize: widget.useArtboardSize, - clipRect: widget.clipRect, - enablePointerEvents: _shouldAddHitTesting, - behavior: widget.behavior, - speedMultiplier: widget.speedMultiplier, - isTouchScrollEnabled: widget.isTouchScrollEnabled, - ) - : widget.placeHolder ?? const SizedBox(); -} diff --git a/lib/src/widgets/rive_builder.dart b/lib/src/widgets/rive_builder.dart new file mode 100644 index 0000000..f93bb34 --- /dev/null +++ b/lib/src/widgets/rive_builder.dart @@ -0,0 +1,192 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; + +/// A function that builds a widget based on the state of the Rive file. +/// +/// - The [context] parameter is the context of the widget. +/// - The [state] parameter is the current state of the Rive file. +typedef RiveBuilder = Widget Function( + BuildContext context, + RiveState state, +); + +/// A function that builds a controller based on the Rive file. +/// +/// - The [file] parameter is the Rive file. +typedef Controller = RiveWidgetController Function(File file); + +/// A function that is called when the Rive state is loaded. +typedef RiveOnLoaded = void Function(RiveLoaded state); + +/// A function that is called when the Rive state failed to load. +typedef RiveOnFailed = void Function(Object error, StackTrace stackTrace); + +/// A widget that builds a Rive file. +/// +/// - The [fileLoader] parameter is the file loader. +/// - The [artboardSelector] parameter specifies which artboard to use +/// - The [stateMachineSelector] parameter specifies which state machine to use +/// - The [dataBind] parameter specifies which view model instance to bind to +/// - The [builder] parameter is the builder that builds the widget based on +/// the state of the Rive file and controller. +/// - The [controller] parameter is an optional function that builds a +/// controller based on the Rive file. Use this to manually create the +/// controller instead of using the default one. +class RiveWidgetBuilder extends StatefulWidget { + const RiveWidgetBuilder({ + super.key, + required this.fileLoader, + this.artboardSelector = const ArtboardDefault(), + this.stateMachineSelector = const StateMachineDefault(), + this.dataBind, + required this.builder, + this.controller, + this.onLoaded, + this.onFailed, + }); + + /// The file loader to load the Rive file. + final FileLoader fileLoader; + + /// The selector to specify which artboard to use. + final ArtboardSelector artboardSelector; + + /// The selector to specify which state machine to use. + final StateMachineSelector stateMachineSelector; + + /// The data bind to specify which view model instance to bind to. + final DataBind? dataBind; + + /// The builder to build the widget based on the state of the Rive file and + /// controller. + final RiveBuilder builder; + + /// An optional function to manually create the controller instead of using + /// the default one. + final Controller? controller; + + /// An optional function to call when the Rive state is loaded. + final RiveOnLoaded? onLoaded; + + /// An optional function to call when the Rive state failed to load. + final RiveOnFailed? onFailed; + + @override + State createState() => _RiveWidgetBuilderState(); +} + +class _RiveWidgetBuilderState extends State { + RiveState _state = RiveLoading(); + late File _file; + + @override + void initState() { + super.initState(); + _setup(withFileLoad: true); + } + + @override + void didUpdateWidget(RiveWidgetBuilder oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.fileLoader != oldWidget.fileLoader) { + _setup(withFileLoad: true); + } else if (widget.artboardSelector != oldWidget.artboardSelector || + widget.stateMachineSelector != oldWidget.stateMachineSelector || + widget.dataBind != oldWidget.dataBind) { + _setup(withFileLoad: false); + } + } + + Future _setup({required bool withFileLoad}) async { + try { + if (withFileLoad) { + _file = await widget.fileLoader.file(); + } + final controllerBuilder = widget.controller; + final controller = controllerBuilder != null + ? controllerBuilder(_file) + : RiveWidgetController( + _file, + artboardSelector: widget.artboardSelector, + stateMachineSelector: widget.stateMachineSelector, + ); + + final dataBind = widget.dataBind; + ViewModelInstance? vmi; + if (dataBind != null) { + vmi = controller.dataBind(dataBind); + } + + setState(() { + _state = RiveLoaded( + file: _file, + controller: controller, + viewModelInstance: vmi, + ); + }); + widget.onLoaded?.call(_state as RiveLoaded); + } on Exception catch (e, stackTrace) { + setState(() { + _state = RiveFailed(e, stackTrace); + }); + widget.onFailed?.call(e, stackTrace); + } + } + + @override + void dispose() { + switch (_state) { + case RiveLoaded state: + // Don't dispose the file because it's owned by the parent widget + state.controller.dispose(); + state.viewModelInstance?.dispose(); + case RiveLoading(): + case RiveFailed(): + // Nothing to dispose + break; + } + super.dispose(); + } + + @override + Widget build(BuildContext context) => widget.builder(context, _state); +} + +/// The state of the [RiveBuilder] widget. +/// +/// [RiveLoading] is the initial state. +/// +/// [RiveLoaded] is the state when the Rive file is loaded and the +/// controller is created. +/// +/// [RiveFailed] is the state when the Rive file, controller, or +/// view model instance fails to load. +sealed class RiveState {} + +/// The state when the Rive file is still loading. +class RiveLoading extends RiveState {} + +/// The state when the Rive file is loaded and the controller is created. +class RiveLoaded extends RiveState { + final File file; + final RiveWidgetController controller; + final ViewModelInstance? viewModelInstance; + + RiveLoaded({ + required this.file, + required this.controller, + required this.viewModelInstance, + }); +} + +/// The state when the Rive file, controller, or view model instance fails to +/// load. +class RiveFailed extends RiveState { + final Object error; + final StackTrace stackTrace; + + RiveFailed( + this.error, [ + this.stackTrace = StackTrace.empty, + ]); +} diff --git a/lib/src/widgets/rive_widget.dart b/lib/src/widgets/rive_widget.dart new file mode 100644 index 0000000..e797460 --- /dev/null +++ b/lib/src/widgets/rive_widget.dart @@ -0,0 +1,113 @@ +import 'package:flutter/material.dart'; +import 'package:rive/rive.dart'; + +/// A widget that displays a Rive artboard. +/// +/// - The [controller] parameter is the [RiveControlelr] that controls the +/// artboard and state machine. This controller builds on top of the concept +/// of a Rive painter, but provides a more convenient API for building +/// Rive widgets. +/// - The [fit] parameter is the fit of the artboard. +/// - The [alignment] parameter is the alignment of the artboard. +/// - The [hitTestBehavior] parameter is the hit test behavior of the artboard. +class RiveWidget extends StatefulWidget { + const RiveWidget({ + super.key, + required this.controller, + this.fit = RiveDefaults.fit, + this.alignment = RiveDefaults.alignment, + this.hitTestBehavior = RiveDefaults.hitTestBehaviour, + this.cursor = RiveDefaults.mouseCursor, + this.layoutScaleFactor = RiveDefaults.layoutScaleFactor, + }); + final RiveWidgetController controller; + + /// The fit of the artboard. + /// + /// Defaults to [RiveDefaults.fit]. + final Fit fit; + + /// The alignment of the artboard. + /// + /// Defaults to [RiveDefaults.alignment]. + final Alignment alignment; + + /// The hit test behavior of the artboard. + /// + /// Defaults to [RiveDefaults.hitTestBehaviour]. + final RiveHitTestBehavior hitTestBehavior; + + /// The cursor of the artboard. + /// + /// Defaults to [RiveDefaults.mouseCursor]. + final MouseCursor cursor; + + /// The layout scale factor of the artboard. + /// + /// Defaults to [RiveDefaults.layoutScaleFactor]. + final double layoutScaleFactor; + + @override + State createState() => _RiveWidgetState(); +} + +class _RiveWidgetState extends State { + @override + void initState() { + super.initState(); + _setupView(); + } + + void _setupView() { + final controller = widget.controller; + controller.alignment = widget.alignment; + controller.fit = widget.fit; + controller.hitTestBehavior = widget.hitTestBehavior; + controller.cursor = widget.cursor; + controller.layoutScaleFactor = widget.layoutScaleFactor; + } + + @override + void didUpdateWidget(covariant RiveWidget oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.controller != oldWidget.controller) { + // If the controller changes, we need to re-setup all the properties + _setupView(); + return; + } + + // Else we only update the properties that have changed. + final controller = widget.controller; + if (widget.alignment != oldWidget.alignment) { + controller.alignment = widget.alignment; + } + if (widget.fit != oldWidget.fit) { + controller.fit = widget.fit; + } + if (widget.hitTestBehavior != oldWidget.hitTestBehavior) { + controller.hitTestBehavior = widget.hitTestBehavior; + } + if (widget.cursor != oldWidget.cursor) { + controller.cursor = widget.cursor; + } + if (widget.layoutScaleFactor != oldWidget.layoutScaleFactor) { + controller.layoutScaleFactor = widget.layoutScaleFactor; + } + + // TODO (Gordon): Can optimize this out once we poll for changes. + // At the moment, we give force a repaint the ensure Rive is updated + // under the condition that the user is rebuilding the widget (calling + // setState). + controller.scheduleRepaint(); + } + + @override + Widget build(BuildContext context) { + return RiveArtboardWidget( + key: widget.key, + artboard: widget.controller.artboard, + painter: widget.controller, + ); + } +} diff --git a/platform_considerations.md b/platform_considerations.md index e0e79c7..43b880c 100644 --- a/platform_considerations.md +++ b/platform_considerations.md @@ -5,10 +5,10 @@ In order to support some of our more low level features, Rive brings some of its | Platform | Technology | Dependencies | | -------- | ---------- | -------------------------------- | | iOS | FFI | statically linked | -| Android | FFI | `rive_text.so` | -| Windows | FFI | `rive_plugin.dll` | +| Android | FFI | `rive_native.so` | +| Windows | FFI | `rive_native.dll` | | Mac | FFI | statically linked | -| Web | WASM | `rive_text.js`, `rive_text.wasm` | +| Web | WASM | `rive_native.js`, `rive_native.wasm` | ## iOS & Mac @@ -20,7 +20,7 @@ We use Gradle & CMake to build `rive_text.so`. Rive's runtime uses modern featur ```gradle android { - compileSdkVersion 31 + compileSdkVersion 35 ndkVersion "27.2.12479018" ... } diff --git a/pubspec.yaml b/pubspec.yaml index df07780..7d10c61 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,29 +1,28 @@ name: rive -version: 0.13.20 +version: 0.14.0-dev.1 homepage: https://rive.app -description: Rive Flutter Runtime. This package provides runtime functionality for playing back and interacting with animations built with the Rive editor available at https://rive.app. +description: Rive Flutter Runtime. This package provides runtime functionality for Rive graphics built with the Rive editor available at https://rive.app. repository: https://github.com/rive-app/rive-flutter topics: - animation - ui - effects - - widgets - - widget + - design + - games + environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=2.5.0" + sdk: ">=3.5.0 <4.0.0" + flutter: ">=3.3.0" + dependencies: - collection: ^1.15.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - http: ">=0.13.3 <2.0.0" - meta: ^1.3.0 - plugin_platform_interface: ^2.0.2 - rive_common: 0.4.15 + rive_native: + path: ../rive_native + dev_dependencies: flutter_test: sdk: flutter - mocktail: - path: ^1.8.3 \ No newline at end of file + flutter_lints: ^5.0.0 diff --git a/shared_lib/build_shared.sh b/shared_lib/build_shared.sh deleted file mode 100755 index 3a5d527..0000000 --- a/shared_lib/build_shared.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -set -e - -CONFIG=debug -SINGLE= -for var in "$@"; do - if [[ $var = "release" ]]; then - CONFIG=release - fi -done - -unameOut="$(uname -s)" -case "${unameOut}" in -Linux*) MACHINE=linux ;; -Darwin*) MACHINE=mac ;; -CYGWIN*) MACHINE=cygwin ;; -MINGW*) MACHINE=mingw ;; -*) MACHINE="UNKNOWN:${unameOut}" ;; -esac - -pushd ../ -./update_dependencies.sh -popd - -if [[ ! -f "bin/premake5" ]]; then - mkdir -p bin - pushd bin - echo Downloading Premake5 - if [ "$MACHINE" = 'mac' ]; then - PREMAKE_URL=https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-macosx.tar.gz - else - PREMAKE_URL=https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-linux.tar.gz - fi - curl $PREMAKE_URL -L -o premake.tar.gz - # Export premake5 into bin - tar -xvf premake.tar.gz 2>/dev/null - # Delete downloaded archive - rm premake.tar.gz - popd -fi - -export PREMAKE=bin/premake5 - -$PREMAKE --scripts=../macos/rive-cpp/build --file=../premake5_rive_plugin.lua gmake2 --arch=x86_64 - -cd .. -for var in "$@"; do - if [[ $var = "clean" ]]; then - make clean - make config=release clean - fi -done - -make config=$CONFIG -j$(($(sysctl -n hw.physicalcpu) + 1)) -if [ "$MACHINE" = 'mac' ]; then - du -hs shared_lib/build/bin/debug/librive_text.dylib -else - du -hs shared_lib/build/bin/debug/librive_text.so -fi diff --git a/test/artboard_test.dart b/test/artboard_test.dart index 7b8e942..7b29363 100644 --- a/test/artboard_test.dart +++ b/test/artboard_test.dart @@ -1,51 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; void main() { - late RiveFile riveFile; + setUp(() {}); - setUp(() { - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - riveFile = RiveFile.import(riveBytes); - }); - - test('Artboards can be read from files', () { - expect(riveFile.mainArtboard.name, 'Artboard 1'); - expect(riveFile.artboards.length, 2); - expect(riveFile.artboardByName('Artboard 2'), isNotNull); - }); - - test('Animations can be read from artboards', () { - final artboard = riveFile.mainArtboard; - expect(artboard.animations.length, 3); - expect(artboard.animations.first.name, 'Animation 1'); - expect(artboard.animations[1].name, 'Animation 2'); - expect(artboard.animations.last.name, 'State Machine 1'); - }); - - test('Animations can be read by name from artboards', () { - final artboard = riveFile.mainArtboard; - expect(artboard.animationByName('Animation 1'), isNotNull); - expect(artboard.animationByName('Animation 2'), isNotNull); - expect(artboard.animationByName('Does Not Exist'), isNull); - expect(artboard.animationByName('Animation 1') is LinearAnimationInstance, - true); - }); - - test('Linear animations can be retreived ffrom artboards', () { - final artboard = riveFile.mainArtboard; - expect(artboard.linearAnimations.toList().length, 2); - expect(artboard.stateMachines.toList().length, 1); - }); - - test('Pausing/Playing an artboard', () { - final artboard = riveFile.mainArtboard.instance(); - expect(artboard.isPlaying, true, reason: "Should be true by default"); - artboard.pause(); - expect(artboard.isPlaying, false, reason: "Should be false after pause"); - artboard.play(); - expect(artboard.isPlaying, true, reason: "Should be true after play"); - }); + test('Artboards can be read from files', () {}); } diff --git a/test/asset_gc_test.dart b/test/asset_gc_test.dart deleted file mode 100644 index 4fc8cc8..0000000 --- a/test/asset_gc_test.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -const assetName = 'CleanShot 2023-06-08 at 08.51.19@2x.png'; - -void main() { - group("Test asset referencer behaviour.", () { - test('Load a rive file, gets you one referencer.', () async { - final riveBytes = loadFile('assets/sample_image.riv'); - final riveFile = RiveFile.import( - riveBytes, - ); - - expect(riveFile.artboards.length, 1); - final image = riveFile.artboards.first.component(assetName); - - final asset = image!.asset; - - expect(asset!.fileAssetReferencers.length, 1); - }); - - test('Make some artboard instances gets additional referencers.', () async { - final riveBytes = loadFile('assets/sample_image.riv'); - final riveFile = RiveFile.import( - riveBytes, - ); - - // each artboard adds file asset referencer. - riveFile.artboards.first.instance(); - riveFile.artboards.first.instance(); - - final image = riveFile.artboards.first.component(assetName); - final asset = image!.asset!; - expect(asset.fileAssetReferencers.length, 3); - }); - - test( - 'If we let instance get garbage collected they will get cleaned up.', - () async { - final riveBytes = loadFile('assets/sample_image.riv'); - final riveFile = RiveFile.import( - riveBytes, - ); - - // each artboard adds file asset referencer. - var count = 19; - while (count-- > 0) { - riveFile.artboards.first.instance(); - } - - final image = riveFile.artboards.first.component(assetName); - final asset = image!.asset!; - expect(asset.fileAssetReferencers.length, 20); - await Future.delayed(const Duration(milliseconds: 100)); - // ok, kinda lame, but the above allows garbage collection to kick in - // which will remove referencers, its not really deterministic though - - expect( - asset.fileAssetReferencers.length < 5, - true, - reason: "Expected ${asset.fileAssetReferencers.length} < 5", - ); - }, - // skipping because it does not work, you can see things get - // finalized but this does not consistently happen in tests. - skip: true, - ); - }); -} diff --git a/test/asset_test.dart b/test/asset_test.dart deleted file mode 100644 index 3a94721..0000000 --- a/test/asset_test.dart +++ /dev/null @@ -1,274 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -import 'dart:async'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rive/rive.dart'; - -import 'mocks/mocks.dart'; -import 'src/network.dart'; -import 'src/utils.dart'; - -const assetName = 'CleanShot 2023-06-08 at 08.51.19@2x.png'; - -class MockAssetBundle extends Mock implements AssetBundle {} - -void main() { - setUpAll(() { - registerFallbackValue(ArtboardFake()); - registerFallbackValue(Uri()); - registerFallbackValue(Stream.value([])); - }); - group("Test loading rive file with embedded asset.", () { - test('Default load does not hit any url', () async { - final mockHttpClient = getMockHttpClient(); - - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/sample_image.riv'); - RiveFile.import( - riveBytes, - ); - }, createHttpClient: (_) => mockHttpClient); - - verifyNever(() => mockHttpClient.openUrl(any(), any())); - }); - - test('Disabling cdn also does not hit a url', () async { - final mockHttpClient = getMockHttpClient(); - - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/sample_image.riv'); - runZonedGuarded(() { - RiveFile.import( - riveBytes, - loadCdnAssets: false, - ); - }, (error, stack) { - // importing assets throws rn when we do not end up loading assets.. - // could suppress this too.. - // could ignore them & info log our load attempts. - - // could have a future people can await to get any issues - // could have a future people can await to get logs... - }); - }, createHttpClient: (_) => mockHttpClient); - - // network disabled - verifyNever(() => mockHttpClient.openUrl(any(), any())); - // by default we try to check for assets - }); - - test('test importing rive file, make sure we get a good callback', - () async { - // lets just return an image - final riveBytes = loadFile('assets/sample_image.riv'); - final imageBytes = loadFile('assets/file.png'); - final assets = []; - final byteList = []; - RiveFile.import(riveBytes, assetLoader: CallbackAssetLoader( - (asset, bytes) async { - assets.add(asset); - byteList.add(bytes); - await asset.decode(Uint8List.sublistView( - imageBytes, - )); - return true; - }, - )); - - final asset = assets.first; - - expect(asset is ImageAsset, true); - final fileAsset = asset as ImageAsset; - expect(fileAsset.extension, Extension.png); - expect(fileAsset.type, Type.image); - expect(fileAsset.name, assetName); - expect(fileAsset.assetId, 42981); - - expect(fileAsset.id, -1); - - expect(byteList.first.length, 202385); - }); - - test('test we load embedded assets if loaders are not provided', () async { - // lets just return an image - final riveBytes = loadFile('assets/sample_image.riv'); - - final assets = []; - RiveFile.import(riveBytes, assetLoader: CallbackAssetLoader( - (asset, bytes) async { - assets.add(asset); - return false; - }, - )); - - final asset = assets.first; - - expect(asset is ImageAsset, true); - final fileAsset = asset as ImageAsset; - expect(fileAsset.extension, Extension.png); - expect(fileAsset.type, Type.image); - expect(fileAsset.name, assetName); - expect(fileAsset.assetId, 42981); - // file asset will not be loaded - expect(fileAsset.image, null); - - expect(fileAsset.id, -1); - await Future.delayed(const Duration(milliseconds: 100)); - expect(fileAsset.image != null, true); - }); - - test('Make sure the image gets the dimensions once the image is loaded', - () async { - // lets just return an image - final riveBytes = loadFile('assets/sample_image.riv'); - final imageBytes = loadFile('assets/file.png'); - final completer = Completer(); - - final file = RiveFile.import( - riveBytes, - assetLoader: CallbackAssetLoader( - (asset, bytes) async { - await asset.decode(Uint8List.sublistView( - imageBytes, - )); - completer.complete(null); - return true; - }, - ), - ); - final image = file.artboards.first - .component("CleanShot 2023-06-08 at 08.51.19@2x.png"); - print(image); - - expect(image.width, 2444); - expect(image.height, 1634); - await completer.future; - expect(image.width, 256); - expect(image.height, 331); - }); - }); - group("Test loading rive file with cdn asset.", () { - late MockHttpClient mockHttpClient; - setUp(() { - mockHttpClient = getMockHttpClient(); - final imageBytes = loadFile('assets/file.png'); - prepMockRequest(mockHttpClient, Uint8List.sublistView(imageBytes)); - }); - - test('Default load will his the cdn', () async { - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/cdn_image.riv'); - RiveFile.import( - riveBytes, - ); - }, createHttpClient: (_) => mockHttpClient); - - verify(() => mockHttpClient.openUrl( - any(), - // ok, hardcoded for the cdn_image.riv file. - Uri.parse( - 'https://public.rive.app/cdn/uuid/b86dc1e6-35f7-4490-96fc-89ebdf848473'), - )).called(1); - }); - - test('Disabling cdn will mean no url hit', () async { - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/cdn_image.riv'); - - RiveFile.import( - riveBytes, - loadCdnAssets: false, - ); - }, createHttpClient: (_) => mockHttpClient); - - // network disabled - verifyNever(() => mockHttpClient.openUrl(any(), any())); - // by default we try to check for assets - }); - test( - 'If we provide a callback, we are hit first, and success means ' - 'no cdn hit', () async { - // lets just return an image - final imageBytes = loadFile('assets/file.png'); - final parameters = []; - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/cdn_image.riv'); - RiveFile.import(riveBytes, assetLoader: CallbackAssetLoader( - (asset, bytes) async { - parameters.add(asset); - await asset.decode(Uint8List.sublistView( - imageBytes, - )); - return true; - }, - )); - }, createHttpClient: (_) => mockHttpClient); - - final asset = parameters.first; - - expect(asset is ImageAsset, true); - verifyNever(() => mockHttpClient.openUrl(any(), any())); - }); - - test( - 'If we provide a callback, we are hit first, a failure means we ' - 'hit cdn', () async { - // lets just return an image - final parameters = []; - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/cdn_image.riv'); - - RiveFile.import(riveBytes, assetLoader: CallbackAssetLoader( - (asset, bytes) async { - parameters.add(asset); - return false; - }, - )); - }, createHttpClient: (_) => mockHttpClient); - - final asset = parameters.first; - - expect(asset is ImageAsset, true); - verify(() => mockHttpClient.openUrl(any(), any())).called(1); - }); - - testWidgets('Loading hosted assets will default to rives public cdn', - (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/image_asset_prod.riv'); - RiveFile.import( - riveBytes, - ); - }, createHttpClient: (_) => mockHttpClient); - - verify(() => mockHttpClient.openUrl( - any(), - // ok, hardcoded for the cdn_image.riv file. - Uri.parse( - 'https://public.rive.app/cdn/uuid/69a03ce3-83f0-4fcb-94a5-0d401b8c030e'), - )).called(1); - }); - - testWidgets('Loading hosted assets can have custom cdns set', - (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - final riveBytes = loadFile('assets/image_asset_uat.riv'); - RiveFile.import( - riveBytes, - ); - }, createHttpClient: (_) => mockHttpClient); - - verify(() => mockHttpClient.openUrl( - any(), - // ok, hardcoded for the cdn_image.riv file. - Uri.parse( - 'https://public.uat.rive.app/cdn/uuid/69a03ce3-83f0-4fcb-94a5-0d401b8c030e'), - )).called(1); - }); - }); -} diff --git a/test/assets/batch_rivs/circle-fui.riv b/test/assets/batch_rivs/circle-fui.riv deleted file mode 100644 index 5070807..0000000 --- a/test/assets/batch_rivs/circle-fui.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:249baa6c8e69991c3d563e01942fa8e14d586f5325af81d7bbf2fae86de2a630 -size 286936 diff --git a/test/assets/batch_rivs/danger-quarantine.riv b/test/assets/batch_rivs/danger-quarantine.riv deleted file mode 100644 index 6459e95..0000000 --- a/test/assets/batch_rivs/danger-quarantine.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5aa95fe11dad1d78882d1537a61e175d8a1777efcb06b62310818aa203d4c177 -size 18519 diff --git a/test/assets/batch_rivs/fire-skull.riv b/test/assets/batch_rivs/fire-skull.riv deleted file mode 100644 index 13f23fb..0000000 --- a/test/assets/batch_rivs/fire-skull.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:560d6f4bdf39b83196fd49e4e8a1825b05279a83801cba80384640e1e1a6427a -size 10715 diff --git a/test/assets/batch_rivs/joystick-demos-fish.riv b/test/assets/batch_rivs/joystick-demos-fish.riv deleted file mode 100644 index b2f96f3..0000000 --- a/test/assets/batch_rivs/joystick-demos-fish.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:72ddd483375fa9f38d47b765b9a4b3a3c4ea1568f175dce13c5cf0a95ef31bbe -size 7248 diff --git a/test/assets/batch_rivs/polito.riv b/test/assets/batch_rivs/polito.riv deleted file mode 100644 index ecfbd89..0000000 --- a/test/assets/batch_rivs/polito.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:76e792dac0d5900841d0ed4112882725923173ea085bfe0471c74f9fdbf9f414 -size 7709 diff --git a/test/assets/cdn_image.riv b/test/assets/cdn_image.riv deleted file mode 100644 index 5b390ac..0000000 --- a/test/assets/cdn_image.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8d93c5ca67c938ae4738342ec1b046f09c22a547167ffe7570bf0d899178fba5 -size 206 diff --git a/test/assets/component_discovery.riv b/test/assets/component_discovery.riv deleted file mode 100644 index 67c978f..0000000 --- a/test/assets/component_discovery.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d09c9d88024d7944c231e4d8b6509040fa7d68219c06ba0730fed077834f8eeb -size 806088 diff --git a/test/assets/electrified_button_simple.riv b/test/assets/electrified_button_simple.riv deleted file mode 100644 index ab8316c..0000000 --- a/test/assets/electrified_button_simple.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:72ac13f7988750df3ad741c46be22d4b9a697a8c369cd6d851cd694f0b629929 -size 820926 diff --git a/test/assets/event_on_listener.riv b/test/assets/event_on_listener.riv deleted file mode 100644 index 9eba920..0000000 --- a/test/assets/event_on_listener.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:011407faa0f4eba9576556c4733e524d8989bc489d75ff35afba31ff88fc3598 -size 429 diff --git a/test/assets/events_from_trigger_test.riv b/test/assets/events_from_trigger_test.riv deleted file mode 100644 index dcba3b2..0000000 --- a/test/assets/events_from_trigger_test.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43496fca427b3da9640dbb646fe20a6982fdb14586ffd777ccd2f5395aa8b78a -size 415 diff --git a/test/assets/events_on_states.riv b/test/assets/events_on_states.riv deleted file mode 100644 index 8e66032..0000000 --- a/test/assets/events_on_states.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6f360a9ba8e224871161a4945d24959c75fba97d9ca81f33be0f73252c31b3c4 -size 486 diff --git a/test/assets/file.png b/test/assets/file.png deleted file mode 100644 index 8a98dfa..0000000 --- a/test/assets/file.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24229c70fc2c0487df97ee0deb7b5c80446a0aaaac11ba9268c2d814894f8adb -size 159880 diff --git a/test/assets/follow_path_path.riv b/test/assets/follow_path_path.riv deleted file mode 100644 index bb9eb85..0000000 --- a/test/assets/follow_path_path.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54020ef6a20855612b904334a59c4f65649f77215aa062c9d0c5618f3ddca5d6 -size 818701 diff --git a/test/assets/follow_path_shapes.riv b/test/assets/follow_path_shapes.riv deleted file mode 100644 index 626e303..0000000 --- a/test/assets/follow_path_shapes.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d2eea5391be368871ba71c5b6cf9b8b8a20fe3ac00f98a473c552e08208493c -size 2750 diff --git a/test/assets/follow_path_solos.riv b/test/assets/follow_path_solos.riv deleted file mode 100644 index dbb2bd7..0000000 --- a/test/assets/follow_path_solos.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89e77e51b507430adb94340455a2b7bd4da40aef55f1ee9568603f50ea09963f -size 287 diff --git a/test/assets/hit_test_consume.riv b/test/assets/hit_test_consume.riv deleted file mode 100644 index e4207bd..0000000 --- a/test/assets/hit_test_consume.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a170d016dde9426d0ba45626de1879c2424a0dbc887fa65513a274b9e7d3cf9a -size 202 diff --git a/test/assets/hit_test_pass_through.riv b/test/assets/hit_test_pass_through.riv deleted file mode 100644 index 6ba0c83..0000000 --- a/test/assets/hit_test_pass_through.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b96d1eb4564c2a0fe4d3dde81154317c10e92bd07a1c93c7e35a5cd3996f1ec -size 121 diff --git a/test/assets/image_asset_prod.riv b/test/assets/image_asset_prod.riv deleted file mode 100644 index 0693a0b..0000000 --- a/test/assets/image_asset_prod.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4a4b3c5a134fab30ec82efad6353c7b04062f35ddafa9777526ce59d12b421f6 -size 240 diff --git a/test/assets/image_asset_uat.riv b/test/assets/image_asset_uat.riv deleted file mode 100644 index 22b7bfa..0000000 --- a/test/assets/image_asset_uat.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:63059240dc7db95ff65c1d349ba09396934c9d57a24bfe4092e282d0f4f7cebc -size 281 diff --git a/test/assets/joystick_handle_source.riv b/test/assets/joystick_handle_source.riv deleted file mode 100644 index c23997b..0000000 --- a/test/assets/joystick_handle_source.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc047f6e53f6f3c0a7d044a61faf9d15792c4cfedb14dc9f8f39307f7e29a7f9 -size 602 diff --git a/test/assets/off_road_car.riv b/test/assets/off_road_car.riv deleted file mode 100644 index 6f40ca9..0000000 --- a/test/assets/off_road_car.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2cf7f74416ebc7c1016dd6801d38ea6e80cd936fead3d7b6240a34110fda960 -size 34921 diff --git a/test/assets/rive-flutter-test-asset.riv b/test/assets/rive-flutter-test-asset.riv deleted file mode 100644 index 3cf7110..0000000 --- a/test/assets/rive-flutter-test-asset.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df1b7d04a10f1c5d402497c88f44a30ab5dd19ca4a110cfe4d7103ea97bd8353 -size 264 diff --git a/test/assets/runtime_nested_inputs.riv b/test/assets/runtime_nested_inputs.riv deleted file mode 100644 index 9c14831..0000000 --- a/test/assets/runtime_nested_inputs.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61a14d72c5b9694b675d729e756fd4e3d0a075bf76ed545d07b62c301af962a0 -size 947 diff --git a/test/assets/sample_image.riv b/test/assets/sample_image.riv deleted file mode 100644 index ecb5bd2..0000000 --- a/test/assets/sample_image.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:321771e476c91cdf145c0cbb39432b7e2debe1eb17fe6da80eb8ddb1684ad830 -size 202647 diff --git a/test/assets/skins_demo.riv b/test/assets/skins_demo.riv deleted file mode 100644 index b814e65..0000000 --- a/test/assets/skins_demo.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7b9bc316e5db9056ff6713ecedd07b304d9e19da9b8310b68369b92711946b2 -size 19672 diff --git a/test/assets/spilled_time.riv b/test/assets/spilled_time.riv deleted file mode 100644 index 59fb019..0000000 --- a/test/assets/spilled_time.riv +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86831a723012b7d779ce1cb7695dc7b87dfe0780bfbf5df24ddf332cf6155f11 -size 367 diff --git a/test/component_find_test.dart b/test/component_find_test.dart deleted file mode 100644 index 558eee1..0000000 --- a/test/component_find_test.dart +++ /dev/null @@ -1,76 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -class MockAssetBundle extends Mock implements AssetBundle {} - -void main() { - setUpAll(() {}); - group("Test finding components on artboard", () { - test('Find a component of a specific type with a specific name.', () async { - final riveBytes = loadFile('assets/component_discovery.riv'); - final riveFile = RiveFile.import(riveBytes); - final artboard = riveFile.mainArtboard.instance(); - - final nestedArtboard = - artboard.component("NestedArtboardFindMe"); - expect(nestedArtboard, isNotNull); - expect(nestedArtboard!.name, "NestedArtboardFindMe"); - - final textRun = artboard.component("TextRunFindMe"); - expect(textRun, isNotNull); - expect(textRun!.name, "TextRunFindMe"); - - final shapeEllipse = artboard.component("EllipseFindMe"); - expect(shapeEllipse, isNotNull); - expect(shapeEllipse!.name, "EllipseFindMe"); - - final shapeRectangle = artboard.component("RectangleFindMe"); - expect(shapeRectangle, isNotNull); - expect(shapeRectangle!.name, "RectangleFindMe"); - - final notFoundComponent = artboard.component("DoesNotExist"); - expect(notFoundComponent, isNull); - }); - - test('Get a component that matches the given predicate', () async { - final riveBytes = loadFile('assets/component_discovery.riv'); - final riveFile = RiveFile.import(riveBytes); - final artboard = riveFile.mainArtboard.instance(); - - final nestedArtboard = - artboard.getComponentWhereOrNull( - (component) => component.name.startsWith("NestedArtboard")); - - expect(nestedArtboard, isNotNull); - expect(nestedArtboard!.name, "NestedArtboardFindMe"); - - final textRun = artboard.getComponentWhereOrNull( - (component) => component.name.startsWith("TextRun")); - - expect(textRun, isNotNull); - expect(textRun!.name, "TextRunFindMe"); - - final shapeEllipse = artboard.getComponentWhereOrNull( - (component) => component.name.startsWith("Ellipse")); - - expect(shapeEllipse, isNotNull); - expect(shapeEllipse!.name, "EllipseFindMe"); - - final shapeRectangle = artboard.getComponentWhereOrNull( - (component) => component.name.startsWith("Rectangle")); - - expect(shapeRectangle, isNotNull); - expect(shapeRectangle!.name, "RectangleFindMe"); - - final notFoundComponent = artboard.getComponentWhereOrNull( - (component) => component.name.startsWith("DoesNotExist")); - expect(notFoundComponent, isNull); - }); - }); -} diff --git a/test/goldens/batch_tests/golden_batch_test.dart b/test/goldens/batch_tests/golden_batch_test.dart deleted file mode 100644 index feb803c..0000000 --- a/test/goldens/batch_tests/golden_batch_test.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - /// Tests all rivs in the `test/assets/batch_rive` directory - group('Golden - Batch tests riv files', () { - List riveFiles = []; - - setUpAll(() { - // Read all files in the batch directory to be tested. - riveFiles = batchRiveFilesToTest(); - }); - - testWidgets('Animation default state machine render as expected', - (WidgetTester tester) async { - for (final file in riveFiles) { - final riveFile = - RiveFile.import(ByteData.sublistView(file.file.readAsBytesSync())); - final fileName = file.fileName; - late Artboard artboard; - - // TODO: change this once the default behavior is to play - // the default state machine. Adding this for now as it ensures we - // do not have to update tests when the default behavior changes. - final defaultStateMachineName = - riveFile.mainArtboard.defaultStateMachine?.name ?? - riveFile.mainArtboard.stateMachines.first.name; - - await tester.pumpWidget( - RiveAnimation.direct( - riveFile, - stateMachines: [defaultStateMachineName], - onInit: (a) { - artboard = a; - }, - ), - ); - - // Render first frame of animation - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - '$fileName-01.png', - reason: 'Animation with filename: $fileName should render correctly', - ); - - // Advance animation by a three quarters of a second - artboard.advance(0.75, nested: true); - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - '$fileName-02.png', - reason: 'Animation with filename: $fileName should render correctly', - ); - - // Advance animation by a two seconds - artboard.advance(2, nested: true); - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - '$fileName-03.png', - reason: 'Animation with filename: $fileName should render correctly', - ); - } - }); - }); -} diff --git a/test/goldens/batch_tests/images/circle-fui.riv-01.png b/test/goldens/batch_tests/images/circle-fui.riv-01.png deleted file mode 100644 index 23aab8a..0000000 --- a/test/goldens/batch_tests/images/circle-fui.riv-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:852a99c18941c61d80e56858f42c8d8675f8baf22a0207483b23a5b8924a97b5 -size 361506 diff --git a/test/goldens/batch_tests/images/circle-fui.riv-02.png b/test/goldens/batch_tests/images/circle-fui.riv-02.png deleted file mode 100644 index 918d323..0000000 --- a/test/goldens/batch_tests/images/circle-fui.riv-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04fecfd9229642c791421e274729266dc1c6583d984a5fe3b3b391a6a1601c9a -size 362826 diff --git a/test/goldens/batch_tests/images/circle-fui.riv-03.png b/test/goldens/batch_tests/images/circle-fui.riv-03.png deleted file mode 100644 index ebde549..0000000 --- a/test/goldens/batch_tests/images/circle-fui.riv-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f44a79f5df1a626f85470853b66a105bb60e953f94dfbeca7b3413e674006b84 -size 365185 diff --git a/test/goldens/batch_tests/images/danger-quarantine.riv-01.png b/test/goldens/batch_tests/images/danger-quarantine.riv-01.png deleted file mode 100644 index 17a9f24..0000000 --- a/test/goldens/batch_tests/images/danger-quarantine.riv-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5171752505766020ba4ce60415442178f2a5d8346f6400d3c0dd91fa2d83deb8 -size 81618 diff --git a/test/goldens/batch_tests/images/danger-quarantine.riv-02.png b/test/goldens/batch_tests/images/danger-quarantine.riv-02.png deleted file mode 100644 index 0ff9f6a..0000000 --- a/test/goldens/batch_tests/images/danger-quarantine.riv-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb9973c589844248c533c3105002ec81fa31da0868f58a2091251588fe1c3c96 -size 83146 diff --git a/test/goldens/batch_tests/images/danger-quarantine.riv-03.png b/test/goldens/batch_tests/images/danger-quarantine.riv-03.png deleted file mode 100644 index a7d6b18..0000000 --- a/test/goldens/batch_tests/images/danger-quarantine.riv-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a56009a140acbbed25e77762b42ec7c8ad5a8f2439b339cc60a2382986ff17cf -size 78347 diff --git a/test/goldens/batch_tests/images/fire-skull.riv-01.png b/test/goldens/batch_tests/images/fire-skull.riv-01.png deleted file mode 100644 index 301a198..0000000 --- a/test/goldens/batch_tests/images/fire-skull.riv-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3971fbaf5a4bac3c2574688a0fb0f185d5afa1febf25467c7f15a650af163989 -size 64959 diff --git a/test/goldens/batch_tests/images/fire-skull.riv-02.png b/test/goldens/batch_tests/images/fire-skull.riv-02.png deleted file mode 100644 index 5f079da..0000000 --- a/test/goldens/batch_tests/images/fire-skull.riv-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c944f27011f53f75267dfe0f3dcb5eba6fdb65beb330f8cde30beec1e92d2b2a -size 65900 diff --git a/test/goldens/batch_tests/images/fire-skull.riv-03.png b/test/goldens/batch_tests/images/fire-skull.riv-03.png deleted file mode 100644 index 2a6b231..0000000 --- a/test/goldens/batch_tests/images/fire-skull.riv-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b422ee1ec995f3edce424889ab1049aad21a6fc35ae727aeb7126fac25e93169 -size 65212 diff --git a/test/goldens/batch_tests/images/joystick-demos-fish.riv-01.png b/test/goldens/batch_tests/images/joystick-demos-fish.riv-01.png deleted file mode 100644 index ad1a83b..0000000 --- a/test/goldens/batch_tests/images/joystick-demos-fish.riv-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:16b2f488a493a008cd3c36a5069d8060a2c1bc75b1b07da8bb10c0a17d5b3b8e -size 33598 diff --git a/test/goldens/batch_tests/images/joystick-demos-fish.riv-02.png b/test/goldens/batch_tests/images/joystick-demos-fish.riv-02.png deleted file mode 100644 index 4c798de..0000000 --- a/test/goldens/batch_tests/images/joystick-demos-fish.riv-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a90e4121263df29b7d054a27246e22d89a2b4c4c169a31deabec44fb4d580f2e -size 37772 diff --git a/test/goldens/batch_tests/images/joystick-demos-fish.riv-03.png b/test/goldens/batch_tests/images/joystick-demos-fish.riv-03.png deleted file mode 100644 index 672e28f..0000000 --- a/test/goldens/batch_tests/images/joystick-demos-fish.riv-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb9941546879d69f03628c2b5a5fa28c26bb8902653910d7e43fea4699c50e6b -size 39343 diff --git a/test/goldens/batch_tests/images/polito.riv-01.png b/test/goldens/batch_tests/images/polito.riv-01.png deleted file mode 100644 index 937a546..0000000 --- a/test/goldens/batch_tests/images/polito.riv-01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f87a6833528f59a06a7c94479c39d85dfc0816a9ad896c53f9ee9c73f643072 -size 68499 diff --git a/test/goldens/batch_tests/images/polito.riv-02.png b/test/goldens/batch_tests/images/polito.riv-02.png deleted file mode 100644 index 2d0545a..0000000 --- a/test/goldens/batch_tests/images/polito.riv-02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f1f43ec135be96620d47b1a458b7bcbdd35ef3694cd023fa40d7389fa7436b81 -size 61843 diff --git a/test/goldens/batch_tests/images/polito.riv-03.png b/test/goldens/batch_tests/images/polito.riv-03.png deleted file mode 100644 index 1acf7fd..0000000 --- a/test/goldens/batch_tests/images/polito.riv-03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e69d34a5943e5ba0967068314114430bf74b5b0be58ae5313deaf71e8078fb53 -size 71791 diff --git a/test/goldens/follow_path/golden_follow_path_solos_test.dart b/test/goldens/follow_path/golden_follow_path_solos_test.dart deleted file mode 100644 index 1c1b3df..0000000 --- a/test/goldens/follow_path/golden_follow_path_solos_test.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - follow path solo tests', () { - testWidgets('Follow path over time', (WidgetTester tester) async { - final riveBytes = loadFile('assets/follow_path_solos.riv'); - final file = RiveFile.import(riveBytes); - late Artboard artboard; - - final widget = RiveAnimation.direct( - file, - stateMachines: const ['State Machine 1'], - onInit: (a) { - artboard = a; - }, - ); - await tester.pumpWidget(widget); - - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_solos_01.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(1.0, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_solos_02.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(1.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_solos_03.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(1.0, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_solos_04.png', - reason: 'Follow path should work as animation advances', - ); - }); - }); -} diff --git a/test/goldens/follow_path/golden_follow_path_test.dart b/test/goldens/follow_path/golden_follow_path_test.dart deleted file mode 100644 index df3d620..0000000 --- a/test/goldens/follow_path/golden_follow_path_test.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - follow path tests', () { - testWidgets('Follow path - shape over time', (WidgetTester tester) async { - final riveBytes = loadFile('assets/follow_path_shapes.riv'); - final file = RiveFile.import(riveBytes); - late Artboard artboard; - - final widget = RiveAnimation.direct( - file, - stateMachines: const ['State Machine 1'], - onInit: (a) { - artboard = a; - }, - ); - await tester.pumpWidget(widget); - - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_over_time_01.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(0.1, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_over_time_02.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(0.1, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_over_time_03.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(0.1, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_over_time_04.png', - reason: 'Follow path should work as animation advances', - ); - }); - - testWidgets('Follow path - path over time', (WidgetTester tester) async { - final riveBytes = loadFile('assets/follow_path_path.riv'); - final file = RiveFile.import(riveBytes); - late Artboard artboard; - - final widget = RiveAnimation.direct( - file, - stateMachines: const ['State Machine 1'], - onInit: (a) { - artboard = a; - }, - ); - await tester.pumpWidget(widget); - - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_path_01.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_path_02.png', - reason: 'Follow path should work as animation advances', - ); - - artboard.advance(2.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'follow_path_path_03.png', - reason: 'Follow path should work as animation advances', - ); - }); - }); -} diff --git a/test/goldens/follow_path/images/follow_path_over_time_01.png b/test/goldens/follow_path/images/follow_path_over_time_01.png deleted file mode 100644 index c5d5126..0000000 --- a/test/goldens/follow_path/images/follow_path_over_time_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d90bcda9c1f5d8c05fdef40737db44703a0c383169862f8e3465b29ad87d97a5 -size 62061 diff --git a/test/goldens/follow_path/images/follow_path_over_time_02.png b/test/goldens/follow_path/images/follow_path_over_time_02.png deleted file mode 100644 index 992a1c7..0000000 --- a/test/goldens/follow_path/images/follow_path_over_time_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:16e4eab3f99a34ecb07897f5a71a451c00c8f1bcf9bc8d0c4c4ee8a4ab2bea24 -size 66343 diff --git a/test/goldens/follow_path/images/follow_path_over_time_03.png b/test/goldens/follow_path/images/follow_path_over_time_03.png deleted file mode 100644 index 251378e..0000000 --- a/test/goldens/follow_path/images/follow_path_over_time_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b91954012d83c34cb4725c8c5608e655df6741f033ee16561962a72463b4c96d -size 65824 diff --git a/test/goldens/follow_path/images/follow_path_over_time_04.png b/test/goldens/follow_path/images/follow_path_over_time_04.png deleted file mode 100644 index 107dcd6..0000000 --- a/test/goldens/follow_path/images/follow_path_over_time_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d7c79af5b882dfddbc94aa7a5d1efa17808cbfa875a1380307173a7911afc757 -size 64784 diff --git a/test/goldens/follow_path/images/follow_path_path_01.png b/test/goldens/follow_path/images/follow_path_path_01.png deleted file mode 100644 index 95f6947..0000000 --- a/test/goldens/follow_path/images/follow_path_path_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d3b7b54b69a740a897da914630555bbce9a9dfabeaa3fdfa4a4ce37774c6270 -size 150139 diff --git a/test/goldens/follow_path/images/follow_path_path_02.png b/test/goldens/follow_path/images/follow_path_path_02.png deleted file mode 100644 index eee3517..0000000 --- a/test/goldens/follow_path/images/follow_path_path_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c110b54737e9da7df678f471087814eae637f2fd6e57ce56c7c6d68ced726976 -size 149757 diff --git a/test/goldens/follow_path/images/follow_path_path_03.png b/test/goldens/follow_path/images/follow_path_path_03.png deleted file mode 100644 index f27309c..0000000 --- a/test/goldens/follow_path/images/follow_path_path_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd0704254d162ce9540e3e1fb738e22a9622b25f64f13a5fa164fece41cd2d00 -size 141876 diff --git a/test/goldens/follow_path/images/follow_path_solos_01.png b/test/goldens/follow_path/images/follow_path_solos_01.png deleted file mode 100644 index 7f5d55f..0000000 --- a/test/goldens/follow_path/images/follow_path_solos_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:473577ef768bf7d5546d11b6a6cb82aad14d4eaf2a48d09baab27ac41d55846b -size 43844 diff --git a/test/goldens/follow_path/images/follow_path_solos_02.png b/test/goldens/follow_path/images/follow_path_solos_02.png deleted file mode 100644 index b8af342..0000000 --- a/test/goldens/follow_path/images/follow_path_solos_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96d5a56012fdd986171c25406924201d9644198fc3a1c79e531f8d39f47377dc -size 43486 diff --git a/test/goldens/follow_path/images/follow_path_solos_03.png b/test/goldens/follow_path/images/follow_path_solos_03.png deleted file mode 100644 index f8cf431..0000000 --- a/test/goldens/follow_path/images/follow_path_solos_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:74c5ccb50884f559a90a1fdc37e36119c1d6a7c3fbceb66357d80241123e537a -size 44174 diff --git a/test/goldens/follow_path/images/follow_path_solos_04.png b/test/goldens/follow_path/images/follow_path_solos_04.png deleted file mode 100644 index 808881e..0000000 --- a/test/goldens/follow_path/images/follow_path_solos_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b236d2a8c3c6e97503e455d40c1e556447d1884eda8d41e844f45e7563d37fab -size 44075 diff --git a/test/goldens/golden_comparator.dart b/test/goldens/golden_comparator.dart deleted file mode 100644 index 4e66cc5..0000000 --- a/test/goldens/golden_comparator.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'dart:developer'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:path/path.dart' as path; - -const _kGoldenDiffTolerance = 0.005; - -class AppFileComparator extends LocalFileComparator { - AppFileComparator(String testFile) : super(Uri.parse(testFile)); - - @override - Future compare(Uint8List imageBytes, Uri golden) async { - final result = await GoldenFileComparator.compareLists( - imageBytes, - await getGoldenBytes(golden), - ); - - if (!result.passed && result.diffPercent > _kGoldenDiffTolerance) { - final error = await generateFailureOutput(result, golden, basedir); - throw FlutterError(error); - } - if (!result.passed) { - log( - 'A tolerable difference of ${result.diffPercent * 100}% was found when ' - 'comparing $golden.', - ); - } - return result.passed || result.diffPercent <= _kGoldenDiffTolerance; - } -} - -/// Expect that the [actual] image matches the golden image identified by -/// [goldenFileKey]. -/// -/// This is a wrapper around [expectLater] and [matchesGoldenFile] that -/// automatically sets the [goldenFileComparator] to [AppFileComparator] and -/// sets the golden file path to `images/$goldenFileKey`. -/// -/// The tolerance for the difference between the golden and actual image is -/// set to [_kGoldenDiffTolerance] - 0.005. -Future expectGoldenMatches( - dynamic actual, - String goldenFileKey, { - String? reason, - bool skip = false, -}) { - final goldenPath = path.join('images', goldenFileKey); - goldenFileComparator = AppFileComparator( - path.join( - (goldenFileComparator as LocalFileComparator).basedir.toString(), - goldenFileKey, - ), - ); - - return expectLater( - actual, - matchesGoldenFile(goldenPath), - reason: reason, - skip: skip, - ); -} diff --git a/test/goldens/joysticks/golden_joysticks_test.dart b/test/goldens/joysticks/golden_joysticks_test.dart deleted file mode 100644 index 47ab837..0000000 --- a/test/goldens/joysticks/golden_joysticks_test.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/math.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - Joystick tests', () { - // See: https://github.com/rive-app/rive/pull/5589 - testWidgets('Joystick handle source', (WidgetTester tester) async { - final riveBytes = loadFile('assets/joystick_handle_source.riv'); - final file = RiveFile.import(riveBytes); - late Artboard artboard; - late StateMachineController controller; - - final widget = RiveAnimation.direct( - file, - useArtboardSize: true, - onInit: (a) { - artboard = a; - controller = artboard.stateMachineByName('State Machine 1')!; - artboard.addController(controller); - }, - ); - await tester.pumpWidget(widget); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'joystick_handle_source_01.png', - reason: 'Handle source on joystick should be updated by listeners', - ); - - controller.pointerMove(Vec2D.fromValues(85, 60)); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'joystick_handle_source_02.png', - reason: 'Handle source on joystick should be updated by listeners', - ); - - controller.pointerMove(Vec2D.fromValues(370, 65)); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'joystick_handle_source_03.png', - reason: 'Handle source on joystick should be updated by listeners', - ); - - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'joystick_handle_source_04.png', - reason: 'Handle source on joystick should be updated by listeners' - ' when advanding time', - ); - }); - }); -} diff --git a/test/goldens/joysticks/images/joystick_handle_source_01.png b/test/goldens/joysticks/images/joystick_handle_source_01.png deleted file mode 100644 index 87b8929..0000000 --- a/test/goldens/joysticks/images/joystick_handle_source_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b650e64d24fb3c05fc3dbe4cba6c3b6af787341a8cf743982f311988674d0e66 -size 21334 diff --git a/test/goldens/joysticks/images/joystick_handle_source_02.png b/test/goldens/joysticks/images/joystick_handle_source_02.png deleted file mode 100644 index f7f6d85..0000000 --- a/test/goldens/joysticks/images/joystick_handle_source_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43c9dcb740e44b33edd13e08878103852ae0eb7ee3e9149dd2124d9c045c4187 -size 21308 diff --git a/test/goldens/joysticks/images/joystick_handle_source_03.png b/test/goldens/joysticks/images/joystick_handle_source_03.png deleted file mode 100644 index 14328da..0000000 --- a/test/goldens/joysticks/images/joystick_handle_source_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7285eacb544a5c319b4c7510bdd6f782883a00a125913c57fc4cc92cf9adf3ce -size 21311 diff --git a/test/goldens/joysticks/images/joystick_handle_source_04.png b/test/goldens/joysticks/images/joystick_handle_source_04.png deleted file mode 100644 index 4a294e1..0000000 --- a/test/goldens/joysticks/images/joystick_handle_source_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f63921034ece5bd1be1d7cb96d84c6b4bf28fbd3f7f56e814b71c5150444cf6d -size 21322 diff --git a/test/goldens/simple_animations/golden_simple_animations_test.dart b/test/goldens/simple_animations/golden_simple_animations_test.dart deleted file mode 100644 index 33fb5dc..0000000 --- a/test/goldens/simple_animations/golden_simple_animations_test.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - simple linear animations', () { - testWidgets('Play first animation found', (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - await tester.pumpWidget(RiveAnimation.direct(file)); - - // Advance animation by one frame - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'play_first_animation_found.png', - reason: 'Animation should be advanced by one frame', - ); - }); - - testWidgets('Play provided animation controller', - (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - final controller = SimpleAnimation('bouncing'); - - late Artboard artboard; - - await tester.pumpWidget(RiveAnimation.direct( - file, - controllers: [controller], - onInit: (a) { - artboard = a; - }, - )); - - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'play_provided_animation_controller_01.png', - reason: 'Simple animation should be advanced by one frame', - ); - - controller.apply(artboard as RuntimeArtboard, 1); - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - 'play_provided_animation_controller_02.png', - reason: 'Simple animation should be advanced by one second', - ); - }); - - testWidgets('Mixed animations', (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - final controllerIdle = SimpleAnimation('idle'); - final controllerBouncing = SimpleAnimation('bouncing'); - final controllerWipers = SimpleAnimation('windshield_wipers'); - - late Artboard artboard; - - await tester.pumpWidget(RiveAnimation.direct( - file, - controllers: [controllerIdle, controllerBouncing, controllerWipers], - onInit: (a) { - artboard = a; - }, - )); - - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'mixed_animations_01.png', - reason: 'Mixed animations should be advanced by one frame', - ); - - controllerIdle.apply(artboard as RuntimeArtboard, 0.5); - controllerBouncing.apply(artboard as RuntimeArtboard, 0.5); - controllerWipers.apply(artboard as RuntimeArtboard, 0.5); - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - 'mixed_animations_02.png', - reason: 'Mixed animations should be advanced by half a second', - ); - }); - }); -} diff --git a/test/goldens/simple_animations/images/mixed_animations_01.png b/test/goldens/simple_animations/images/mixed_animations_01.png deleted file mode 100644 index e451031..0000000 --- a/test/goldens/simple_animations/images/mixed_animations_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:17ce202d83aa483a07474e0adad651dd3859938224cb54b9afba3f8ec6ff757a -size 497679 diff --git a/test/goldens/simple_animations/images/mixed_animations_02.png b/test/goldens/simple_animations/images/mixed_animations_02.png deleted file mode 100644 index f8d7be1..0000000 --- a/test/goldens/simple_animations/images/mixed_animations_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:82c34817b2ae0c6051bbd22b4ef7ccc992044a96ac527dd33ad86addf72d83bb -size 491924 diff --git a/test/goldens/simple_animations/images/play_first_animation_found.png b/test/goldens/simple_animations/images/play_first_animation_found.png deleted file mode 100644 index ee50201..0000000 --- a/test/goldens/simple_animations/images/play_first_animation_found.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dcb348e2b2a7360bf6e4100879befc767176b65a7f04138c2428e9cb93170a66 -size 462288 diff --git a/test/goldens/simple_animations/images/play_provided_animation_controller_01.png b/test/goldens/simple_animations/images/play_provided_animation_controller_01.png deleted file mode 100644 index 86861e2..0000000 --- a/test/goldens/simple_animations/images/play_provided_animation_controller_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3626496af8cedecca04796fcf2eee9deaf8c9eb0cf7cdf5a323e26aed1060317 -size 505022 diff --git a/test/goldens/simple_animations/images/play_provided_animation_controller_02.png b/test/goldens/simple_animations/images/play_provided_animation_controller_02.png deleted file mode 100644 index 0881085..0000000 --- a/test/goldens/simple_animations/images/play_provided_animation_controller_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9152c60eaca00018a44d3cef375827f9a616e38c24b04d9a4bd5e23f4380fcf3 -size 508222 diff --git a/test/goldens/skins_opacity/golden_skins_opacity_test.dart b/test/goldens/skins_opacity/golden_skins_opacity_test.dart deleted file mode 100644 index dd6c7b3..0000000 --- a/test/goldens/skins_opacity/golden_skins_opacity_test.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - solo animations', () { - testWidgets('Play first animation found', (WidgetTester tester) async { - final riveBytes = loadFile('assets/skins_demo.riv'); - final file = RiveFile.import(riveBytes); - late SMITrigger trigger; - late Artboard artboard; - late StateMachineController controller; - - final widget = RiveAnimation.direct( - file, - onInit: (a) { - artboard = a; - controller = StateMachineController.fromArtboard( - artboard, - 'Motion', - )!; - controller.isActive = false; - artboard.addController(controller); - trigger = controller.getTriggerInput('Skin')!; - }, - ); - - await tester.pumpWidget(widget); - trigger.fire(); - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'skins_opacity_01.png', - reason: 'Skins (opacity/animation) should be swapped', - ); - - trigger.fire(); - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'skins_opacity_02.png', - reason: 'Skins (opacity/animation) should be swapped', - ); - - trigger.fire(); - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'skins_opacity_03.png', - reason: 'Skins (opacity/animation) should be swapped', - ); - - trigger.fire(); - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'skins_opacity_04.png', - reason: 'Skins (opacity/animation) should be swapped', - ); - - trigger.fire(); - artboard.advance(0.5, nested: true); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'skins_opacity_05.png', - reason: 'Skins (opacity/animation) should be swapped', - ); - }); - }); -} diff --git a/test/goldens/skins_opacity/images/skins_opacity_01.png b/test/goldens/skins_opacity/images/skins_opacity_01.png deleted file mode 100644 index a1574b4..0000000 --- a/test/goldens/skins_opacity/images/skins_opacity_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e04235a1d43106315eb4abad9ee63a07a3e656363601da6223890afa0ad7c52 -size 26543 diff --git a/test/goldens/skins_opacity/images/skins_opacity_02.png b/test/goldens/skins_opacity/images/skins_opacity_02.png deleted file mode 100644 index 7fe36ef..0000000 --- a/test/goldens/skins_opacity/images/skins_opacity_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd890928ccef4e12106db697f926e79449fb20b16c01b5a6e1701d15bc823e1a -size 28170 diff --git a/test/goldens/skins_opacity/images/skins_opacity_03.png b/test/goldens/skins_opacity/images/skins_opacity_03.png deleted file mode 100644 index 2bf61cb..0000000 --- a/test/goldens/skins_opacity/images/skins_opacity_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:391b7c21c44e8760a9a8b6ed83cd8deaf03bae701876810bf8ddaba7ea26d28d -size 31862 diff --git a/test/goldens/skins_opacity/images/skins_opacity_04.png b/test/goldens/skins_opacity/images/skins_opacity_04.png deleted file mode 100644 index f838fe5..0000000 --- a/test/goldens/skins_opacity/images/skins_opacity_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e051cf8d2c0f396194d55589c9b58fc888422f6b5015c2c079f2144f067428a6 -size 28979 diff --git a/test/goldens/skins_opacity/images/skins_opacity_05.png b/test/goldens/skins_opacity/images/skins_opacity_05.png deleted file mode 100644 index aa8581c..0000000 --- a/test/goldens/skins_opacity/images/skins_opacity_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6a3abd62dce3becf00e92273615f264b8272f8ea228fb76c21d8356a169ed20c -size 36698 diff --git a/test/goldens/spilled_time/images/spilled_time_00.png b/test/goldens/spilled_time/images/spilled_time_00.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/images/spilled_time_01.png b/test/goldens/spilled_time/images/spilled_time_01.png deleted file mode 100644 index be7575d..0000000 --- a/test/goldens/spilled_time/images/spilled_time_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:27bf6a24a874ed77e25e29b4b294f5207a0489656d6c7caea532b3f23375c212 -size 21138 diff --git a/test/goldens/spilled_time/images/spilled_time_02.png b/test/goldens/spilled_time/images/spilled_time_02.png deleted file mode 100644 index 4a89687..0000000 --- a/test/goldens/spilled_time/images/spilled_time_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36d8f3786a1ee6206deac0a7fac12fafab69795a7a72b7595b272e8c7c694b5c -size 21133 diff --git a/test/goldens/spilled_time/images/spilled_time_03.png b/test/goldens/spilled_time/images/spilled_time_03.png deleted file mode 100644 index de32ded..0000000 --- a/test/goldens/spilled_time/images/spilled_time_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ae4c6fb4ce0847134e7059d0cb6c259896a26f18c511edf3300f946b841af3d -size 21138 diff --git a/test/goldens/spilled_time/images/spilled_time_04.png b/test/goldens/spilled_time/images/spilled_time_04.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/images/spilled_time_05.png b/test/goldens/spilled_time/images/spilled_time_05.png deleted file mode 100644 index 10c5d84..0000000 --- a/test/goldens/spilled_time/images/spilled_time_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86d7be8a4e4ac369ba524a278f60a87f8189b0869c3d884a7f1c7d41ecbeb3f1 -size 21140 diff --git a/test/goldens/spilled_time/images/spilled_time_exact_00.png b/test/goldens/spilled_time/images/spilled_time_exact_00.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_exact_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/images/spilled_time_exact_01.png b/test/goldens/spilled_time/images/spilled_time_exact_01.png deleted file mode 100644 index e1f3357..0000000 --- a/test/goldens/spilled_time/images/spilled_time_exact_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:64abf4ab9a8fc63dc33f4380642217d5eb5ced4e684ec6989ad0c57a7da4a263 -size 21140 diff --git a/test/goldens/spilled_time/images/spilled_time_exact_02.png b/test/goldens/spilled_time/images/spilled_time_exact_02.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_exact_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/images/spilled_time_overshoot_00.png b/test/goldens/spilled_time/images/spilled_time_overshoot_00.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_overshoot_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/images/spilled_time_overshoot_01.png b/test/goldens/spilled_time/images/spilled_time_overshoot_01.png deleted file mode 100644 index 4a89687..0000000 --- a/test/goldens/spilled_time/images/spilled_time_overshoot_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36d8f3786a1ee6206deac0a7fac12fafab69795a7a72b7595b272e8c7c694b5c -size 21133 diff --git a/test/goldens/spilled_time/images/spilled_time_overshoot_02.png b/test/goldens/spilled_time/images/spilled_time_overshoot_02.png deleted file mode 100644 index c3033ec..0000000 --- a/test/goldens/spilled_time/images/spilled_time_overshoot_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:232f5484944a4ce2b9002f443800e1ca1e9c04f55790f67f41960434555d007f -size 21139 diff --git a/test/goldens/spilled_time/spilled_time_test.dart b/test/goldens/spilled_time/spilled_time_test.dart deleted file mode 100644 index 9328f67..0000000 --- a/test/goldens/spilled_time/spilled_time_test.dart +++ /dev/null @@ -1,151 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -class RiveAnimationMatcher { - final WidgetTester tester; - final String name; - var _matchCount = 0; - - RiveAnimationMatcher(this.tester, this.name); - - Future match(String reason) async { - await tester.pump(); - print('${name}_${_matchCount.toString().padLeft(2, '0')}.png'); - await expectGoldenMatches( - find.byType(RiveAnimation), - '${name}_${_matchCount.toString().padLeft(2, '0')}.png', - reason: reason, - ); - _matchCount++; - } -} - -void main() { - group('Golden - spilled time test', () { - testWidgets('Test with Spilled time', (WidgetTester tester) async { - final matcher = RiveAnimationMatcher(tester, 'spilled_time'); - final riveBytes = loadFile('assets/spilled_time.riv'); - final file = RiveFile.import(riveBytes); - late SMITrigger trigger; - late Artboard artboard; - late StateMachineController controller; - - final widget = RiveAnimation.direct( - file, - onInit: (a) { - artboard = a; - controller = StateMachineController.fromArtboard( - artboard, - 'State Machine 1', - )!; - controller.isActive = false; - artboard.addController(controller); - trigger = controller.getTriggerInput('Trigger 1')!; - }, - ); - await tester.pumpWidget(widget); - - // first fire after fire just changes the state, this time gets lost - // i suspect the "entry state" eats this time. - trigger.fire(); - artboard.advance(0.5); - await matcher.match('one shot & loop lines line up at left hand side'); - - artboard.advance(0.25); - await matcher.match('one shot & loop lines line up 25% across'); - - artboard.advance(1.25); - await matcher - .match('one shot is finished at 100%, loop looped back to 50%'); - - // we advance an extra time before trigger - artboard.advance(0.1); - await matcher.match('one shot stays at 100%, loop advanced to 60%'); - - // once again advance after fire, the whole time gets lost - // TODO: without the spilled time fix, the one shot animation - // does advance, the loop does not. the fix might be the wrong - // way around - trigger.fire(); - artboard.advance(0.3); - await matcher.match('one shot & loop lines line up at left hand side'); - - artboard.advance(0.1); - await matcher.match('top and bottom lines line up 10% across width'); - }); - - testWidgets('Test with Spilled time overshoot', - (WidgetTester tester) async { - final matcher = RiveAnimationMatcher(tester, 'spilled_time_overshoot'); - final riveBytes = loadFile('assets/spilled_time.riv'); - final file = RiveFile.import(riveBytes); - late SMITrigger trigger; - late Artboard artboard; - late StateMachineController controller; - - final widget = RiveAnimation.direct( - file, - onInit: (a) { - artboard = a; - controller = StateMachineController.fromArtboard( - artboard, - 'State Machine 1', - )!; - controller.isActive = false; - artboard.addController(controller); - trigger = controller.getTriggerInput('Trigger 1')!; - }, - ); - await tester.pumpWidget(widget); - - trigger.fire(); - artboard.advance(0); - await matcher.match('one shot & loop lines line up at left hand side'); - - artboard.advance(1.5); - await matcher.match('one shot gets stuck at 100% & loop advances to 50%'); - - trigger.fire(); - artboard.advance(0.25); - await matcher.match('one shot & loop reset to 0%'); - }); - - testWidgets('Test with Spilled time exact', (WidgetTester tester) async { - final matcher = RiveAnimationMatcher(tester, 'spilled_time_exact'); - final riveBytes = loadFile('assets/spilled_time.riv'); - final file = RiveFile.import(riveBytes); - late SMITrigger trigger; - late Artboard artboard; - late StateMachineController controller; - - final widget = RiveAnimation.direct( - file, - onInit: (a) { - artboard = a; - controller = StateMachineController.fromArtboard( - artboard, - 'State Machine 1', - )!; - controller.isActive = false; - artboard.addController(controller); - trigger = controller.getTriggerInput('Trigger 1')!; - }, - ); - await tester.pumpWidget(widget); - - trigger.fire(); - artboard.advance(0); - await matcher.match('one shot & loop lines line up at left hand side'); - - artboard.advance(1); - await matcher.match('one shot & loop get to 100%'); - - trigger.fire(); - artboard.advance(0.25); - await matcher.match('one shot resets to 0% & loop reset to 0%'); - }); - }); -} diff --git a/test/goldens/text/golden_text_test.dart b/test/goldens/text/golden_text_test.dart deleted file mode 100644 index 08e23f4..0000000 --- a/test/goldens/text/golden_text_test.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/math.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - Text tests', () { - testWidgets('Text runs update with bone constraints', - (WidgetTester tester) async { - final riveBytes = loadFile('assets/electrified_button_simple.riv'); - final file = RiveFile.import(riveBytes); - late Artboard artboard; - late StateMachineController controller; - late TextValueRun textRun; - - final widget = RiveAnimation.direct( - file, - useArtboardSize: true, - onInit: (a) { - artboard = a; - controller = artboard.stateMachineByName('button')!; - artboard.addController(controller); - textRun = artboard.component('name')!; - }, - ); - await tester.pumpWidget(widget); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'text_bones_constraint_01.png', - reason: 'First frame should match golden', - ); - - controller.pointerMove(Vec2D.fromValues(250, 250)); - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'text_bones_constraint_02.png', - reason: - 'Hovering should trigger a different animation for text and button', - ); - - textRun.text = 'short'; - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - 'text_bones_constraint_03.png', - reason: 'Short text runs should update with bone constraints', - ); - - textRun.text = 'Extremely long text. The longest.'; - await tester.pump(); - await expectGoldenMatches( - find.byType(RiveAnimation), - 'text_bones_constraint_04.png', - reason: 'Long text runs should update with bone constraints', - ); - }); - }); -} diff --git a/test/goldens/text/images/text_bones_constraint_01.png b/test/goldens/text/images/text_bones_constraint_01.png deleted file mode 100644 index f1ffd6e..0000000 --- a/test/goldens/text/images/text_bones_constraint_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ddeb9c542c5253b4ff4b8d7289e6d318f3a061041ceeecfa6f723ab0abad761e -size 42087 diff --git a/test/goldens/text/images/text_bones_constraint_02.png b/test/goldens/text/images/text_bones_constraint_02.png deleted file mode 100644 index 2e8d87a..0000000 --- a/test/goldens/text/images/text_bones_constraint_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61cff8801da33c1431fc5e58420b5c02c48f8e9f5f3199fb1287261608996289 -size 77065 diff --git a/test/goldens/text/images/text_bones_constraint_03.png b/test/goldens/text/images/text_bones_constraint_03.png deleted file mode 100644 index 030b0b6..0000000 --- a/test/goldens/text/images/text_bones_constraint_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fec3cf8130def01847828f3cd4031d5eda59af442a60cb923a4e1aabd7a3aecb -size 67366 diff --git a/test/goldens/text/images/text_bones_constraint_04.png b/test/goldens/text/images/text_bones_constraint_04.png deleted file mode 100644 index a65b0de..0000000 --- a/test/goldens/text/images/text_bones_constraint_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3ddd3040ca2bf52e28a9657b6791c5d80d6f91941d8e97705b19b23daeea6c95 -size 87510 diff --git a/test/goldens/ticker_mode/golden_ticker_mode_test.dart b/test/goldens/ticker_mode/golden_ticker_mode_test.dart deleted file mode 100644 index 5a5571c..0000000 --- a/test/goldens/ticker_mode/golden_ticker_mode_test.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import '../../src/utils.dart'; -import '../golden_comparator.dart'; - -void main() { - group('Golden - ticker mode tests', () { - testWidgets('ticker mode initially false pauses animation', - (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - final widget = TickerMode( - enabled: false, - child: RiveAnimation.direct(file), - ); - await tester.pumpWidget(widget); - - // Advance animation by one frame - await tester.pump(); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_false.png', - reason: 'Animation frame should be paused with ticker mode false', - ); - - await tester.pumpFrames(widget, const Duration(milliseconds: 1500)); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_false.png', - reason: 'Animation should not have advanced with ticker mode false', - ); - }); - - testWidgets('ticker mode initially true plays animation', - (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - final widget = TickerMode( - enabled: true, - child: RiveAnimation.direct(file), - ); - await tester.pumpWidget(widget); - - await tester.pumpFrames(widget, const Duration(milliseconds: 100)); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_true_1.png', - reason: 'Animation frame should play with ticker mode true', - ); - - await tester.pumpFrames(widget, const Duration(milliseconds: 1500)); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_true_2.png', - reason: 'Animation should advance with ticker mode true', - ); - }); - - testWidgets('ticker mode variable state', (WidgetTester tester) async { - final riveBytes = loadFile('assets/off_road_car.riv'); - final file = RiveFile.import(riveBytes); - - final key = GlobalKey<_VariableTickerModeState>(); - final widget = _VariableTickerMode(stateKey: key, file: file); - - await tester.pumpWidget(widget); - - await tester.pumpFrames(widget, const Duration(milliseconds: 100)); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_true_1.png', - reason: 'Animation frame should play with ticker mode true', - ); - - key.currentState!.disableTickerMode(); - - await tester.pumpFrames(widget, const Duration(milliseconds: 1500)); - - await expectGoldenMatches( - find.byType(RiveAnimation), - 'ticker_mode_true_paused_state.png', - reason: - 'Animation should not have advanced with ticker mode state false', - ); - }); - }); -} - -class _VariableTickerMode extends StatefulWidget { - const _VariableTickerMode({ - required this.stateKey, - required this.file, - }) : super(key: stateKey); - - final GlobalKey<_VariableTickerModeState> stateKey; - final RiveFile file; - - @override - State<_VariableTickerMode> createState() => _VariableTickerModeState(); -} - -class _VariableTickerModeState extends State<_VariableTickerMode> { - bool ticker = true; - - void disableTickerMode() { - setState(() { - ticker = false; - }); - } - - @override - Widget build(BuildContext context) { - return TickerMode( - enabled: ticker, - child: RiveAnimation.direct(widget.file), - ); - } -} diff --git a/test/goldens/ticker_mode/images/ticker_mode_false.png b/test/goldens/ticker_mode/images/ticker_mode_false.png deleted file mode 100644 index ee50201..0000000 --- a/test/goldens/ticker_mode/images/ticker_mode_false.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dcb348e2b2a7360bf6e4100879befc767176b65a7f04138c2428e9cb93170a66 -size 462288 diff --git a/test/goldens/ticker_mode/images/ticker_mode_true_1.png b/test/goldens/ticker_mode/images/ticker_mode_true_1.png deleted file mode 100644 index 2b4ad18..0000000 --- a/test/goldens/ticker_mode/images/ticker_mode_true_1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c2cfab857dbcad75420973bdf1bc74fa6d83d3ac7428bb30f524616e4f0767dd -size 463733 diff --git a/test/goldens/ticker_mode/images/ticker_mode_true_2.png b/test/goldens/ticker_mode/images/ticker_mode_true_2.png deleted file mode 100644 index 8ff405c..0000000 --- a/test/goldens/ticker_mode/images/ticker_mode_true_2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c6e9cbded409f8f4838c8ce7f18fa7e2721087cb40d334afb04a85ebe7843c2e -size 473098 diff --git a/test/goldens/ticker_mode/images/ticker_mode_true_paused_state.png b/test/goldens/ticker_mode/images/ticker_mode_true_paused_state.png deleted file mode 100644 index 50ba9f9..0000000 --- a/test/goldens/ticker_mode/images/ticker_mode_true_paused_state.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e6ed13efb7f90bc32b5b5f8bd8a87dcd50aa8c5e532d18b486b3b1fad20f2384 -size 466392 diff --git a/test/hit_test.dart b/test/hit_test.dart deleted file mode 100644 index c047d5a..0000000 --- a/test/hit_test.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -/// `hit_test_pass_through.riv` does not have any listeners. Only a -/// [RiveHitTestBehavior] of type `opaque` should block content underneath. -/// -/// `hit_test_consumer.riv` has a listener that covers the entire artboard. -/// Only a [RiveHitTestBehavior] of type `transparent` should allow hits -/// for content underneath. - -void main() { - testWidgets('Hit test pass through artboard to widget beneath', - (tester) async { - final riveBytes = loadFile('assets/hit_test_pass_through.riv'); - final riveFile = RiveFile.import(riveBytes); - - int count = 0; - await tester.pumpWidget(HitTestWidget( - file: riveFile, - behavior: RiveHitTestBehavior.translucent, - onTap: () { - count++; - }, - )); - - await tester.pumpAndSettle(); - - final titleFinder = find.text(textButtonTitle); - await tester.tap(titleFinder); - - expect(count, 1); - }); - - testWidgets('Hit test blocked by default opaque behavior', (tester) async { - final riveBytes = loadFile('assets/hit_test_pass_through.riv'); - final riveFile = RiveFile.import(riveBytes); - - int count = 0; - await tester.pumpWidget(HitTestWidget( - file: riveFile, - behavior: RiveHitTestBehavior.opaque, // default - onTap: () { - count++; - }, - )); - - await tester.pumpAndSettle(); - - final titleFinder = find.text(textButtonTitle); - await tester.tap(titleFinder); - - expect(count, 0); - }); - - testWidgets('Hit test artboard consume hit with opaque', (tester) async { - final riveBytes = loadFile('assets/hit_test_consume.riv'); - final riveFile = RiveFile.import(riveBytes); - - int count = 0; - await tester.pumpWidget(HitTestWidget( - file: riveFile, - behavior: RiveHitTestBehavior.opaque, - onTap: () { - count++; - }, - )); - await tester.pumpAndSettle(); - final titleFinder = find.text(textButtonTitle); - await tester.tap(titleFinder); - - expect(count, 0); - }); - - testWidgets('Hit test artboard consume hit with translucent', (tester) async { - final riveBytes = loadFile('assets/hit_test_consume.riv'); - final riveFile = RiveFile.import(riveBytes); - - int count = 0; - await tester.pumpWidget(HitTestWidget( - file: riveFile, - behavior: RiveHitTestBehavior.translucent, - onTap: () { - count++; - }, - )); - await tester.pumpAndSettle(); - final titleFinder = find.text(textButtonTitle); - await tester.tap(titleFinder); - - expect(count, 0); - }); - - testWidgets('Hit test artboard pass through transparent behavior', - (tester) async { - final riveBytes = loadFile('assets/hit_test_consume.riv'); - final riveFile = RiveFile.import(riveBytes); - - int count = 0; - await tester.pumpWidget(HitTestWidget( - file: riveFile, - behavior: RiveHitTestBehavior.transparent, - onTap: () { - count++; - }, - )); - await tester.pumpAndSettle(); - final titleFinder = find.text(textButtonTitle); - await tester.tap(titleFinder); - - expect(count, 1); - }); -} - -const textButtonTitle = "Widget to click"; - -class HitTestWidget extends StatelessWidget { - const HitTestWidget({ - required this.file, - required this.onTap, - required this.behavior, - super.key, - }); - - final RiveFile file; - final VoidCallback onTap; - final RiveHitTestBehavior behavior; - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - body: SizedBox( - width: 500, - height: 500, - child: Stack( - children: [ - Center( - child: GestureDetector( - onTap: onTap, - child: const Text(textButtonTitle), - ), - ), - RiveAnimation.direct( - file, - stateMachines: const ['State Machine 1'], - fit: BoxFit.cover, - behavior: behavior, - ), - ], - ), - ), - ), - ); - } -} diff --git a/test/linear_animation_instance_test.dart b/test/linear_animation_instance_test.dart deleted file mode 100644 index 4ebae78..0000000 --- a/test/linear_animation_instance_test.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -void main() { - late RiveFile riveFile; - - setUp(() { - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - riveFile = RiveFile.import(riveBytes); - }); - - test('LinearAnimationInstance exposes direction is either +/-1', () { - final artboard = riveFile.mainArtboard; - - expect(artboard.animations, isNotEmpty); - LinearAnimationInstance instance = - LinearAnimationInstance(artboard.animations.first as LinearAnimation); - - expect(instance.direction, 1); - instance.direction = -1; - expect(instance.direction, -1); - // If any other integer is given, it should default to 1 - instance.direction = -4; - expect(instance.direction, 1); - }); - - test('LinearAnimationInstance has a valid start and end time', () { - final artboard = riveFile.mainArtboard; - - expect(artboard.animations, isNotEmpty); - LinearAnimationInstance instance = - LinearAnimationInstance(artboard.animations.first as LinearAnimation); - - final startTime = instance.animation.startTime; - final endTime = instance.animation.endTime; - expect(startTime <= endTime, isTrue); - expect(instance.direction, 1); - // Advance the animation to the mid point - instance.advance((endTime - startTime) / 2); - expect(instance.time > startTime, isTrue); - expect(instance.time < endTime, isTrue); - // Advance past the end of the4 animation - instance.advance(endTime); - expect(instance.time == endTime, isTrue); - }); - - test('LinearAnimationInstance can be reset', () { - final artboard = riveFile.mainArtboard; - - expect(artboard.animations, isNotEmpty); - LinearAnimationInstance instance = - LinearAnimationInstance(artboard.animations.first as LinearAnimation); - - // Check the starting position - expect(instance.animation.startTime < instance.animation.endTime, isTrue); - expect(instance.animation.startTime, instance.time); - - // Advance - instance.advance(instance.animation.endTime); - expect(instance.time, instance.animation.endTime); - - // Reset - instance.reset(); - expect(instance.time, instance.animation.startTime); - }); -} diff --git a/test/mocks/fakes.dart b/test/mocks/fakes.dart deleted file mode 100644 index eea8ebf..0000000 --- a/test/mocks/fakes.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -class ArtboardFake extends Fake implements Artboard { - bool _isPlaying = true; - - @override - bool get isPlaying => _isPlaying; - - @override - void pause() { - _isPlaying = false; - } - - @override - void play() { - _isPlaying = true; - } -} diff --git a/test/mocks/mocks.dart b/test/mocks/mocks.dart deleted file mode 100644 index 64a8b8d..0000000 --- a/test/mocks/mocks.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:mocktail/mocktail.dart'; -import 'package:rive/src/rive_core/artboard.dart'; -export 'fakes.dart'; - -// ignore: one_member_abstracts -abstract class _OnInitFunction { - void call(Artboard _); -} - -class OnInitCallbackMock extends Mock implements _OnInitFunction {} diff --git a/test/nested_input_test.dart b/test/nested_input_test.dart deleted file mode 100644 index 19971e8..0000000 --- a/test/nested_input_test.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -void main() { - late RiveFile riveFile; - - setUp(() { - TestWidgetsFlutterBinding.ensureInitialized(); - final riveBytes = loadFile('assets/runtime_nested_inputs.riv'); - riveFile = RiveFile.import(riveBytes); - }); - - test('Nested boolean input can be get/set', () async { - final artboard = riveFile.artboards.first.instance(); - expect(artboard, isNotNull); - final artboardInstance = artboard.instance(); - expect(artboardInstance, isNotNull); - final bool = artboard.getBoolInput("CircleOuterState", "CircleOuter"); - expect(bool, isNotNull); - expect(bool!.value, false); - bool.value = true; - expect(bool.value, true); - }); - - test('Nested number input can be get/set', () async { - final artboard = riveFile.artboards.first.instance(); - expect(artboard, isNotNull); - final artboardInstance = artboard.instance(); - expect(artboardInstance, isNotNull); - final num = artboard.getNumberInput("CircleOuterNumber", "CircleOuter"); - expect(num, isNotNull); - expect(num!.value, 0); - num.value = 99; - expect(num.value, 99); - }); - - test('Nested trigger can be get/fired', () async { - final artboard = riveFile.artboards.first.instance(); - expect(artboard, isNotNull); - final artboardInstance = artboard.instance(); - expect(artboardInstance, isNotNull); - final trigger = - artboard.getTriggerInput("CircleOuterTrigger", "CircleOuter"); - expect(trigger, isNotNull); - trigger!.fire(); - }); - - test('Nested boolean input can be get/set multiple levels deep', () async { - final artboard = riveFile.artboards.first.instance(); - expect(artboard, isNotNull); - final artboardInstance = artboard.instance(); - expect(artboardInstance, isNotNull); - final bool = - artboard.getBoolInput("CircleInnerState", "CircleOuter/CircleInner"); - expect(bool, isNotNull); - expect(bool!.value, false); - bool.value = true; - expect(bool.value, true); - }); -} diff --git a/test/rive_animation_test.dart b/test/rive_animation_test.dart deleted file mode 100644 index 7d52399..0000000 --- a/test/rive_animation_test.dart +++ /dev/null @@ -1,352 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rive/rive.dart'; - -import 'mocks/mocks.dart'; -import 'src/utils.dart'; - -const _changeAnimationButtonKey = Key('btnChangeAnimation'); -const _changeStateMachineButtonKey = Key('btnChangeStateMachine'); -const _changeControllerButtonKey = Key('btnChangeController'); -const _updateWidgetPropertiesButtonKey = Key('btnUpdateWidgetProperties'); - -const _placeHolderWidgetOne = Text('placeholder one'); -const _placeHolderWidgetTwo = Text('placeholder two'); - -class TestApp extends StatefulWidget { - final RiveFile file; - const TestApp( - this.file, { - this.onInit, - Key? key, - }) : super(key: key); - - final OnInitCallback? onInit; - - @override - _TestAppState createState() => _TestAppState(); -} - -class _TestAppState extends State { - int _counter = 0; - - final animations = ["one", "two"]; - final stateMachines = ["one", "two"]; - final controllers = [SimpleAnimation('one'), SimpleAnimation('two')]; - - late String animation = animations.first; - late String stateMachine = stateMachines.first; - late SimpleAnimation controller = controllers.first; - - BoxFit fit = BoxFit.contain; - Alignment alignment = Alignment.topCenter; - bool anitaliasing = true; - Widget placeholder = _placeHolderWidgetOne; - - void _changeAnimation() { - setState(() { - _counter += 1; - animation = animations[_counter % animations.length]; - }); - } - - void _changeStateMachine() { - setState(() { - _counter += 1; - stateMachine = stateMachines[_counter % stateMachines.length]; - }); - } - - void _changeController() { - setState(() { - _counter += 1; - controller = controllers[_counter % stateMachines.length]; - }); - } - - void _updateWidgetProperties() { - setState(() { - fit = BoxFit.fitHeight; - alignment = Alignment.bottomCenter; - anitaliasing = false; - placeholder = _placeHolderWidgetTwo; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - children: [ - Expanded( - child: RiveAnimation.direct( - widget.file, - animations: [animation], - stateMachines: [stateMachine], - controllers: [controller], - fit: fit, - alignment: alignment, - antialiasing: anitaliasing, - placeHolder: placeholder, - onInit: widget.onInit, - ), - ), - ElevatedButton( - key: _changeAnimationButtonKey, - onPressed: _changeAnimation, - child: const Text('Change Animation'), - ), - ElevatedButton( - key: _changeStateMachineButtonKey, - onPressed: _changeStateMachine, - child: const Text('Change State Machine'), - ), - ElevatedButton( - key: _changeControllerButtonKey, - onPressed: _changeController, - child: const Text('Change Controller'), - ), - ElevatedButton( - key: _updateWidgetPropertiesButtonKey, - onPressed: _updateWidgetProperties, - child: const Text('Update widget properties'), - ), - ], - ), - ), - ); - } -} - -void main() { - setUpAll(() { - registerFallbackValue(ArtboardFake()); - }); - - late OnInitCallbackMock initMock; - - setUp( - () { - initMock = OnInitCallbackMock(); - }, - ); - - testWidgets('Render a rive file', (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final riveFile = RiveFile.import(riveBytes); - await tester.pumpWidget(MaterialApp(home: RiveAnimation.direct(riveFile))); - }); - - group('Test updates to rive widget:', () { - testWidgets('Changing animation changes rive widget', - (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final riveFile = RiveFile.import(riveBytes); - - await tester.pumpWidget( - MaterialApp( - home: TestApp( - riveFile, - onInit: initMock.call, - ), - ), - ); - - final state = - tester.state(find.byType(RiveAnimation).first) as RiveAnimationState; - - expect(state.widget.animations, ["one"]); - - await tester.tap(find.byKey(_changeAnimationButtonKey)); - await tester.pumpAndSettle(); - - expect(state.widget.animations, ["two"]); - verify(() => initMock.call(any())).called(2); - }); - - testWidgets('Changing state machines changes rive widget', - (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final riveFile = RiveFile.import(riveBytes); - - await tester.pumpWidget( - MaterialApp( - home: TestApp( - riveFile, - onInit: initMock.call, - ), - ), - ); - - final state = - tester.state(find.byType(RiveAnimation).first) as RiveAnimationState; - - expect(state.widget.stateMachines, ["one"]); - - await tester.tap(find.byKey(_changeStateMachineButtonKey)); - await tester.pumpAndSettle(); - - expect(state.widget.stateMachines, ["two"]); - verify(() => initMock.call(any())).called(2); - }); - - testWidgets('Changing controller changes rive widget', - (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final riveFile = RiveFile.import(riveBytes); - - await tester.pumpWidget( - MaterialApp( - home: TestApp( - riveFile, - onInit: initMock.call, - ), - ), - ); - - final state = - tester.state(find.byType(RiveAnimation).first) as RiveAnimationState; - - expect((state.widget.controllers.first as SimpleAnimation).animationName, - "one"); - - await tester.tap(find.byKey(_changeControllerButtonKey)); - await tester.pumpAndSettle(); - - expect((state.widget.controllers.first as SimpleAnimation).animationName, - "two"); - verify(() => initMock.call(any())).called(2); - }); - - testWidgets( - 'Changing fit|alignment|anitaliasing|placeholder does not call onInit', - (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final riveFile = RiveFile.import(riveBytes); - - await tester.pumpWidget( - MaterialApp( - home: TestApp( - riveFile, - onInit: initMock.call, - ), - ), - ); - - final state = - tester.state(find.byType(RiveAnimation).first) as RiveAnimationState; - - expect(state.widget.alignment, Alignment.topCenter); - expect(state.widget.fit, BoxFit.contain); - expect(state.widget.antialiasing, true); - expect(state.widget.placeHolder, _placeHolderWidgetOne); - - await tester.tap(find.byKey(_updateWidgetPropertiesButtonKey)); - await tester.pumpAndSettle(); - - expect(state.widget.alignment, Alignment.bottomCenter); - expect(state.widget.fit, BoxFit.fitHeight); - expect(state.widget.antialiasing, false); - expect(state.widget.placeHolder, _placeHolderWidgetTwo); - - // should not call onInit more than onces when updating these properties - verify(() => initMock.call(any())).called(1); - }); - - testWidgets('Events report', (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/event_on_listener.riv'); - final riveFile = RiveFile.import(riveBytes); - - var controller = StateMachineController.fromArtboard( - riveFile.mainArtboard, 'State Machine 1'); - expect(controller, isNotNull); - - Set receivedEvents = {}; - controller!.addEventListener((event) { - receivedEvents.add(event.name); - }); - - BoxFit fit = BoxFit.contain; - Alignment alignment = Alignment.topLeft; - bool anitaliasing = true; - Widget placeholder = _placeHolderWidgetOne; - - const riveKey = Key('riveWidgetKey'); - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: Center( - child: RiveAnimation.direct( - riveFile, - key: riveKey, - controllers: [controller], - fit: fit, - alignment: alignment, - antialiasing: anitaliasing, - placeHolder: placeholder, - ), - ), - ), - ), - ); - await tester.pumpAndSettle(); - await tester.tapAt(tester.getTopLeft(find.byKey(riveKey)) + - const Offset(343 * 1.2, 116 * 1.2)); - await tester.pumpAndSettle(); - - expect(receivedEvents, contains('Footstep')); - expect(receivedEvents, contains('Event 3')); - }); - - testWidgets('State & Transition events report', - (WidgetTester tester) async { - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/events_on_states.riv'); - final riveFile = RiveFile.import(riveBytes); - - var controller = StateMachineController.fromArtboard( - riveFile.mainArtboard, 'State Machine 1'); - expect(controller, isNotNull); - - Set receivedEvents = {}; - controller!.addEventListener((event) { - receivedEvents.add(event.name); - }); - - BoxFit fit = BoxFit.contain; - Alignment alignment = Alignment.topLeft; - bool anitaliasing = true; - Widget placeholder = _placeHolderWidgetOne; - - const riveKey = Key('riveWidgetKey'); - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: Center( - child: RiveAnimation.direct( - riveFile, - key: riveKey, - controllers: [controller], - fit: fit, - alignment: alignment, - antialiasing: anitaliasing, - placeHolder: placeholder, - ), - ), - ), - ), - ); - await tester.pump(Duration.zero); - - expect(receivedEvents, contains('First')); - }); - }); -} diff --git a/test/rive_file_test.dart b/test/rive_file_test.dart deleted file mode 100644 index 5d0e026..0000000 --- a/test/rive_file_test.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -void main() { - late RiveFile riveFile; - - setUp(() { - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - riveFile = RiveFile.import(riveBytes); - }); - - test('Rive files contain the correct number of artboards', () { - expect(riveFile.artboards.length, 2); - }); - - test('A default artboard is available in a Rive file', () { - // Create a dummy RiveFile - expect(riveFile.mainArtboard, isNotNull); - expect(riveFile.mainArtboard.name, 'Artboard 1'); - }); - - test('Artboards can be retrieved by name', () { - var artboard = riveFile.artboardByName('Artboard 1'); - expect(artboard, isNotNull); - expect(artboard!.name, 'Artboard 1'); - - artboard = riveFile.artboardByName('Artboard 2'); - expect(artboard, isNotNull); - expect(artboard!.name, 'Artboard 2'); - - artboard = riveFile.artboardByName('Nonexistant'); - expect(artboard, isNull); - }); -} diff --git a/test/rive_network_test.dart b/test/rive_network_test.dart deleted file mode 100644 index e27f868..0000000 --- a/test/rive_network_test.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rive/rive.dart'; - -import 'mocks/mocks.dart'; -import 'src/network.dart'; -import 'src/utils.dart'; - -void main() { - late MockHttpClient mockHttpClient; - - // ignore: close_sinks - late MockHttpClientRequest request; - - setUpAll(() { - registerFallbackValue(ArtboardFake()); - registerFallbackValue(Uri()); - registerFallbackValue(Stream.value([])); - // Build our app and trigger a frame. - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - final body = riveBytes.buffer.asUint8List(); - mockHttpClient = getMockHttpClient(); - - request = prepMockRequest(mockHttpClient, body); - }); - - testWidgets('Using the network, calls the http client without headers', - (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - await tester.pumpWidget( - const MaterialApp( - home: RiveAnimation.network('https://some.fake.url'), - ), - ); - }, createHttpClient: (_) => mockHttpClient); - - verify(() => mockHttpClient.openUrl(any(), any())).called(1); - verifyNever(() => request.headers.set(any(), any())); - }); - - testWidgets('Using the network, calls the http client with headers', - (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - await tester.pumpWidget( - const MaterialApp( - home: RiveAnimation.network('https://some.fake.url', headers: { - 'first': 'header', - 'second': 'header', - }), - ), - ); - }, createHttpClient: (_) => mockHttpClient); - - verify(() => mockHttpClient.openUrl(any(), any())).called(1); - verify(() => request.headers.set(any(), any())).called(2); - }); -} diff --git a/test/simple_animation_test.dart b/test/simple_animation_test.dart deleted file mode 100644 index 1031afe..0000000 --- a/test/simple_animation_test.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:rive/rive.dart'; - -import 'src/utils.dart'; - -void main() { - late RiveFile riveFile; - - setUp(() { - final riveBytes = loadFile('assets/rive-flutter-test-asset.riv'); - riveFile = RiveFile.import(riveBytes); - }); - - test('SimpleAnimation exposes mix', () { - expect(riveFile.mainArtboard.name, 'Artboard 1'); - - final firstController = - SimpleAnimation(riveFile.mainArtboard.animations.first.name); - expect(firstController.animationName, 'Animation 1'); - expect(firstController.mix, 1.0); - - firstController.mix = 0.5; - expect(firstController.mix, 0.5); - - firstController.mix = 2.5; - expect(firstController.mix, 1.0); - - firstController.mix = -1; - expect(firstController.mix, 0.0); - - final secondController = - SimpleAnimation(riveFile.mainArtboard.animations[1].name, mix: 0.8); - expect(secondController.animationName, 'Animation 2'); - expect(secondController.mix, 0.8); - }); - - test('SimpleAnimation exposes autoplay', () { - final firstController = SimpleAnimation( - riveFile.mainArtboard.animations.first.name, - ); - // Autoplay defaults to true - expect(firstController.autoplay, isTrue); - // Controller should be active after being added to an artboard - riveFile.mainArtboard.addController(firstController); - expect(firstController.isActive, isTrue); - - final secondController = SimpleAnimation( - riveFile.mainArtboard.animations.first.name, - autoplay: false, - ); - // Autoplay defaults to true - expect(secondController.autoplay, isFalse); - // Controller should be inactive after being added to an artboard - riveFile.mainArtboard.addController(secondController); - expect(secondController.isActive, isFalse); - }); -} diff --git a/test/src/network.dart b/test/src/network.dart deleted file mode 100644 index 651a325..0000000 --- a/test/src/network.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; - -class MockHttpClient extends Mock implements HttpClient {} - -class MockHttpClientRequest extends Mock implements HttpClientRequest {} - -// no clue but our tester seems unhappy? -class MockHttpClientResponse extends Mock implements HttpClientResponse { - @override - List get redirects => []; -} - -class MockHttpHeaders extends Mock implements HttpHeaders {} - -MockHttpClient getMockHttpClient() => MockHttpClient(); -MockHttpClientRequest prepMockRequest( - MockHttpClient httpClient, - Uint8List body, -) { - MockHttpClientRequest request = MockHttpClientRequest(); - - when(() => request.headers).thenReturn(MockHttpHeaders()); - - when(() => httpClient.openUrl(any(), any())).thenAnswer((invocation) { - final response = MockHttpClientResponse(); - when(request.close).thenAnswer((_) => Future.value(response)); - when(() => request.addStream(any())).thenAnswer((_) async => null); - when(() => response.headers).thenReturn(MockHttpHeaders()); - when(() => response.handleError(any(), test: any(named: 'test'))) - .thenAnswer((_) => Stream.value(body)); - when(() => response.statusCode).thenReturn(200); - when(() => response.reasonPhrase).thenReturn('OK'); - when(() => response.contentLength).thenReturn(body.length); - when(() => response.isRedirect).thenReturn(false); - when(() => response.persistentConnection).thenReturn(false); - return Future.value(request); - }); - return request; -} diff --git a/test/src/utils.dart b/test/src/utils.dart deleted file mode 100644 index 7cb53c4..0000000 --- a/test/src/utils.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:flutter/widgets.dart'; -import 'package:path/path.dart'; - -/// Loads a Rive file from the assets sub-folder -ByteData loadFile(String filename) { - final file = File( - './${Directory.current.path.endsWith('/test') ? '' : 'test/'}$filename'); - return ByteData.sublistView(file.readAsBytesSync()); -} - -/// Loads in all the files in the batch_rivs directory ('test/assets/batch_rivs') -List batchRiveFilesToTest() { - final directory = Directory('test/assets/batch_rivs'); - - final files = directory.listSync(); - return files - .map((e) { - try { - final file = e as File; - return FileTesterWrapper( - file: file, - fileName: basename(file.path), - ); - // ignore: avoid_catches_without_on_clauses - } catch (e, st) { - debugPrintStack(stackTrace: st); - throw Exception('Not a Rive file'); - } - }) - .where((element) => extension(element.fileName) == '.riv') - .toList(); -} - -class FileTesterWrapper { - final File file; - final String fileName; - - FileTesterWrapper({ - required this.file, - required this.fileName, - }); -}