Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a583b4a
Migrate from WinForms to Avalonia UI
TastelessVoid Nov 12, 2025
e2ab03c
Fixed formatting
TastelessVoid Nov 12, 2025
0620bb0
Delete old WinForms files since parity has been ensured.
TastelessVoid Nov 12, 2025
1e7c7d9
Switch to system color dialog, removed unnecessary comments
TastelessVoid Nov 12, 2025
08d7607
Adjusted Seed Output tab and fixed build.sh scripting.
TastelessVoid Nov 12, 2025
9f50ff6
Fix patching & saving ROM
TastelessVoid Nov 12, 2025
736f5ee
Hide seed output until randomized, properly parse custom tabs and fix…
TastelessVoid Nov 13, 2025
869914f
Fixed compact UI checkbox not working and the default state not being…
TastelessVoid Nov 13, 2025
b7b8b81
Made several MenuItems in the dock checkboxes instead to properly ref…
TastelessVoid Nov 13, 2025
e5fe523
Minor UI adjustments and fixed custom logic/yaml/etc. storage from pr…
TastelessVoid Nov 13, 2025
a252dd1
Fixed missing resource folder, why did git not add that?
TastelessVoid Nov 15, 2025
559b4dc
Aligned MenuItems with CheckBox items
TastelessVoid Nov 15, 2025
6e334dc
Compact the UI to not be huge in comparison to WinForms
TastelessVoid Nov 15, 2025
0fb1717
UI adjustments requested by Catobat
TastelessVoid Nov 15, 2025
7d12efd
Dropdown adjustments
TastelessVoid Nov 15, 2025
20eb3f7
Re-Compact UI because I accidentally undid it
TastelessVoid Nov 15, 2025
298fbe2
Added dark theme, fixed dropdown issues, minor adjustments
TastelessVoid Nov 15, 2025
5a70e7e
Removed hardcoded testing values and made dynamic tabs less fragile
TastelessVoid Nov 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Build Tools/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
# Simple cross-platform build script for Avalonia UI and CLI
# Usage: ./build.sh <output-dir>

