Commit Graph
2927 Commits
Author SHA1 Message Date
RobertBeekman 83cf6da830 Core - Fix profile service, storage and device bugs found by the tests (#912)
* Core - Fix default headset layouts and the z-index of devices placed by the auto-arrange fallback

- Headsets with 2 or 4 LEDs get their default layout, the files are named "... LEDs headset.xml"
- Devices placed by the auto-arrange fallback get the z-index of their type

* Core - Fall back to the default value passed to GetSetting when a stored setting can't be read

* Core - Fix storing, cloning and migrating profiles

- New profiles are stored at the current migration version, so they're no longer migrated on every start and can be duplicated right away
- A category created at the top is listed first right away, so its profiles render on top
- CloneProfileConfiguration makes a copy of the stored data, saving a clone stores its profile through the original
- Importing a profile raises ProfileAdded
- A profile configuration that isn't valid JSON is logged and skipped instead of stopping all migrations
- A stored profile without a version is migrated from version 0, like an imported one
- ProfileCategoryRepository.IsUnique returns true when the name is free
- M0001 and M0004 leave a missing node type or storage out instead of writing null
- M0003 also unwraps a list that is an item of another list
2026-10-24 16:19:23 +02:00
RobertBeekman 295038f338 Profile editor - Fix undo and editor service bugs found by the tests (#913)
* Profile editor - Fix undoing profile editor commands

- Undoing a change to an existing keyframe's value restores the value instead of deleting the keyframe
- Undoing "remove effect" puts the effect back in its place instead of below the next one
- Undoing "toggle keyframes" restores what it was before
- Undoing a brush change on a layer that had no brush removes the brush again, using the new Layer.RemoveLayerBrush
- Undoing "add element" disables the element again
- Undoing an event path change back to no path goes back to an event start node, like a new condition
- MoveProfileElement says "Move folder" for folders
- UpdateLayerProperty without a time no longer calls itself "Add ... keyframe"

* Profile editor - Fix auto-saving, failing commands, suspended editing and smaller editor issues

- A failed auto-save no longer stops auto-saving for the rest of the session
- A failing command is no longer also reported to ReactiveUI as unhandled, on top of the error dialog
- Resuming editing applies the editor's time again right away
- Nothing is focused while editing is suspended
- A layer created on another layer gets a name that isn't in use next to it
- CanUndo and CanRedo start out false, so new subscribers know the state right away
- An empty command scope doesn't add an undo step
- New subscribers to History get the current history once
- Expanding the keyframe selection with an already selected keyframe doesn't add it twice
- Snapping can snap to a snap time of zero
2026-10-24 16:17:05 +02:00
RobertBeekman 63186ee06d Core - Fix color gradient and utility bugs found by the tests (#914)
* Profile adaption - Fix arrow keys section including Page Down

- The arrow keys keyboard section now starts at Arrow Up instead of the key before it (Page Down)
- Updated the keyboard section test to expect only the four arrow keys

* Color quantizer - Let fully saturated colors be vibrant and grays be muted

- The saturation limits of the color types are now inclusive, so 100% saturated colors count as vibrant and 0% saturated colors count as muted
- The lightness limits stay exclusive so pure black and white are still left out
- Updated the quantizer tests to match

* Color gradients - Fix stop placement, seamless toggling and list events

- Stops on an occupied position now move down 0.001 instead of 0.002 (rounding error in the distance check)
- Flip, rotate, spread and interpolate move all stops together, so a stop can take a position another stop is leaving
- Spreading or randomizing a single stop puts it at 0 instead of NaN
- ToggleSeamless does nothing on an empty gradient and caps stretched stops at 1 instead of 100
- RemoveAt reports the removed stop and its index
- Insert links the stop like Add does and raises the add before the move
- Remove, RemoveAt, Clear and replacing a stop through the indexer unlink and stop listening to the actual removed stop
- Copying from a list of stops sorts them by position
- Obsolete GetPositionsArray no longer skips the seamless positions, obsolete GetColor picks the right colors after a repeat
- Updated the gradient tests to match

* Core - Fix small color, enum, string and type utility bugs

- Darken keeps the alpha of the color
- GetAllValuesAndDescriptions(Type) uses the [Description] attribute like the generic version
- UrlFriendly cuts titles at 80 characters instead of 81
- RemapInternationalCharToAscii knows both cases of r, l, d, thorn, sharp s, h and j with accents
- IsGenericType returns false instead of throwing when the base type is not generic
- IsCastableFrom also finds conversion operators declared on the target type
- GetDisplayName keeps the brackets of array types when humanizing
- Updated the utility tests to match
2026-10-24 15:53:52 +02:00
RobertBeekman 6df81b19b1 Core - Fix data model and event condition bugs found by the tests (#910)
* 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.
2026-10-20 13:46:06 +02:00
RobertBeekman a25d0f0c9c Core - Fix profile rendering and timeline bugs found by the tests (#909)
* 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
2026-10-20 13:30:04 +02:00
RobertBeekman 504845c7d2 Tests - Add Artemis.Core and profile editor test suites (#907) 2026-10-20 09:22:10 +02:00
RobertBeekman 6e7fae16d2 Merge pull request #903 from senposage/codex/close-process-query-handles
Close process query handles
2026-10-17 21:12:15 +02:00
RobertBeekman 163f713b31 CI - Allow pull requests to master from any branch
Remove the workflow that only allowed pull requests to master from development, which no longer exists.
2026-10-17 21:10:33 +02:00
RobertBeekman 65409c4378 Merge pull request #906 from Artemis-RGB/feature/small-led-render-scale
Keep small LEDs addressable at reduced render scales and reduce texture readback allocations
2026-10-17 21:02:23 +02:00
RobertBeekman ce5fa00aed Core - Stop sampling SKTexture after disposal 2026-10-17 20:38:30 +02:00
rjc862003 02dd7df5dd Reduce per-frame texture readback allocations 2026-10-17 20:38:30 +02:00
RobertBeekman e1357f1bf0 Core - Keep small LEDs addressable at reduced render scales
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.
2026-10-17 20:38:30 +02:00
rjc862003 2b29c15cf1 Close process query handles 2026-10-01 23:49:22 -04:00
Robert Beekman df9ab302ca #828 - Remove mention of open-source 2026-09-26 22:38:37 +02:00
Robert 46511022d6 Merge branch 'development' 2026-01-01 16:20:55 +01:00
Robert 961e8e709a Menu - Don't collapse workshop menu item when navigating to it from a submenu item 2026-01-01 16:20:48 +01:00
Robert 14c301a37e Visual tweaks 2025-12-31 12:38:53 +01:00
Robert 559434630d Show multiple recent releases per entry if available 2025-12-31 09:44:14 +01:00
Robert 562049681f Workshop - Recently updated tab 2025-12-30 10:02:16 +01:00
Robert 74d5480d7b Surface editor - Show model instead of device name
Settings - Add link to plugin's workshop page
Workshop library - Recently updated tab (WIP)
2025-12-29 12:30:24 +01:00
Robert 0823de45a4 Merge branch 'feature/docs-in-docker' into development 2025-12-29 12:02:57 +01:00
Robert cb1bc5daf7 Remove old CI stuff 2025-12-29 12:02:46 +01:00
Robert 7043505ca8 Add Dockerfile 2025-12-29 11:42:32 +01:00
Robert f61884806a Filter out storage 2025-12-29 11:17:53 +01:00
Robert 487f9ff8b3 Merge branch 'development' 2025-12-27 21:42:25 +01:00
Robert 9bc4eca7f9 UI - Fix back-button not always working (I blame you, Avalonia)
Workshop - Add a EF migration to fix entry types based on metadata
2025-12-27 21:42:09 +01:00
Robert Beekman 36761509e2 Merge branch 'master' into development 2025-12-24 14:04:57 +01:00
Robert efd893c209 Workshop - Fix misalignment in EntryTypes causing plugins to not load
Core - Downgrade SkiaSharp back to what Avalonia likes, 2.88.9
2025-12-23 20:53:39 +01:00
Robert 7985cde6a3 Workshop - Update workshop schema 2025-12-23 08:36:13 +01:00
Robert d063f13ca5 Hotfix - Auto-enable plugins after updating them 2025-12-23 07:44:52 +01:00
Robert 7c7d91eda9 Hotfix workshop auto-update 2025-12-22 20:47:26 +01:00
Robert 4b58485956 Fix version number and .net version 2025-12-22 20:20:54 +01:00
Robert fb100eb9ad Merge branch 'development' 2025-12-22 20:13:58 +01:00
Robert 6bf5a11108 Workshop - Improved workshop entry compatibility handling
Workshop - Added minimum Artemis version to releases
2025-12-22 20:13:49 +01:00
Robert 86f2426f37 Core - Remove API versioning, we have MinimumVersion to achieve the same thing 2025-12-19 23:11:27 +01:00
Robert e2cb73e327 Don't log so much Avalonia stuff even when debugging tyvm 2025-12-16 22:37:10 +01:00
Robert 55dca6cebb Upgrade packages
Update namespaces
Clean up unused imports
Replace Avalonia.ReactiveUI with ReactiveUI.Avalonia 🙄
2025-12-16 22:28:16 +01:00
Robert fdc02ec581 Merge branch 'development' 2025-12-13 17:11:03 +01:00
Robert 8e4a430e19 Workshop - Fix default sorting being blank
Sidebar - Allow right-clicking a profile to open the menu without opening the profile
Profile editor - Fix editor not stopping to focus the profile
2025-12-13 16:19:16 +01:00
Robert db59b5dd55 Merge branch 'development' 2025-12-12 18:35:18 +01:00
Robert 0eb2c3a3b2 Remove plugins from build 2025-12-12 18:32:10 +01:00
Robert 5d7fb777ce Merge branch 'development' 2025-12-12 18:29:43 +01:00
Robert ce4885f06d Merge branch 'feature/default-entries' into development 2025-12-12 18:29:35 +01:00
Robert bda247d3c3 Streamlines plugin management and installation
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
2025-12-12 18:29:24 +01:00
Robert 7f5b677cc3 Capture view model references in WhenActivated of views to avoid NRE 2025-12-11 23:58:15 +01:00
Robert 5609065974 Workshop - Add --alt-login-callback startup argument
UI - Rounded corners on profile icons
2025-12-11 23:54:50 +01:00
Robert 06c5294e88 Profile editor - Fix race condition causing the editor to fail to activate on suspended profiles
Surface editor - Implemented left-handed preset
2025-12-11 22:55:31 +01:00
Robert 108cbaae3d Replace profile-from-workshop-dialog with a page 2025-12-10 23:06:14 +01:00
Robert 638dbd11eb Revert regrets 2025-12-09 20:57:51 +01:00
Robert 2ad5f974e8 Think better of move 2025-12-09 20:55:50 +01:00