CodeIX.PortableUI.Effects 0.4.0-alpha.10

This is a prerelease version of CodeIX.PortableUI.Effects.
dotnet add package CodeIX.PortableUI.Effects --version 0.4.0-alpha.10
                    
NuGet\Install-Package CodeIX.PortableUI.Effects -Version 0.4.0-alpha.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeIX.PortableUI.Effects" Version="0.4.0-alpha.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CodeIX.PortableUI.Effects" Version="0.4.0-alpha.10" />
                    
Directory.Packages.props
<PackageReference Include="CodeIX.PortableUI.Effects" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CodeIX.PortableUI.Effects --version 0.4.0-alpha.10
                    
#r "nuget: CodeIX.PortableUI.Effects, 0.4.0-alpha.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CodeIX.PortableUI.Effects@0.4.0-alpha.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CodeIX.PortableUI.Effects&version=0.4.0-alpha.10&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CodeIX.PortableUI.Effects&version=0.4.0-alpha.10&prerelease
                    
Install as a Cake Tool

MonoGame.PortableUI

NuGet CI Publish NuGet Release source License Conderis

MonoGame.PortableUI is a lightweight code-first UI layer for MonoGame. The modernized package line targets .NET 10 and multi-targets net10.0 (MonoGame DesktopGL) and net10.0-android (MonoGame.Framework.Android) so the same library serves desktop and Android clients.

This branch removed the legacy PCL, Xamarin/PCL and WindowsDX project set; Android has now been reintroduced on the current MonoGame + .NET Android SDK toolchain (see samples/MonoGame.PortableUI.Demo.Android). DesktopGL remains the primary verified demo platform; iOS/other platforms can follow the same multi-targeting pattern.

Quick Start

dotnet tool restore
dotnet restore
dotnet build
dotnet test
dotnet run --project samples/MonoGame.PortableUI.Demo

Run the layout benchmarks manually when working on performance:

dotnet run --project benchmarks/MonoGame.PortableUI.Benchmarks --configuration Release -- --filter *Layout*

To edit demo content:

dotnet mgcb-editor samples/MonoGame.PortableUI.Demo/Content/Content.mgcb

All themes below ship in the CodeIX.PortableUI.Themes add-on package (namespace MonoGame.PortableUI.Themes) (PortableThemes.All); the core library works completely without it. Each theme lives in its own file under src/MonoGame.PortableUI.Themes/Themes/ and depends only on the core package - plus CodeIX.PortableUI.Effects for the ten themes with post effects or glass - so you can either reference the NuGet package (quick start) or copy a single theme file into your project and customize it — see Themes/README.md.

Optional effects: shader visuals live in the CodeIX.PortableUI.Effects package (namespaces unchanged): post effects (ScanlinePostEffect, CrtBarrelPostEffect, VignettePostEffect, FilmGrainPostEffect, BloomPostEffect, DotMatrixPostEffect), backdrop blur and glass brushes (FrostedGlassBrush, AcrylicBrush, LiquidGlassBrush, ShimmerGlassBrush). Referencing it is enough - it installs itself when first used (PortableEffects.Install() does it explicitly). Without it the UI draws flat and needs no shaders.

Fonts cannot ship pre-built from NuGet, so the package carries them as content files. Three steps in your game:

  1. Copy the files from the package's ThemeContent/Fonts/ into your Content/Fonts/ folder (.ttf + .spritefont + licenses).
  2. Paste the blocks from ThemeContent/themes-fonts.mgcb-snippet.txt into your Content.mgcb.
  3. Call FontManager.LoadFonts(this, PortableThemes.FontNames.ToArray()) at startup.

Themes whose fonts are not built still render correctly with your default font (FontManager logs one warning per missing family). Details in the package's ThemeContent/README.md.

Regenerate the gallery images from the demo:

dotnet run --project samples/MonoGame.PortableUI.Demo -- --screenshot docs/themes --screenshot-screen controls