if [[ $# -lt 1 ]]; then
echo "Usage: $0 <output-dir>"
exit 1
fi
OUTDIR="$1"
SOLUTION_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$SOLUTION_DIR"

# Build UI (Avalonia) self-contained single-file (no trimming for compatibility)
publish_ui(){
local rid="$1"
local dest="$OUTDIR/UI/$rid"
dotnet publish MinishCapRandomizerUI.Avalonia/MinishCapRandomizerUI.Avalonia.csproj -c Release -r "$rid" \
-p:PublishSingleFile=true -p:SelfContained=true \
-p:EnableCompressionInSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -o "$dest"
}

# Build CLI
publish_cli(){
local rid="$1"
local dest="$OUTDIR/CLI/$rid"
dotnet publish MinishCapRandomizerCLI/MinishCapRandomizerCLI.csproj -c Release -r "$rid" \
-p:PublishSingleFile=true -p:SelfContained=true -o "$dest"
}

for rid in linux-x64 linux-arm64 win-x64 win-arm64; do
publish_ui "$rid"
publish_cli "$rid"
done

echo "Builds published to $OUTDIR"
45 changes: 18 additions & 27 deletions MinishCapRandomizerCLI/MinishCapRandomizerCLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,18 @@
<ProjectReference Include="..\RandomizerCore\RandomizerCore.csproj" />
</ItemGroup>

<!-- Copy auxiliary data into output/publish directories using MSBuild, not shell cp -->
<ItemGroup>
<Content Include="..\RandomizerCore\Resouces\Patches\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<PackageReference Include="RestSharp" Version="112.1.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.8" />
<None Include="..\RandomizerCore\Resources\Patches\**\*.*">
<Link>Patches\%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<None Include="..\Vendor\Language Raws\**\*.*">
<Link>Language Raws\%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>

<Target Name="SetSourceRevisionId" BeforeTargets="InitializeSourceControlInformation">
Expand All @@ -52,24 +55,12 @@
</Exec>
</Target>

<Target Name="PostBuildDebugWindows" Condition="$([MSBuild]::IsOSPlatform('Windows')) and '$(Configuration)' == 'Debug'" AfterTargets="PostBuildEvent">
<Exec Command="xcopy &quot;$(ProjectDir)..\RandomizerCore\Resources\Patches\&quot; &quot;$(TargetDir)Patches\&quot; /y /d /s" />
<Exec Command="xcopy &quot;$(ProjectDir)..\Vendor\Language Raws\&quot; &quot;$(TargetDir)Language Raws\&quot; /y /d /s" />
</Target>

<Target Name="PostBuildReleaseWindows" Condition="$([MSBuild]::IsOSPlatform('Windows')) and '$(Configuration)' == 'Release'" AfterTargets="PostBuildEvent">
<Exec Command="xcopy &quot;$(ProjectDir)..\RandomizerCore\Resources\Patches\&quot; &quot;$(PublishDir)Patches\&quot; /y /d /s" />
<Exec Command="xcopy &quot;$(ProjectDir)..\Vendor\Language Raws\&quot; &quot;$(PublishDir)Language Raws\&quot; /y /d /s" />
</Target>

<Target Name="PostBuildDebugUnix" Condition="!$([MSBuild]::IsOSPlatform('Windows')) and '$(Configuration)' == 'Debug'" AfterTargets="PostBuildEvent">
<Exec Command="cp -r &quot;$(ProjectDir)/../RandomizerCore/Resources/Patches/&quot; &quot;$(TargetDir)&quot;" />
<Exec Command="cp -r &quot;$(ProjectDir)/../Vendor/Language Raws/&quot; &quot;$(TargetDir)&quot;" />
</Target>

<Target Name="PostBuildReleaseUnix" Condition="!$([MSBuild]::IsOSPlatform('Windows')) and '$(Configuration)' == 'Release'" AfterTargets="PostBuildEvent">
<Exec Command="cp -r &quot;$(ProjectDir)/../RandomizerCore/Resources/Patches/&quot; &quot;$(PublishDir)&quot;" />
<Exec Command="cp -r &quot;$(ProjectDir)/../Vendor/Language Raws/&quot; &quot;$(PublishDir)&quot;" />
</Target>
<ItemGroup>
<PackageReference Include="RestSharp" Version="112.1.0" />
<PackageReference Include="SkiaSharp" Version="2.88.8" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.8" />
<PackageReference Include="SkiaSharp.NativeAssets.Win32" Version="2.88.8" />
</ItemGroup>

<!-- Remove OS-specific post-build copy targets in favor of declarative CopyToPublishDirectory -->
</Project>
208 changes: 208 additions & 0 deletions MinishCapRandomizerUI.Avalonia/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MinishCapRandomizerUI.Avalonia.App"
RequestedThemeVariant="Default">
<Application.Styles>
<FluentTheme />

<!-- Window backgrounds per theme -->
<Style Selector="Window:light">
<Setter Property="Background" Value="#F6F8FB" />
</Style>
<Style Selector="Window:dark">
<Setter Property="Background" Value="#2D2D30" />
</Style>

<!-- Dark theme styles with grey tones -->
<Style Selector="HeaderedContentControl:dark">
<Setter Property="BorderBrush" Value="#3F3F46" />
<Setter Property="Template">
<ControlTemplate>
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border ZIndex="1" Background="#2D2D30" Padding="4,0,4,0" Margin="6,0,0,0">
<TextBlock Text="{TemplateBinding Header}" FontWeight="Bold" Foreground="#E0E0E0" />
</Border>
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" CornerRadius="3" Padding="0,3,0,0" Margin="0,6,0,0"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="#252526">
<ContentPresenter Name="PART_ContentPresenter" Padding="6,8,6,3" Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>

<Style Selector="HeaderedContentControl.compact-groupbox:dark">
<Setter Property="BorderBrush" Value="#3F3F46" />
<Setter Property="Template">
<ControlTemplate>
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border ZIndex="1" Background="#2D2D30" Padding="4,0,4,0" Margin="5,0,0,0">
<TextBlock Text="{TemplateBinding Header}" FontWeight="Bold" Foreground="#E0E0E0" />
</Border>
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" CornerRadius="3" Padding="0,2,0,0" Margin="0,5,0,0"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="#252526">
<ContentPresenter Name="PART_ContentPresenter" Padding="5,6,5,3" Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>

<!-- Dark theme text and control colors -->
<Style Selector="TextBlock:dark">
<Setter Property="Foreground" Value="#E0E0E0" />
</Style>

<Style Selector="TextBox:dark">
<Setter Property="Background" Value="#333337" />
<Setter Property="Foreground" Value="#E0E0E0" />
<Setter Property="BorderBrush" Value="#3F3F46" />
</Style>

<Style Selector="ComboBox:dark">
<Setter Property="Background" Value="#333337" />
<Setter Property="Foreground" Value="#E0E0E0" />
<Setter Property="BorderBrush" Value="#3F3F46" />
</Style>

<Style Selector="Button:dark">
<Setter Property="Background" Value="#3F3F46" />
<Setter Property="Foreground" Value="#E0E0E0" />
<Setter Property="BorderBrush" Value="#555555" />
</Style>

<Style Selector="CheckBox.toggled:dark">
<Setter Property="Foreground" Value="#569CD6" />
<Setter Property="FontWeight" Value="Bold" />
</Style>

<Style Selector="CheckBox.toggled:checked:dark">
<Setter Property="Foreground" Value="#6FCF97" />
<Setter Property="FontWeight" Value="Bold" />
</Style>

<Style Selector="TextBlock">
<Setter Property="FontSize" Value="11" />
</Style>
<Style Selector="TextBox">
<Setter Property="FontSize" Value="11" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Padding" Value="4,2" />
</Style>
<Style Selector="ComboBox">
<Setter Property="FontSize" Value="11" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Padding" Value="4,1" />
</Style>
<Style Selector="Button">
<Setter Property="FontSize" Value="11" />
<Setter Property="MinHeight" Value="22" />
<Setter Property="Padding" Value="6,2" />
</Style>
<Style Selector="CheckBox">
<Setter Property="FontSize" Value="11" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Padding" Value="4,1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style Selector="CheckBox.toggled">
<Setter Property="Foreground" Value="#007ACC" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style Selector="CheckBox.toggled:checked">
<Setter Property="Foreground" Value="#1B5E20" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style Selector="RadioButton">
<Setter Property="FontSize" Value="11" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Padding" Value="4,1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<!-- Real GroupBox style (HeaderedContentControl) adapted for WinForms groups feel -->
<Style Selector="HeaderedContentControl">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="3,2" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseMediumBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<ControlTemplate>
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border ZIndex="1" Background="{DynamicResource SystemControlBackgroundAltHighBrush}" Padding="4,0,4,0" Margin="6,0,0,0">
<TextBlock Text="{TemplateBinding Header}" FontWeight="Bold" />
</Border>
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" CornerRadius="3" Padding="0,3,0,0" Margin="0,6,0,0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ContentPresenter Name="PART_ContentPresenter" Padding="6,8,6,3" Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>
<!-- Compact variant using class, slightly tighter margins/padding -->
<Style Selector="HeaderedContentControl.compact-groupbox">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="3,1" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseMediumBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<ControlTemplate>
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border ZIndex="1" Background="{DynamicResource SystemControlBackgroundAltHighBrush}" Padding="4,0,4,0" Margin="5,0,0,0">
<TextBlock Text="{TemplateBinding Header}" FontWeight="Bold" />
</Border>
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" CornerRadius="3" Padding="0,2,0,0" Margin="0,5,0,0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ContentPresenter Name="PART_ContentPresenter" Padding="5,6,5,3" Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="MenuItem">
<Setter Property="FontSize" Value="11" />
<Setter Property="Padding" Value="6,4,6,4" />
</Style>
<Style Selector="MenuItem CheckBox">
<Setter Property="FontSize" Value="11" />
<Setter Property="Padding" Value="4" />
<Setter Property="Margin" Value="0" />
<Setter Property="MinHeight" Value="16" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Application.Styles>
</Application>
35 changes: 35 additions & 0 deletions MinishCapRandomizerUI.Avalonia/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;

namespace MinishCapRandomizerUI.Avalonia;

public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}

base.OnFrameworkInitializationCompleted();
}

