Unreal Engine Archives Explorer
Go to file
Rob Trame fdc4b05b2c
feat(aup): migrate SpectrumAnalyzer and Timeline to Avalonia (#76)
* feat(aup): migrate SpectrumAnalyzer and Timeline to Avalonia — closes #21

* fix(aup): address all review findings and PR comments for Timeline and SpectrumAnalyzer

Timeline.cs:
- C1/PR#3: Wire ProgressLineBrushProperty to _progressLine.BorderBrush; add
  BorderThickness(0,0,1,0) to reproduce WPF right-edge cursor line
- M1: Restructure constructor to two-row Grid (Row0=20px ticks, Row1=* progress)
  with _positionLine spanning both rows — matches WPF PART_Timeline template
- M2: Fix default brush values to match WPF Resources.xaml style setters
  (TickBrush=#7F848E, TimeBrush=#DAE5F2, ProgressLineBrush=Brown,
  ProgressBrush=LinearGradientBrush #45B649→#DCE35B)
- Min1: Fix OnSourceEvent signature — remove erroneous nullable SourceEventArgs?
- PR#4: Add PositionProperty.Changed handler to keep _progressLine.Width in sync
  whenever Position is set by any means (not only via SourcePropertyChangedEvent)
- S1: Set ClipToBounds=true on root Grid and _lengthGrid

SpectrumAnalyzer.cs:
- Min2: Add FrequencyBarBorderThicknessProperty.Changed handler → CreateBars()
- Min3/PR#2: Fix double CreateBars() on out-of-range FrequencyBarCount by using
  early returns instead of fall-through after coerce assignment
- PR#1: Guard UpdateSpectrum when _bars is empty; trigger CreateBars() from
  OnSourceEvent(Loading) so bars exist before first FftData event arrives

* fix(aup): second-pass review fixes for Timeline and SpectrumAnalyzer

Timeline.cs:
- M2: Reorder root.Children so _positionLine is added last, ensuring the
  mouse-cursor indicator renders on top of the advancing _progressLine fill
- Min1: Remove _bottomBorder shared field; instantiate Border inline inside
  UpdateTimeline() like all other tick elements, eliminating shared-state risk
- S1: Wrap TickBrush/TimeBrush AddClassHandler callbacks in
  Dispatcher.UIThread.Post to be consistent with BoundsProperty.Changed

SpectrumAnalyzer.cs:
- M1: Reset _bars to Array.Empty<Border>() inside SilenceBars() so the
  UpdateSpectrum _bars.Length==0 guard correctly blocks stale writes after
  bars are cleared
- Min2: Add AddClassHandler for FrequencyBarBrush, FrequencyBarBorderBrush,
  and FrequencyBarCornerRadius → CreateBars() to keep runtime changes in sync

* fix(aup): third-pass review fixes for Timeline and SpectrumAnalyzer

SpectrumAnalyzer.cs:
- M1/PR#5: Snapshot _bars into a local 'bars' at the top of UpdateSpectrum so
  the dispatched UI-thread closure and all loop bounds use the same consistent
  array reference; prevents IndexOutOfRangeException when SilenceBars() or a
  FrequencyBarCount change replaces _bars between the guard check and the
  Background-priority closure
- M2: Remove Dispatcher.UIThread.Invoke() wrapper around SpectrumScalingStrategy
  read — Avalonia 11 StyledProperty value reads are thread-safe for value types;
  eliminates synchronous audio-thread→UI-thread roundtrip (deadlock risk + perf)

Timeline.cs:
- M3: Extend BoundsProperty.Changed handler to also recompute _progressLine.Width
  using the new Bounds.Width so the progress indicator stays proportionally
  correct after window resize
- PR#6: Clamp seek ratio to [0.0, 1.0] before passing to Source.SkipTo() to
  guard against pointer positions marginally outside the control bounds
2026-03-15 16:28:26 -06:00
.github chore: update identity, branding, and CI for FModel Linux fork (#69) 2026-03-12 11:13:00 -06:00
.vscode Set up dev env 2026-03-11 15:51:34 -06:00
CUE4Parse@06fbf1aced chore: point CUE4Parse submodule at r6e/CUE4Parse-Linux (#66) 2026-03-11 19:49:17 -06:00
FModel feat(aup): migrate SpectrumAnalyzer and Timeline to Avalonia (#76) 2026-03-15 16:28:26 -06:00
.editorconfig chore: update identity, branding, and CI for FModel Linux fork (#69) 2026-03-12 11:13:00 -06:00
.gitignore Finish setting up env 2026-03-11 17:28:01 -06:00
.gitmodules chore: point CUE4Parse submodule at r6e/CUE4Parse-Linux (#66) 2026-03-11 19:49:17 -06:00
LICENSE Re-add GPL-3 license 2021-05-22 16:33:08 -04:00
NOTICE chore: update identity, branding, and CI for FModel Linux fork (#69) 2026-03-12 11:13:00 -06:00
README.md chore: update identity, branding, and CI for FModel Linux fork (#69) 2026-03-12 11:13:00 -06:00

FModel Linux — Unreal Engine Archives Explorer for Linux

CI Status Latest


This is an unofficial Linux port of FModel, originally created by Asval (4sval) and contributors. It is not affiliated with or endorsed by the upstream project or its maintainers. Please do not report Linux-port-specific issues upstream.

Description

FModel Linux is a Linux port of FModel — an archive explorer for Unreal Engine games. It uses CUE4Parse as its core parsing library, providing robust support for the latest UE4 and UE5 archive formats, along with a comprehensive set of tools for previewing and converting game packages.

This fork replaces the Windows-only WPF UI stack with Avalonia UI and removes other Windows-specific dependencies to enable native Linux support. It is maintained by r6e.

Installation

Installation instructions for the Linux port are available in the project wiki (work in progress).

For the upstream Windows release, refer to the official FModel installation guide.

Supporting the Upstream Project

This fork does not accept donations. If you find FModel valuable, please consider supporting the original FModel project and its contributors.

License

FModel Linux is a derivative work licensed under GPL-3. The original FModel project is copyright © Asval and FModel contributors. Licenses of third-party libraries used are listed in NOTICE.