The default theme shows the library's built-in styling when no theme is applied; the demo theme is the demo's own DemoTheme.cs, a commented template for writing your own theme with just the core package:

Default (no theme) Demo Theme (template)
Default Demo Theme
C64 Game Boy NES Mac 1-bit
C64 Game Boy NES Mac 1-bit
DOS Norton Phosphor Amber
DOS Norton Phosphor Amber
Amiga Windows 95 Mac OS 9 NeXTSTEP
Amiga Windows 95 Mac OS 9 NeXTSTEP
BeOS Luna Aqua Aero
BeOS Luna Aqua Aero
Metro Fluent Material Frosted Glass
Metro Fluent Material Frosted Glass
Liquid Glass Aurora Terminal Studio
Liquid Glass Aurora Terminal Studio
Cyberpunk Vaporwave Nord Dracula
Cyberpunk Vaporwave Nord Dracula
Solarized Light Solarized Dark Gruvbox Parchment
Solarized Light Solarized Dark Gruvbox Parchment
LCARS E-Ink Neumorphism Brutalist
LCARS E-Ink Neumorphism Brutalist

Game UI themes:

Sci-Fi HUD Dark Fantasy RPG Cozy Casual
Sci-Fi HUD Dark Fantasy RPG Cozy Casual
Tactical Ops Phantom Strike
Tactical Ops Phantom Strike

Small API Examples

Initialize the screen engine from your Game. By default, PortableUI tracks the MonoGame viewport and keeps the layout in sync with the window:

private ScreenEngine? _screenEngine;

protected override void Initialize()
{
    _screenEngine = ScreenEngine.Initialize(this);
    base.Initialize();
}

protected override void LoadContent()
{
    FontManager.LoadFonts(this, "Segoe", "default");
    _screenEngine?.NavigateToScreen(new MainScreen());
}

If your UI uses a virtual coordinate space instead of the actual backbuffer size, switch to manual sizing:

protected override void Initialize()
{
    _screenEngine = ScreenEngine.Initialize(this, new ScreenEngineOptions
    {
        ScreenSizeMode = ScreenSizeMode.Manual
    });
    _screenEngine.SetScreenSize(1280, 720);
    base.Initialize();
}

Desktop hosts can opt into system clipboard support through the engine options:

_screenEngine = ScreenEngine.Initialize(this, new ScreenEngineOptions
{
    ClipboardService = OperatingSystem.IsWindows() ? new WindowsClipboardService() : NullClipboardService.Instance
});

Build screens with code-first controls:

public sealed class MainScreen : Screen
{
    public MainScreen()
    {
        BackgroundBrush = Color.Black;

        var layout = new Grid
        {
            Margin = 16,
            RowDefinitions =
            {
                new RowDefinition { Height = GridLength.Auto },
                new RowDefinition()
            }
        };

        layout.AddChild(new TextBlock
        {
            Text = "Inventory",
            TextColor = Color.White,
            TextSize = 18
        });

        var stack = new StackPanel { Orientation = Orientation.Vertical, Margin = new Thickness(0, 12) };
        var save = new TextButton("Save") { Height = 40, BackgroundBrush = Color.White };
        save.Click += (_, _) => ScreenEngine?.NavigateToScreen(new DetailsScreen());
        stack.AddChild(save);

        layout.AddChild(stack, row: 1);
        Content = layout;
    }
}

Handle text input and selection events:

var textBox = new TextBox { HintText = "Player name", MaxLength = 24, Height = 36 };
textBox.TextChanged += (_, args) => Console.WriteLine(args.NewText);
textBox.SelectAll();

var password = new TextBox { HintText = "Password", PasswordChar = '*', Height = 36 };

var notes = new TextBox { HintText = "Notes", IsMultiline = true, Height = 96 };
notes.EnterPressed += (_, _) => Console.WriteLine("Submitted with Ctrl+Enter");

