Unreal Engine Archives Explorer
Go to file
Rob Trame bc74c35dc1
feat(P2-005): migrate CustomRichTextBox (FLogger) and CustomScrollViewer to Avalonia (#72)
* feat(P2-005): migrate CustomRichTextBox (FLogger) and CustomScrollViewer to Avalonia (#18)

CustomRichTextBox:
- Replace WPF RichTextBox / FlowDocument / Hyperlink with AvaloniaEdit.TextEditor
- FLogger converted to static class; removes ITextFormatter / BrushConverter / _previous offset
- Per-segment colouring implemented via LogColorizer : DocumentColorizingTransformer
- LogSegment record tracks offset, length, IBrush, and optional link URL
- Append/Text/Link methods marshal to Dispatcher.UIThread.InvokeAsync (DispatcherPriority.Background)
- Link click handler stubs TODO(P4-001) (OS file manager integration)
- GetBrush() caches parsed Color.Parse(hexString) -> SolidColorBrush per hex string

CustomScrollViewer:
- Replace WPF DependencyProperty / FrameworkPropertyMetadata with Avalonia AttachedProperty<double>
- Changed from ScrollViewer subclass to static helper class
- VerticalOffsetProperty uses AvaloniaProperty.RegisterAttached + Changed.AddClassHandler
- Offset set via ScrollViewer.Offset.WithY(); two-way sync via ScrollChanged event
- Formatter-clean GetVerticalOffset/SetVerticalOffset accessors added

Package updates (FModel.csproj):
- Replace deprecated AvaloniaEdit 0.10.12 with Avalonia.AvaloniaEdit 11.3.0
  (old package unlisted on NuGet; new namespace is AvaloniaEdit.* not ICSharpCode.AvalonEdit.*)
- Serilog 4.3.0 -> 4.3.1 (patch)

Closes #18

* fix(P2-005): address post-review findings in CustomRichTextBox and CustomScrollViewer

CustomScrollViewer:
- Register VerticalOffsetProperty with BindingMode.TwoWay so bare {Binding ScrollPosition}
  in XAML preserves tab scroll-position across tab switches (matches WPF BindsTwoWayByDefault)
- Replace null! with null in _subscribed.Add (no nullable context; operator was semantic no-op)

CustomRichTextBox:
- Move ScrollToEnd() call to end of Append dispatch lambda so it fires once per log event
  rather than once per Text()/Link() segment (n calls per exception → 1 call per Append)
- Replace dead guard Document.LineCount > 0 with Document.TextLength > 0 in ScrollToEnd()
  (TextDocument always has LineCount >= 1; the old guard was never false)

* fix(P2-005): fix CustomScrollViewer subscription and CWT null marker

- Move ScrollChanged subscription before the epsilon guard so viewers
  starting at offset 0.0 still subscribe on their first property set;
  previously the early return prevented subscription entirely in the
  common initial case where bound value == viewer.Offset.Y == 0.0
- Replace null with a static readonly _marker object as the
  ConditionalWeakTable value; null is technically accepted on .NET 8
  but a non-null sentinel is clearer and avoids platform ambiguity
2026-03-14 16:47:43 -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(P2-005): migrate CustomRichTextBox (FLogger) and CustomScrollViewer to Avalonia (#72) 2026-03-14 16:47:43 -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.