* Core - Fix removing dynamic children and checking which properties are in use
- DataModel.RemoveDynamicChild compared the value of each child with the
child that was passed in, so it never removed anything.
- IsPropertyInUse with includeChildren matched paths by their start, so
a path to "Integers" made "Integer" count as in use. Children are now
matched on what follows a dot.
* Core - Fix data model paths around saving, removed children and stored types
- The constructors saved the path before setting it up, while it was
still invalid, so a new path stored nothing and didn't follow its data
model leaving and returning to the store until it was saved.
- Removing the dynamic child a path points to left the path valid and
reading a default value, it now becomes invalid like when the child
was never there.
- The stored type of a path is now also looked up in all loaded
assemblies, Type.GetType only found it in Artemis.Core and the .NET
libraries, not in plugins or SkiaSharp.
* Core - Only let event conditions react to what happens after they start watching
- A trigger from before the condition watched its event, for example
long before the profile was activated, counted as new and played the
element once. Triggers now count from the moment the condition starts
watching its path.
- A condition on a plain value treated the first value it saw as a
change and played the element on the first frame. The first value is
now taken as the starting value.
* Core - Keep the name of renamed layer effects when loading
BaseLayerEffect.Load checked HasBeenRenamed before reading it from the entity, so renamed effects always fell back to the descriptor's display name.
* Core - Apply layer effect filters once on layers
Layer.DelegateRendering composited the layer with the pre-processed paint and also handed that paint to the brush, so color and image filters of effects applied to the brush output and again when compositing. The brush now gets a copy of the paint without those filters, like folders which apply them once.
* Core - Disable folders that get suspended while enabled
Layer.Update disables a suspended layer but Folder.Update only disabled a folder once its timeline finished, so a folder suspended outside of the editor kept rendering its children.
* Core - Update device LEDs when rotating or scaling a device
The Rotation and Scale setters only updated the RGB.NET device, the Artemis LED rectangles and the device path kept their old positions and DeviceUpdated wasn't raised until X or Y was set.
* Core - Correct the docs of the Layer and Folder constructors
They claimed the new element adds itself to the child collection of the parent, it doesn't and callers rely on adding it themselves.
* Core - Apply layer opacity once for brushes that draw with the paint
Brushes drawing with a shader or image keep the alpha of the paint they are given, so the layer opacity and opacity effects applied to the brush output and again when compositing, 50% opacity rendered at 25%. The brush now gets an opaque paint, per-LED brushes already overrode the color. The solid color test brush now draws with a shader like the real solid brush so the opacity tests cover this.
* Tests - Describe expected faded colors by their opacity
Adds an AtOpacity helper so assertions read as red at 50% over black instead of a hand-computed 127, and uses it for layer opacity, opacity effects, folder fades, the profile fade and semi-transparent drawing.
* Core - Wrap timelines around by how far they went past the main segment
Repeating timelines wrapped around by the frame time rather than by how
far they went past the end of the main segment, so wrapping could be off
by up to a frame. A timeline that was already past the end, like the
finished timeline new layers start with, still starts the main segment
over.
* Tests - Mention the defaults the timeline wrap-around tests depend on
Sample each LED from its unsnapped absolute boundary instead of the
render-grid-aligned AbsoluteRectangle, ensuring at least one pixel and
clamping to the texture. Also apply the saved render scale at startup.
Refactors plugin handling for improved reliability and user experience.
- Removes built-in plugin copying, migrating to workshop-based installation
- Introduces a dedicated service for plugin interactions (enabling, disabling, removal, settings)
- Simplifies plugin enabling/disabling logic in the UI, centralizing the logic
Core - Modifies the Artemis data folder path based on the build configuration.
Plugins - Adds a confirmation dialog to prompt the user to restart if a plugin requires admin rights.
Startup wizard - Updates the installation progress bar in the startup wizard.
Workshop - Changes category retrieval to be based on EntryType.
Workshop - Adds the ability to include default entries when searching the workshop.