var combo = new ComboBox { Height = 36 };
combo.Items.Add("Compact");
combo.Items.Add("Touch");
combo.SelectionChanged += (_, _) => Console.WriteLine(combo.SelectedItem);
combo.SelectedIndex = 0;

// Sortable, scrollable table with typed columns (Auto/Absolute/star widths),
// click-to-sort headers, draggable column edges, selection and cell templates.
var grid = new DataGrid { Height = 240 };
grid.Columns.Add(new DataGridColumn { Header = "Name", CellText = i => ((Ship)i).Name, SortKey = i => ((Ship)i).Name });
grid.Columns.Add(new DataGridColumn
{
    Header = "Price",
    Width = new GridLength(90, GridLengthUnit.Absolute),
    CellAlignment = TextAlignment.Right,
    CellText = i => ((Ship)i).Price.ToString("N2"),
    SortKey = i => ((Ship)i).Price
});
grid.Items.AddRange(ships);
grid.Refresh();
grid.SortBy(grid.Columns[0], ascending: true);
grid.SelectionChanged += (_, _) => Console.WriteLine(grid.SelectedItem);

Projects

  • src/MonoGame.PortableUI contains the library (multi-targeted net10.0 + net10.0-android).
  • samples/MonoGame.PortableUI.Demo contains the DesktopGL demo and MGCB content.
  • samples/MonoGame.PortableUI.Demo.Android contains a minimal Android host (activity + manifest) that runs the same controls on device/emulator. Android hosts must pin the back buffer to the real display size (PreferredBackBufferWidth/Height from Resources.DisplayMetrics); otherwise MonoGame's density-scaled default back buffer diverges from the GL surface and clips text drawn in content-tight controls (buttons, list rows). See AndroidDemoGame.
  • benchmarks/MonoGame.PortableUI.Benchmarks contains BenchmarkDotNet layout and visual-tree baselines.
  • tests/MonoGame.PortableUI.Tests contains windowless regression tests for layout, state, input and composite controls.
  • docs/issues.md maps the historical GitHub issue backlog to fixes, tests or obsolete platform notes.

Fonts

The demo bundles only free, open-licensed fonts (SIL OFL 1.1, CC BY-SA 4.0 — all usable in commercial projects; no proprietary system fonts are redistributed). The full per-font list with authors, licenses and sources lives in docs/FONTS.md. The MIT license covers the MonoGame.PortableUI source code only; the bundled fonts keep their own licenses.

Packaging

The package ID remains MonoGame.PortableUI. Packaging is SDK-based and uses modern NuGet metadata:

  • PackageLicenseExpression=MIT
  • PackageReadmeFile=README.md
  • repository metadata and SourceLink
  • symbol packages via .snupkg

The project file uses 0.0.0-local as a local fallback. Published package versions are derived from release tags such as v0.2.0-alpha.1.

Release Flow

master is the release source; releases are tags on master.

  1. Merge changes into master.
  2. Create a tag such as v0.2.0-alpha.2.
  3. GitHub Actions derives the package version from the tag, then builds, tests and packs.
  4. The NuGet publish workflow uses Trusted Publishing for tags.
  5. NuGet.org still needs the one-time trusted publisher setup for this repository, release-nuget.yml workflow file and NuGet environment.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on CodeIX.PortableUI.Effects:

Package Downloads
CodeIX.PortableUI.Themes

Theme catalog add-on for MonoGame.PortableUI. MonoGame.PortableUI works completely without this package; each theme lives in its own file so it can be copied into a project and customized.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.0-alpha.10 59 10/20/2026
0.4.0-alpha.9 57 10/20/2026
0.4.0-alpha.8 62 10/14/2026
0.4.0-alpha.7 61 10/14/2026
0.4.0-alpha.6 64 10/13/2026
0.4.0-alpha.5 64 10/11/2026
0.4.0-alpha.4 64 10/6/2026
0.4.0-alpha.3 64 10/6/2026
0.4.0-alpha.2 65 10/6/2026
0.4.0-alpha.1 65 10/5/2026