public void ApplyThemePreference(string preference)
{
RequestedThemeVariant = preference switch
{
"Light" => ThemeVariant.Light,
"Dark" => ThemeVariant.Dark,
_ => ThemeVariant.Default // System
};
}
}

Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
namespace MinishCapRandomizerUI.DrawConstants;
using Avalonia.Media;
using Avalonia;

namespace MinishCapRandomizerUI.Avalonia.DrawConstants;

public static class Constants
{
public static int TopRowAboveSpacing => 15;
public static int FirstElementInRowX => 10;
public static int WidthMargin => 10;

public static int CategorySpacing => 20;

public static int CategoryLabelAlignX => 17;

public static int CategoryLabelAlignY => -8;

public static int CategoryWidth => 760;

public static BorderStyle CategoryBorderStyle => BorderStyle.FixedSingle;
public static Color DefaultBackgroundColor => Color.White;
public static Color DefaultButtonBackgroundColor => Color.Transparent; //Never heard of this color but it matches on the UI
public static Thickness CategoryBorderThickness => new(1);
public static IBrush CategoryBorderBrush => Brushes.Gray;
public static IBrush DefaultBackgroundBrush => Brushes.White;
public static IBrush DefaultButtonBackgroundBrush => Brushes.Transparent;

public static bool CategoryLabelsUseAutosize => true;

public static bool LabelsAndCheckboxesUseAutoEllipsis => true;

public static int DefaultStartingPaneX => 6;

public static int DefaultStartingPaneY => 15;
public static double SpecialScaling = 1;

public static double SpecialScaling = 1; //Some controls use this as a scaling factor, set during UI building based on DPI
public static bool UseMnemonic => false;

public static bool UseMnemonic => false; //This is used so that way escape characters like & are used literally

public const int TotalColorPickersPerRow = 1;
public const int TotalNumberBoxesPerRow = 2;
public const int TotalDropdownsPerRow = 2;
public const int TotalFlagsPerRow = 3;

public const int TooltipInitialShowDelayMs = 400;
public const int TooltipRepeatDelayMs = 400;
public const int TooltipDisplayLengthMs = 30000; //This is a hard limit of WinForms, sucks but oh well
public const int TooltipDisplayLengthMs = 30000;
}
Loading