Compare commits

...

13 Commits
3.0.1 ... 3.0.2

Author SHA1 Message Date
Matt Nadareski
8cfbf2d9f1 Bump version 2023-12-01 12:49:43 -05:00
Matt Nadareski
0064737130 Handle most VS and dotnet differences 2023-11-30 23:34:44 -05:00
Matt Nadareski
292e3999c5 Reference .NET Framework 3.0 for 3.5 2023-11-30 20:51:04 -05:00
Matt Nadareski
5ed1e94d84 Import WinFX for .NET Framework 3.5 2023-11-30 18:00:45 -05:00
Matt Nadareski
5b094f57cb Update USE_ALL in Powershell script 2023-11-30 13:43:20 -05:00
Matt Nadareski
8066b5541e Update Redumper to build 271 2023-11-30 13:39:32 -05:00
Matt Nadareski
921d0207c2 Fix cross-framework UI styles 2023-11-30 13:12:56 -05:00
Matt Nadareski
4374ff7f74 Fix most .NET Framework 3.5 issues 2023-11-30 12:58:06 -05:00
Matt Nadareski
0be5825b5e Fix cross-framework UI rendering 2023-11-30 11:54:40 -05:00
Matt Nadareski
14c630bea7 Fix Powershell build script 2023-11-30 03:19:39 -05:00
Matt Nadareski
9a66c685fd Replace build script with Powershell
Thanks to Deterous for the original script conversion.
2023-11-30 00:48:20 -05:00
Matt Nadareski
5e0fa1ad47 Add Disc ID and Key fields in info window (fixes #609) 2023-11-30 00:08:39 -05:00
Matt Nadareski
79065dcc69 Read CSS for some copy protections (fixes #608) 2023-11-29 23:57:58 -05:00
26 changed files with 1495 additions and 354 deletions

View File

@@ -1,3 +1,18 @@
### 3.0.2 (2023-12-01)
- Read CSS for some copy protections
- Add Disc ID and Key fields in info window
- Replace build script with Powershell
- Fix Powershell build script
- Fix cross-framework UI rendering
- Fix most .NET Framework 3.5 issues
- Fix cross-framework UI styles
- Update Redumper to build 271
- Update USE_ALL in Powershell script
- Import WinFX for .NET Framework 3.5
- Reference .NET Framework 3.0 for 3.5
- Handle most VS and dotnet differences
### 3.0.1 (2023-11-30)
- Add Bandai Pippin detection

View File

@@ -3,14 +3,14 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.0.1</VersionPrefix>
<VersionPrefix>3.0.2</VersionPrefix>
<!-- Package Properties -->
<Title>MPF Check</Title>

View File

@@ -3,13 +3,13 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.0.1</VersionPrefix>
<VersionPrefix>3.0.2</VersionPrefix>
<!-- Package Properties -->
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>

View File

@@ -521,6 +521,9 @@ namespace MPF.Core.Modules.DiscImageCreator
info.CopyProtection!.SecuROMData = GetFullFile($"{basePath}_subIntention.txt") ?? string.Empty;
}
// Needed for some odd copy protections
info.CopyProtection!.Protection = GetDVDProtection($"{basePath}_CSSKey.txt", $"{basePath}_disc.txt") ?? string.Empty;
break;
case RedumpSystem.DVDAudio:

View File

@@ -358,6 +358,9 @@ namespace MPF.Core.Modules.Redumper
case RedumpSystem.RainbowDisc:
case RedumpSystem.SonyElectronicBook:
info.CopyProtection!.SecuROMData = GetSecuROMData($"{basePath}.log") ?? string.Empty;
// Needed for some odd copy protections
info.CopyProtection!.Protection = GetDVDProtection($"{basePath}.log") ?? string.Empty;
break;
case RedumpSystem.DVDAudio:

View File

@@ -234,7 +234,7 @@ namespace MPF.Core
resultProgress?.Report(Result.Success("Running copy protection scan... this might take a while!"));
var (protectionString, fullProtections) = await InfoTool.GetCopyProtection(drive, options, protectionProgress);
info.CopyProtection!.Protection = protectionString;
info.CopyProtection!.Protection += protectionString;
info.CopyProtection.FullProtections = fullProtections as Dictionary<string, List<string>?> ?? [];
resultProgress?.Report(Result.Success("Copy protection scan complete!"));

View File

@@ -1,7 +1,9 @@
using System;
using System.Drawing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using MPF.UI.Core;
namespace WPFCustomMessageBox
{
@@ -28,11 +30,19 @@ namespace WPFCustomMessageBox
{
get
{
#if NET35
return _TextBlock_Message!.Text;
#else
return TextBlock_Message.Text;
#endif
}
set
{
#if NET35
_TextBlock_Message!.Text = value;
#else
TextBlock_Message.Text = value;
#endif
}
}
@@ -40,11 +50,19 @@ namespace WPFCustomMessageBox
{
get
{
#if NET35
return _Label_Ok!.Content.ToString();
#else
return Label_Ok.Content.ToString();
#endif
}
set
{
#if NET35
_Label_Ok!.Content = value.TryAddKeyboardAccellerator();
#else
Label_Ok.Content = value.TryAddKeyboardAccellerator();
#endif
}
}
@@ -52,11 +70,19 @@ namespace WPFCustomMessageBox
{
get
{
#if NET35
return _Label_Cancel!.Content.ToString();
#else
return Label_Cancel.Content.ToString();
#endif
}
set
{
#if NET35
_Label_Cancel!.Content = value.TryAddKeyboardAccellerator();
#else
Label_Cancel.Content = value.TryAddKeyboardAccellerator();
#endif
}
}
@@ -64,11 +90,19 @@ namespace WPFCustomMessageBox
{
get
{
#if NET35
return _Label_Yes!.Content.ToString();
#else
return Label_Yes.Content.ToString();
#endif
}
set
{
#if NET35
_Label_Yes!.Content = value.TryAddKeyboardAccellerator();
#else
Label_Yes.Content = value.TryAddKeyboardAccellerator();
#endif
}
}
@@ -76,16 +110,39 @@ namespace WPFCustomMessageBox
{
get
{
#if NET35
return _Label_No!.Content.ToString();
#else
return Label_No.Content.ToString();
#endif
}
set
{
#if NET35
_Label_No!.Content = value.TryAddKeyboardAccellerator();
#else
Label_No.Content = value.TryAddKeyboardAccellerator();
#endif
}
}
public MessageBoxResult Result { get; set; }
#if NET35
private Button? _Button_Cancel => ItemHelper.FindChild<Button>(this, "Button_Cancel");
private Button? _Button_No => ItemHelper.FindChild<Button>(this, "Button_No");
private Button? _Button_OK => ItemHelper.FindChild<Button>(this, "Button_OK");
private Button? _Button_Yes => ItemHelper.FindChild<Button>(this, "Button_Yes");
private System.Windows.Controls.Image? _Image_MessageBox => ItemHelper.FindChild<System.Windows.Controls.Image>(this, "Image_MessageBox");
private Label? _Label_Cancel => ItemHelper.FindChild<Label>(this, "Label_Cancel");
private Label? _Label_No => ItemHelper.FindChild<Label>(this, "Label_No");
private Label? _Label_Ok => ItemHelper.FindChild<Label>(this, "Label_Ok");
private Label? _Label_Yes => ItemHelper.FindChild<Label>(this, "Label_Yes");
private TextBlock? _TextBlock_Message => ItemHelper.FindChild<TextBlock>(this, "TextBlock_Message");
#endif
internal CustomMessageBoxWindow(Window? owner, string? message, string? caption = null, MessageBoxButton? button = null, MessageBoxImage? image = null, bool removeTitleBarIcon = true)
{
#if NET40_OR_GREATER || NETCOREAPP
@@ -103,7 +160,9 @@ namespace WPFCustomMessageBox
System.Windows.Shell.WindowChrome.SetWindowChrome(this, chrome);
#endif
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
_removeTitleBarIcon = removeTitleBarIcon;
Focusable = true;
@@ -124,7 +183,11 @@ namespace WPFCustomMessageBox
if (image.HasValue)
DisplayImage(image.Value);
else
#if NET35
_Image_MessageBox!.Visibility = Visibility.Collapsed;
#else
Image_MessageBox.Visibility = Visibility.Collapsed;
#endif
}
protected override void OnSourceInitialized(EventArgs e)
@@ -141,39 +204,75 @@ namespace WPFCustomMessageBox
{
case MessageBoxButton.OKCancel:
// Hide all but OK, Cancel
#if NET35
_Button_OK!.Visibility = Visibility.Visible;
_Button_OK.Focus();
_Button_Cancel!.Visibility = Visibility.Visible;
_Button_Yes!.Visibility = Visibility.Collapsed;
_Button_No!.Visibility = Visibility.Collapsed;
#else
Button_OK.Visibility = Visibility.Visible;
Button_OK.Focus();
Button_Cancel.Visibility = Visibility.Visible;
Button_Yes.Visibility = Visibility.Collapsed;
Button_No.Visibility = Visibility.Collapsed;
#endif
break;
case MessageBoxButton.YesNo:
// Hide all but Yes, No
#if NET35
_Button_Yes!.Visibility = Visibility.Visible;
_Button_Yes.Focus();
_Button_No!.Visibility = Visibility.Visible;
_Button_OK!.Visibility = Visibility.Collapsed;
_Button_Cancel!.Visibility = Visibility.Collapsed;
#else
Button_Yes.Visibility = Visibility.Visible;
Button_Yes.Focus();
Button_No.Visibility = Visibility.Visible;
Button_OK.Visibility = Visibility.Collapsed;
Button_Cancel.Visibility = Visibility.Collapsed;
#endif
break;
case MessageBoxButton.YesNoCancel:
// Hide only OK
#if NET35
_Button_Yes!.Visibility = Visibility.Visible;
_Button_Yes.Focus();
_Button_No!.Visibility = Visibility.Visible;
_Button_Cancel!.Visibility = Visibility.Visible;
_Button_OK!.Visibility = Visibility.Collapsed;
#else
Button_Yes.Visibility = Visibility.Visible;
Button_Yes.Focus();
Button_No.Visibility = Visibility.Visible;
Button_Cancel.Visibility = Visibility.Visible;
Button_OK.Visibility = Visibility.Collapsed;
#endif
break;
default:
// Hide all but OK
#if NET35
_Button_OK!.Visibility = Visibility.Visible;
_Button_OK.Focus();
_Button_Yes!.Visibility = Visibility.Collapsed;
_Button_No!.Visibility = Visibility.Collapsed;
_Button_Cancel!.Visibility = Visibility.Collapsed;
#else
Button_OK.Visibility = Visibility.Visible;
Button_OK.Focus();
Button_Yes.Visibility = Visibility.Collapsed;
Button_No.Visibility = Visibility.Collapsed;
Button_Cancel.Visibility = Visibility.Collapsed;
#endif
break;
}
}
@@ -201,8 +300,13 @@ namespace WPFCustomMessageBox
break;
}
#if NET35
_Image_MessageBox!.Source = icon.ToImageSource();
_Image_MessageBox.Visibility = Visibility.Visible;
#else
Image_MessageBox.Source = icon.ToImageSource();
Image_MessageBox.Visibility = Visibility.Visible;
#endif
}
private void Button_OK_Click(object sender, RoutedEventArgs e)

124
MPF.UI.Core/ItemHelper.cs Normal file
View File

@@ -0,0 +1,124 @@
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
namespace MPF.UI.Core
{
internal static class ItemHelper
{
/// <summary>
/// Finds a Child of a given item in the visual tree.
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter.
/// If not matching item can be found,
/// a null parent is being returned.</returns>
public static T? FindChild<T>(DependencyObject? parent, string childName) where T : DependencyObject
{
// Confirm parent and childName are valid.
if (parent == null) return null;
T? foundChild = null;
if (parent is ItemsControl itemsControl && itemsControl.Items != null)
{
int childrenCount = itemsControl.Items.Count;
for (int i = 0; i < childrenCount; i++)
{
var child = itemsControl.Items[i] as DependencyObject;
// If the child is not of the request child type child
if (child is not T)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null)
break;
}
else if (!string.IsNullOrEmpty(childName))
{
// If the child's name is set for search
if (child is FrameworkElement frameworkElement && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
}
else if (parent is ContentControl contentControl && contentControl.Content != null)
{
var child = contentControl.Content as DependencyObject;
// If the child is not of the request child type child
if (child is not T)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
}
else if (!string.IsNullOrEmpty(childName))
{
// If the child's name is set for search
if (child is FrameworkElement frameworkElement && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
}
}
else
{
// child element found.
foundChild = (T)child;
}
}
else if (parent is Visual)
{
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
// If the child is not of the request child type child
if (child is not T)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null)
break;
}
else if (!string.IsNullOrEmpty(childName))
{
// If the child's name is set for search
if (child is FrameworkElement frameworkElement && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
}
return foundChild;
}
}
}

View File

@@ -2,14 +2,15 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0-windows;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
<TargetFrameworks>net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0-windows;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<ImportFrameworkWinFXTargets Condition="$(TargetFramework.StartsWith(`net3`))">true</ImportFrameworkWinFXTargets>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.0.1</VersionPrefix>
<VersionPrefix>3.0.2</VersionPrefix>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
@@ -31,6 +32,14 @@
<ProjectReference Include="..\MPF.Core\MPF.Core.csproj" />
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net3`))">
<Reference Include="PresentationBuildTasks" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
<Reference Include="PresentationCore" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll" />
<Reference Include="PresentationFramework" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll" />
<Reference Include="WindowsBase" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.RedumpLib" Version="1.3.1" />
</ItemGroup>

View File

@@ -31,9 +31,20 @@ namespace MPF.UI.Core.UserControls
/// </summary>
private Run? lastLine = null;
#if NET35
private Button? _ClearButton => ItemHelper.FindChild<Button>(this, "ClearButton");
private RichTextBox? _Output => ItemHelper.FindChild<RichTextBox>(this, "Output");
private ScrollViewer? _OutputViewer => ItemHelper.FindChild<ScrollViewer>(this, "OutputViewer");
private Button? _SaveButton => ItemHelper.FindChild<Button>(this, "SaveButton");
#endif
public LogOutput()
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
// Update the internal state
Document = new FlowDocument()
@@ -47,13 +58,24 @@ namespace MPF.UI.Core.UserControls
LogQueue = new ProcessingQueue<LogLine>(ProcessLogLine);
// Add handlers
#if NET35
_OutputViewer!.SizeChanged += OutputViewerSizeChanged;
_Output!.TextChanged += OnTextChanged;
_ClearButton!.Click += OnClearButton;
_SaveButton!.Click += OnSaveButton;
#else
OutputViewer.SizeChanged += OutputViewerSizeChanged;
Output.TextChanged += OnTextChanged;
ClearButton.Click += OnClearButton;
SaveButton.Click += OnSaveButton;
#endif
// Update the internal state
#if NET35
_Output.Document = Document;
#else
Output.Document = Document;
#endif
}
#region Logging
@@ -170,7 +192,7 @@ namespace MPF.UI.Core.UserControls
});
}
#endregion
#endregion
#region Helpers
@@ -197,7 +219,11 @@ namespace MPF.UI.Core.UserControls
/// <summary>
/// Scroll the current view to the bottom
/// </summary>
#if NET35
public void ScrollToBottom() => _OutputViewer!.ScrollToBottom();
#else
public void ScrollToBottom() => OutputViewer.ScrollToBottom();
#endif
#endregion

View File

@@ -39,7 +39,7 @@ namespace MPF.UI.Core.UserControls
public static readonly DependencyProperty VerticalScrollBarVisibilityProperty =
DependencyProperty.Register("VerticalScrollBarVisibility", typeof(ScrollBarVisibility), typeof(UserInput));
#endregion
#region Properties
@@ -118,7 +118,9 @@ namespace MPF.UI.Core.UserControls
HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
}
}
}

View File

@@ -31,7 +31,7 @@
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
<Label.Content>
<TextBlock TextAlignment="Center"><Bold>Disc Information</Bold></TextBlock>
<Run FontWeight="Bold" Text="Disc Information" />
</Label.Content>
<Label.ContextMenu>
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
@@ -172,6 +172,10 @@
<controls:UserInput x:Name="CommentsTextBox" Label="Comments"
Text="{Binding SubmissionInfo.CommonDiscInfo.Comments, Mode=TwoWay}" TextHeight="50"
Enter="True" TextWrapping="Wrap" VerticalContentAlignmentValue="Top" />
<controls:UserInput x:Name="DiscKeyTextBox" Label="Disc Key" Visibility="Collapsed"
Text="{Binding Path=SubmissionInfo.Extras.DiscKey, Mode=TwoWay}"/>
<controls:UserInput x:Name="DiscIDTextBox" Label="Disc ID" Visibility="Collapsed"
Text="{Binding Path=SubmissionInfo.Extras.DiscID, Mode=TwoWay}"/>
<controls:UserInput x:Name="GenreTextBox" Label="Genre"
Text="{Binding Path=SubmissionInfo.CommonDiscInfo.CommentsSpecialFields[(redump:SiteCode)Genre], Mode=TwoWay}"/>
<controls:UserInput x:Name="ProtectionTextBox" Label="Protection" ToolTip="CAUTION: Only edit if you know what you are doing!"

View File

@@ -1,8 +1,10 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using MPF.Core.Data;
using MPF.Core.UI.ViewModels;
using MPF.Core.Utilities;
using MPF.UI.Core.UserControls;
using SabreTools.RedumpLib.Data;
namespace MPF.UI.Core.Windows
@@ -12,6 +14,105 @@ namespace MPF.UI.Core.Windows
/// </summary>
public partial class DiscInformationWindow : WindowBase
{
#if NET35
#region Common Info
private Grid? _LanguageSelectionGrid => ItemHelper.FindChild<Grid>(this, "LanguageSelectionGrid");
#endregion
#region Additional Info
private UserInput? _CommentsTextBox => ItemHelper.FindChild<UserInput>(this, "CommentsTextBox");
private UserInput? _DiscIDTextBox => ItemHelper.FindChild<UserInput>(this, "DiscIDTextBox");
private UserInput? _DiscKeyTextBox => ItemHelper.FindChild<UserInput>(this, "DiscKeyTextBox");
#endregion
#region Contents
private UserInput? _ExtrasTextBox => ItemHelper.FindChild<UserInput>(this, "ExtrasTextBox");
private UserInput? _GameFootageTextBox => ItemHelper.FindChild<UserInput>(this, "GameFootageTextBox");
private UserInput? _GamesTextBox => ItemHelper.FindChild<UserInput>(this, "GamesTextBox");
private UserInput? _GeneralContent => ItemHelper.FindChild<UserInput>(this, "GeneralContent");
private UserInput? _NetYarozeGamesTextBox => ItemHelper.FindChild<UserInput>(this, "NetYarozeGamesTextBox");
private UserInput? _PatchesTextBox => ItemHelper.FindChild<UserInput>(this, "PatchesTextBox");
private UserInput? _PlayableDemosTextBox => ItemHelper.FindChild<UserInput>(this, "PlayableDemosTextBox");
private UserInput? _RollingDemosTextBox => ItemHelper.FindChild<UserInput>(this, "RollingDemosTextBox");
private UserInput? _SavegamesTextBox => ItemHelper.FindChild<UserInput>(this, "SavegamesTextBox");
private UserInput? _TechDemosTextBox => ItemHelper.FindChild<UserInput>(this, "TechDemosTextBox");
private UserInput? _VideosTextBox => ItemHelper.FindChild<UserInput>(this, "VideosTextBox");
#endregion
#region Ringcodes
private GroupBox? _L0Info => ItemHelper.FindChild<GroupBox>(this, "L0Info");
private UserInput? _L0MasteringRing => ItemHelper.FindChild<UserInput>(this, "L0MasteringRing");
private UserInput? _L0MasteringSID => ItemHelper.FindChild<UserInput>(this, "L0MasteringSID");
private UserInput? _L0Toolstamp => ItemHelper.FindChild<UserInput>(this, "L0Toolstamp");
private UserInput? _L0MouldSID => ItemHelper.FindChild<UserInput>(this, "L0MouldSID");
private UserInput? _L0AdditionalMould => ItemHelper.FindChild<UserInput>(this, "L0AdditionalMould");
private GroupBox? _L1Info => ItemHelper.FindChild<GroupBox>(this, "L1Info");
private UserInput? _L1MasteringRing => ItemHelper.FindChild<UserInput>(this, "L1MasteringRing");
private UserInput? _L1MasteringSID => ItemHelper.FindChild<UserInput>(this, "L1MasteringSID");
private UserInput? _L1Toolstamp => ItemHelper.FindChild<UserInput>(this, "L1Toolstamp");
private UserInput? _L1MouldSID => ItemHelper.FindChild<UserInput>(this, "L1MouldSID");
private UserInput? _L1AdditionalMould => ItemHelper.FindChild<UserInput>(this, "L1AdditionalMould");
private GroupBox? _L2Info => ItemHelper.FindChild<GroupBox>(this, "L2Info");
private UserInput? _L2MasteringRing => ItemHelper.FindChild<UserInput>(this, "L2MasteringRing");
private UserInput? _L2MasteringSID => ItemHelper.FindChild<UserInput>(this, "L2MasteringSID");
private UserInput? _L2Toolstamp => ItemHelper.FindChild<UserInput>(this, "L2Toolstamp");
private GroupBox? _L3Info => ItemHelper.FindChild<GroupBox>(this, "L3Info");
private UserInput? _L3MasteringRing => ItemHelper.FindChild<UserInput>(this, "L3MasteringRing");
private UserInput? _L3MasteringSID => ItemHelper.FindChild<UserInput>(this, "L3MasteringSID");
private UserInput? _L3Toolstamp => ItemHelper.FindChild<UserInput>(this, "L3Toolstamp");
#endregion
#region Read-Only Info
private UserInput? _FullyMatchedID => ItemHelper.FindChild<UserInput>(this, "FullyMatchedID");
private UserInput? _PartiallyMatchedIDs => ItemHelper.FindChild<UserInput>(this, "PartiallyMatchedIDs");
private UserInput? _AntiModchip => ItemHelper.FindChild<UserInput>(this, "AntiModchip");
private UserInput? _DiscOffset => ItemHelper.FindChild<UserInput>(this, "DiscOffset");
private UserInput? _DMIHash => ItemHelper.FindChild<UserInput>(this, "DMIHash");
private UserInput? _EDC => ItemHelper.FindChild<UserInput>(this, "EDC");
private UserInput? _ErrorsCount => ItemHelper.FindChild<UserInput>(this, "ErrorsCount");
private UserInput? _EXEDateBuildDate => ItemHelper.FindChild<UserInput>(this, "EXEDateBuildDate");
private UserInput? _Filename => ItemHelper.FindChild<UserInput>(this, "Filename");
private UserInput? _Header => ItemHelper.FindChild<UserInput>(this, "Header");
private UserInput? _InternalName => ItemHelper.FindChild<UserInput>(this, "InternalName");
private UserInput? _InternalSerialName => ItemHelper.FindChild<UserInput>(this, "InternalSerialName");
private UserInput? _Multisession => ItemHelper.FindChild<UserInput>(this, "Multisession");
private UserInput? _LibCrypt => ItemHelper.FindChild<UserInput>(this, "LibCrypt");
private UserInput? _LibCryptData => ItemHelper.FindChild<UserInput>(this, "LibCryptData");
private UserInput? _PFIHash => ItemHelper.FindChild<UserInput>(this, "PFIHash");
private UserInput? _PIC => ItemHelper.FindChild<UserInput>(this, "PIC");
private UserInput? _PVD => ItemHelper.FindChild<UserInput>(this, "PVD");
private UserInput? _RingNonZeroDataStart => ItemHelper.FindChild<UserInput>(this, "RingNonZeroDataStart");
private UserInput? _SecuROMData => ItemHelper.FindChild<UserInput>(this, "SecuROMData");
private UserInput? _SSHash => ItemHelper.FindChild<UserInput>(this, "SSHash");
private UserInput? _SecuritySectorRanges => ItemHelper.FindChild<UserInput>(this, "SecuritySectorRanges");
private UserInput? _SSVersion => ItemHelper.FindChild<UserInput>(this, "SSVersion");
private UserInput? _UniversalHash => ItemHelper.FindChild<UserInput>(this, "UniversalHash");
private UserInput? _VolumeLabel => ItemHelper.FindChild<UserInput>(this, "VolumeLabel");
private UserInput? _XeMID => ItemHelper.FindChild<UserInput>(this, "XeMID");
private UserInput? _XMID => ItemHelper.FindChild<UserInput>(this, "XMID");
#endregion
#region Accept / Cancel
private Button? _AcceptButton => ItemHelper.FindChild<Button>(this, "AcceptButton");
private Button? _CancelButton => ItemHelper.FindChild<Button>(this, "CancelButton");
private Button? _RingCodeGuideButton => ItemHelper.FindChild<Button>(this, "RingCodeGuideButton");
#endregion
#endif
/// <summary>
/// Read-only access to the current disc information view model
/// </summary>
@@ -22,7 +123,9 @@ namespace MPF.UI.Core.Windows
/// </summary>
public DiscInformationWindow(Options options, SubmissionInfo? submissionInfo)
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
#if NET452_OR_GREATER || NETCOREAPP
var chrome = new System.Windows.Shell.WindowChrome
@@ -44,9 +147,15 @@ namespace MPF.UI.Core.Windows
}
// Add handlers
#if NET35
_AcceptButton!.Click += OnAcceptClick;
_CancelButton!.Click += OnCancelClick;
_RingCodeGuideButton!.Click += OnRingCodeGuideClick;
#else
AcceptButton.Click += OnAcceptClick;
CancelButton.Click += OnCancelClick;
RingCodeGuideButton.Click += OnRingCodeGuideClick;
#endif
// Update UI with new values
ManipulateFields(options, submissionInfo);
@@ -80,9 +189,26 @@ namespace MPF.UI.Core.Windows
private void EnableTabsInInputFields()
{
// Additional Information
#if NET35
_CommentsTextBox!.Tab = true;
#else
CommentsTextBox.Tab = true;
#endif
// Contents
#if NET35
_GeneralContent!.Tab = true;
_GamesTextBox!.Tab = true;
_NetYarozeGamesTextBox!.Tab = true;
_PlayableDemosTextBox!.Tab = true;
_RollingDemosTextBox!.Tab = true;
_TechDemosTextBox!.Tab = true;
_GameFootageTextBox!.Tab = true;
_VideosTextBox!.Tab = true;
_PatchesTextBox!.Tab = true;
_SavegamesTextBox!.Tab = true;
_ExtrasTextBox!.Tab = true;
#else
GeneralContent.Tab = true;
GamesTextBox.Tab = true;
NetYarozeGamesTextBox.Tab = true;
@@ -94,30 +220,59 @@ namespace MPF.UI.Core.Windows
PatchesTextBox.Tab = true;
SavegamesTextBox.Tab = true;
ExtrasTextBox.Tab = true;
#endif
// L0
#if NET35
_L0MasteringRing!.Tab = true;
_L0MasteringSID!.Tab = true;
_L0Toolstamp!.Tab = true;
_L0MouldSID!.Tab = true;
_L0AdditionalMould!.Tab = true;
#else
L0MasteringRing.Tab = true;
L0MasteringSID.Tab = true;
L0Toolstamp.Tab = true;
L0MouldSID.Tab = true;
L0AdditionalMould.Tab = true;
#endif
// L1
#if NET35
_L1MasteringRing!.Tab = true;
_L1MasteringSID!.Tab = true;
_L1Toolstamp!.Tab = true;
_L1MouldSID!.Tab = true;
_L1AdditionalMould!.Tab = true;
#else
L1MasteringRing.Tab = true;
L1MasteringSID.Tab = true;
L1Toolstamp.Tab = true;
L1MouldSID.Tab = true;
L1AdditionalMould.Tab = true;
#endif
// L2
#if NET35
_L2MasteringRing!.Tab = true;
_L2MasteringSID!.Tab = true;
_L2Toolstamp!.Tab = true;
#else
L2MasteringRing.Tab = true;
L2MasteringSID.Tab = true;
L2Toolstamp.Tab = true;
#endif
// L3
#if NET35
_L3MasteringRing!.Tab = true;
_L3MasteringSID!.Tab = true;
_L3Toolstamp!.Tab = true;
#else
L3MasteringRing.Tab = true;
L3MasteringSID.Tab = true;
L3Toolstamp.Tab = true;
#endif
}
/// <summary>
@@ -131,6 +286,64 @@ namespace MPF.UI.Core.Windows
if (submissionInfo == null)
return;
#if NET35
if (submissionInfo.FullyMatchedID == null)
_FullyMatchedID!.Visibility = Visibility.Collapsed;
if (submissionInfo.PartiallyMatchedIDs == null)
_PartiallyMatchedIDs!.Visibility = Visibility.Collapsed;
else
_PartiallyMatchedIDs!.Text = string.Join(", ", submissionInfo.PartiallyMatchedIDs.Select(i => i.ToString()).ToArray());
if (submissionInfo.CopyProtection?.AntiModchip == null)
_AntiModchip!.Visibility = Visibility.Collapsed;
if (submissionInfo.TracksAndWriteOffsets?.OtherWriteOffsets == null)
_DiscOffset!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.Keys?.Contains(SiteCode.DMIHash) != true)
_DMIHash!.Visibility = Visibility.Collapsed;
if (submissionInfo.EDC?.EDC == null)
_EDC!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CommonDiscInfo?.ErrorsCount))
_ErrorsCount!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CommonDiscInfo?.EXEDateBuildDate))
_EXEDateBuildDate!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.Filename) != true)
_Filename!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.Header))
_Header!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.InternalName) != true)
_InternalName!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.InternalSerialName) != true)
_InternalSerialName!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.Multisession) != true)
_Multisession!.Visibility = Visibility.Collapsed;
if (submissionInfo.CopyProtection?.LibCrypt == null)
_LibCrypt!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.LibCryptData))
_LibCryptData!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.PFIHash) != true)
_PFIHash!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.PIC))
_PIC!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.PVD))
_PVD!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.RingNonZeroDataStart) != true)
_RingNonZeroDataStart!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.CopyProtection?.SecuROMData))
_SecuROMData!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSHash) != true)
_SSHash!.Visibility = Visibility.Collapsed;
if (string.IsNullOrEmpty(submissionInfo.Extras?.SecuritySectorRanges))
_SecuritySectorRanges!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.SSVersion) != true)
_SSVersion!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.UniversalHash) != true)
_UniversalHash!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.VolumeLabel) != true)
_VolumeLabel!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.XeMID) != true)
_XeMID!.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.XMID) != true)
_XMID!.Visibility = Visibility.Collapsed;
#else
if (submissionInfo.FullyMatchedID == null)
FullyMatchedID.Visibility = Visibility.Collapsed;
if (submissionInfo.PartiallyMatchedIDs == null)
@@ -187,6 +400,7 @@ namespace MPF.UI.Core.Windows
XeMID.Visibility = Visibility.Collapsed;
if (submissionInfo.CommonDiscInfo?.CommentsSpecialFields?.ContainsKey(SiteCode.XMID) != true)
XMID.Visibility = Visibility.Collapsed;
#endif
}
/// <summary>
@@ -203,19 +417,37 @@ namespace MPF.UI.Core.Windows
{
case DiscType.CD:
case DiscType.GDROM:
#if NET35
_L0Info!.Header = "Data Side";
_L0MasteringRing!.Label = "Mastering Ring";
_L0MasteringSID!.Label = "Mastering SID";
_L0Toolstamp!.Label = "Toolstamp/Mastering Code";
_L0MouldSID!.Label = "Mould SID";
_L0AdditionalMould!.Label = "Additional Mould";
#else
L0Info.Header = "Data Side";
L0MasteringRing.Label = "Mastering Ring";
L0MasteringSID.Label = "Mastering SID";
L0Toolstamp.Label = "Toolstamp/Mastering Code";
L0MouldSID.Label = "Mould SID";
L0AdditionalMould.Label = "Additional Mould";
#endif
#if NET35
_L1Info!.Header = "Label Side";
_L1MasteringRing!.Visibility = Visibility.Collapsed;
_L1MasteringSID!.Visibility = Visibility.Collapsed;
_L1Toolstamp!.Visibility = Visibility.Collapsed;
_L1MouldSID!.Label = "Mould SID";
_L1AdditionalMould!.Label = "Additional Mould";
#else
L1Info.Header = "Label Side";
L1MasteringRing.Visibility = Visibility.Collapsed;
L1MasteringSID.Visibility = Visibility.Collapsed;
L1Toolstamp.Visibility = Visibility.Collapsed;
L1MouldSID.Label = "Mould SID";
L1AdditionalMould.Label = "Additional Mould";
#endif
break;
case DiscType.DVD5:
@@ -235,103 +467,212 @@ namespace MPF.UI.Core.Windows
// Quad-layer discs
if (submissionInfo?.SizeAndChecksums?.Layerbreak3 != default(long))
{
#if NET35
_L2Info!.Visibility = Visibility.Visible;
_L3Info!.Visibility = Visibility.Visible;
#else
L2Info.Visibility = Visibility.Visible;
L3Info.Visibility = Visibility.Visible;
#endif
#if NET35
_L0Info!.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
_L0MasteringRing!.Label = "Mastering Ring";
_L0MasteringSID!.Label = "Mastering SID";
_L0Toolstamp!.Label = "Toolstamp/Mastering Code";
_L0MouldSID!.Label = "Data Side Mould SID";
_L0AdditionalMould!.Label = "Data Side Additional Mould";
#else
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
L0MasteringRing.Label = "Mastering Ring";
L0MasteringSID.Label = "Mastering SID";
L0Toolstamp.Label = "Toolstamp/Mastering Code";
L0MouldSID.Label = "Data Side Mould SID";
L0AdditionalMould.Label = "Data Side Additional Mould";
#endif
#if NET35
_L1Info!.Header = "Layer 1";
_L1MasteringRing!.Label = "Mastering Ring";
_L1MasteringSID!.Label = "Mastering SID";
_L1Toolstamp!.Label = "Toolstamp/Mastering Code";
_L1MouldSID!.Label = "Label Side Mould SID";
_L1AdditionalMould!.Label = "Label Side Additional Mould";
#else
L1Info.Header = "Layer 1";
L1MasteringRing.Label = "Mastering Ring";
L1MasteringSID.Label = "Mastering SID";
L1Toolstamp.Label = "Toolstamp/Mastering Code";
L1MouldSID.Label = "Label Side Mould SID";
L1AdditionalMould.Label = "Label Side Additional Mould";
#endif
#if NET35
_L2Info!.Header = "Layer 2";
_L2MasteringRing!.Label = "Mastering Ring";
_L2MasteringSID!.Label = "Mastering SID";
_L2Toolstamp!.Label = "Toolstamp/Mastering Code";
#else
L2Info.Header = "Layer 2";
L2MasteringRing.Label = "Mastering Ring";
L2MasteringSID.Label = "Mastering SID";
L2Toolstamp.Label = "Toolstamp/Mastering Code";
#endif
#if NET35
_L3Info!.Header = reverseOrder ? "Layer 3 (Inner)" : "Layer 3 (Outer)";
_L3MasteringRing!.Label = "Mastering Ring";
_L3MasteringSID!.Label = "Mastering SID";
_L3Toolstamp!.Label = "Toolstamp/Mastering Code";
#else
L3Info.Header = reverseOrder ? "Layer 3 (Inner)" : "Layer 3 (Outer)";
L3MasteringRing.Label = "Mastering Ring";
L3MasteringSID.Label = "Mastering SID";
L3Toolstamp.Label = "Toolstamp/Mastering Code";
#endif
}
// Triple-layer discs
else if (submissionInfo?.SizeAndChecksums?.Layerbreak2 != default(long))
{
#if NET35
_L2Info!.Visibility = Visibility.Visible;
#else
L2Info.Visibility = Visibility.Visible;
#endif
#if NET35
_L0Info!.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
_L0MasteringRing!.Label = "Mastering Ring";
_L0MasteringSID!.Label = "Mastering SID";
_L0Toolstamp!.Label = "Toolstamp/Mastering Code";
_L0MouldSID!.Label = "Data Side Mould SID";
_L0AdditionalMould!.Label = "Data Side Additional Mould";
#else
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
L0MasteringRing.Label = "Mastering Ring";
L0MasteringSID.Label = "Mastering SID";
L0Toolstamp.Label = "Toolstamp/Mastering Code";
L0MouldSID.Label = "Data Side Mould SID";
L0AdditionalMould.Label = "Data Side Additional Mould";
#endif
#if NET35
_L1Info!.Header = "Layer 1";
_L1MasteringRing!.Label = "Mastering Ring";
_L1MasteringSID!.Label = "Mastering SID";
_L1Toolstamp!.Label = "Toolstamp/Mastering Code";
_L1MouldSID!.Label = "Label Side Mould SID";
_L1AdditionalMould!.Label = "Label Side Additional Mould";
#else
L1Info.Header = "Layer 1";
L1MasteringRing.Label = "Mastering Ring";
L1MasteringSID.Label = "Mastering SID";
L1Toolstamp.Label = "Toolstamp/Mastering Code";
L1MouldSID.Label = "Label Side Mould SID";
L1AdditionalMould.Label = "Label Side Additional Mould";
#endif
#if NET35
_L2Info!.Header = reverseOrder ? "Layer 2 (Inner)" : "Layer 2 (Outer)";
_L2MasteringRing!.Label = "Mastering Ring";
_L2MasteringSID!.Label = "Mastering SID";
_L2Toolstamp!.Label = "Toolstamp/Mastering Code";
#else
L2Info.Header = reverseOrder ? "Layer 2 (Inner)" : "Layer 2 (Outer)";
L2MasteringRing.Label = "Mastering Ring";
L2MasteringSID.Label = "Mastering SID";
L2Toolstamp.Label = "Toolstamp/Mastering Code";
#endif
}
// Double-layer discs
else if (submissionInfo?.SizeAndChecksums?.Layerbreak != default(long))
{
#if NET35
_L0Info!.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
_L0MasteringRing!.Label = "Mastering Ring";
_L0MasteringSID!.Label = "Mastering SID";
_L0Toolstamp!.Label = "Toolstamp/Mastering Code";
_L0MouldSID!.Label = "Data Side Mould SID";
_L0AdditionalMould!.Label = "Data Side Additional Mould";
#else
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
L0MasteringRing.Label = "Mastering Ring";
L0MasteringSID.Label = "Mastering SID";
L0Toolstamp.Label = "Toolstamp/Mastering Code";
L0MouldSID.Label = "Data Side Mould SID";
L0AdditionalMould.Label = "Data Side Additional Mould";
#endif
#if NET35
_L1Info!.Header = reverseOrder ? "Layer 1 (Inner)" : "Layer 1 (Outer)";
_L1MasteringRing!.Label = "Mastering Ring";
_L1MasteringSID!.Label = "Mastering SID";
_L1Toolstamp!.Label = "Toolstamp/Mastering Code";
_L1MouldSID!.Label = "Label Side Mould SID";
_L1AdditionalMould!.Label = "Label Side Additional Mould";
#else
L1Info.Header = reverseOrder ? "Layer 1 (Inner)" : "Layer 1 (Outer)";
L1MasteringRing.Label = "Mastering Ring";
L1MasteringSID.Label = "Mastering SID";
L1Toolstamp.Label = "Toolstamp/Mastering Code";
L1MouldSID.Label = "Label Side Mould SID";
L1AdditionalMould.Label = "Label Side Additional Mould";
#endif
}
// Single-layer discs
else
{
#if NET35
_L0Info!.Header = "Data Side";
_L0MasteringRing!.Label = "Mastering Ring";
_L0MasteringSID!.Label = "Mastering SID";
_L0Toolstamp!.Label = "Toolstamp/Mastering Code";
_L0MouldSID!.Label = "Mould SID";
_L0AdditionalMould!.Label = "Additional Mould";
#else
L0Info.Header = "Data Side";
L0MasteringRing.Label = "Mastering Ring";
L0MasteringSID.Label = "Mastering SID";
L0Toolstamp.Label = "Toolstamp/Mastering Code";
L0MouldSID.Label = "Mould SID";
L0AdditionalMould.Label = "Additional Mould";
#endif
#if NET35
_L1Info!.Header = "Label Side";
_L1MasteringRing!.Visibility = Visibility.Collapsed;
_L1MasteringSID!.Visibility = Visibility.Collapsed;
_L1Toolstamp!.Visibility = Visibility.Collapsed;
_L1MouldSID!.Label = "Mould SID";
_L1AdditionalMould!.Label = "Additional Mould";
#else
L1Info.Header = "Label Side";
L1MasteringRing.Label = "Mastering Ring";
L1MasteringSID.Label = "Mastering SID";
L1Toolstamp.Label = "Toolstamp/Mastering Code";
L1MasteringRing.Visibility = Visibility.Collapsed;
L1MasteringSID.Visibility = Visibility.Collapsed;
L1Toolstamp.Visibility = Visibility.Collapsed;
L1MouldSID.Label = "Mould SID";
L1AdditionalMould.Label = "Additional Mould";
#endif
}
break;
// All other media we assume to have no rings
default:
#if NET35
_L0Info!.Visibility = Visibility.Collapsed;
_L1Info!.Visibility = Visibility.Collapsed;
_L2Info!.Visibility = Visibility.Collapsed;
_L3Info!.Visibility = Visibility.Collapsed;
#else
L0Info.Visibility = Visibility.Collapsed;
L1Info.Visibility = Visibility.Collapsed;
L2Info.Visibility = Visibility.Collapsed;
L3Info.Visibility = Visibility.Collapsed;
#endif
break;
}
}
@@ -345,8 +686,30 @@ namespace MPF.UI.Core.Windows
var system = submissionInfo?.CommonDiscInfo?.System;
switch (system)
{
case RedumpSystem.NintendoWiiU:
#if NET35
_DiscKeyTextBox!.Visibility = Visibility.Visible;
#else
DiscKeyTextBox.Visibility = Visibility.Visible;
#endif
break;
case RedumpSystem.SonyPlayStation2:
#if NET35
_LanguageSelectionGrid!.Visibility = Visibility.Visible;
#else
LanguageSelectionGrid.Visibility = Visibility.Visible;
#endif
break;
case RedumpSystem.SonyPlayStation3:
#if NET35
_DiscKeyTextBox!.Visibility = Visibility.Visible;
_DiscIDTextBox!.Visibility = Visibility.Visible;
#else
DiscKeyTextBox.Visibility = Visibility.Visible;
DiscIDTextBox.Visibility = Visibility.Visible;
#endif
break;
}
}

View File

@@ -76,7 +76,7 @@
</StackPanel>
<Label Panel.ZIndex="0" Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
<Label.Content>
<TextBlock TextAlignment="Center"><Bold>Media Preservation Frontend</Bold></TextBlock>
<TextBlock TextAlignment="Center"><Run FontWeight="Bold" Text="Media Preservation Frontend" /></TextBlock>
</Label.Content>
<Label.ContextMenu>
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"

View File

@@ -2,8 +2,8 @@ using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using MPF.Core;
using MPF.Core.UI.ViewModels;
using MPF.UI.Core.UserControls;
using SabreTools.RedumpLib;
using SabreTools.RedumpLib.Data;
using WPFCustomMessageBox;
@@ -18,12 +18,56 @@ namespace MPF.UI.Core.Windows
/// </summary>
public MainViewModel MainViewModel => DataContext as MainViewModel ?? new MainViewModel();
#if NET35
#region Top Menu Bar
private MenuItem? _AboutMenuItem => ItemHelper.FindChild<MenuItem>(this, "AboutMenuItem");
private MenuItem? _AppExitMenuItem => ItemHelper.FindChild<MenuItem>(this, "AppExitMenuItem");
private MenuItem? _CheckForUpdatesMenuItem => ItemHelper.FindChild<MenuItem>(this, "CheckForUpdatesMenuItem");
private MenuItem? _DebugViewMenuItem => ItemHelper.FindChild<MenuItem>(this, "DebugViewMenuItem");
private MenuItem? _OptionsMenuItem => ItemHelper.FindChild<MenuItem>(this, "OptionsMenuItem");
#endregion
#region Settings
private ComboBox? _DriveLetterComboBox => ItemHelper.FindChild<ComboBox>(this, "DriveLetterComboBox");
private ComboBox? _DriveSpeedComboBox => ItemHelper.FindChild<ComboBox>(this, "DriveSpeedComboBox");
private ComboBox? _DumpingProgramComboBox => ItemHelper.FindChild<ComboBox>(this, "DumpingProgramComboBox");
private CheckBox? _EnableParametersCheckBox => ItemHelper.FindChild<CheckBox>(this, "EnableParametersCheckBox");
private ComboBox? _MediaTypeComboBox => ItemHelper.FindChild<ComboBox>(this, "MediaTypeComboBox");
private Button? _OutputPathBrowseButton => ItemHelper.FindChild<Button>(this, "OutputPathBrowseButton");
private TextBox? _OutputPathTextBox => ItemHelper.FindChild<TextBox>(this, "OutputPathTextBox");
private ComboBox? _SystemTypeComboBox => ItemHelper.FindChild<ComboBox>(this, "SystemTypeComboBox");
#endregion
#region Controls
private Button? _CopyProtectScanButton => ItemHelper.FindChild<Button>(this, "CopyProtectScanButton");
private Button? _MediaScanButton => ItemHelper.FindChild<Button>(this, "MediaScanButton");
private Button? _StartStopButton => ItemHelper.FindChild<Button>(this, "StartStopButton");
private Button? _UpdateVolumeLabel => ItemHelper.FindChild<Button>(this, "UpdateVolumeLabel");
#endregion
#region Status
private LogOutput? _LogOutput => ItemHelper.FindChild<LogOutput>(this, "LogOutput");
#endregion
#endif
/// <summary>
/// Constructor
/// </summary>
public MainWindow()
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
#if NET452_OR_GREATER || NETCOREAPP
var chrome = new System.Windows.Shell.WindowChrome
@@ -53,9 +97,17 @@ namespace MPF.UI.Core.Windows
// Display the debug option in the menu, if necessary
if (MainViewModel.Options.ShowDebugViewMenuItem)
#if NET35
_DebugViewMenuItem!.Visibility = Visibility.Visible;
#else
DebugViewMenuItem.Visibility = Visibility.Visible;
#endif
#if NET35
MainViewModel.Init(_LogOutput!.EnqueueLog, DisplayUserMessage, ShowDiscInformationWindow);
#else
MainViewModel.Init(LogOutput.EnqueueLog, DisplayUserMessage, ShowDiscInformationWindow);
#endif
// Set the UI color scheme according to the options
ApplyTheme();
@@ -80,29 +132,58 @@ namespace MPF.UI.Core.Windows
public void AddEventHandlers()
{
// Menu Bar Click
#if NET35
_AboutMenuItem!.Click += AboutClick;
_AppExitMenuItem!.Click += AppExitClick;
_CheckForUpdatesMenuItem!.Click += CheckForUpdatesClick;
_DebugViewMenuItem!.Click += DebugViewClick;
_OptionsMenuItem!.Click += OptionsMenuItemClick;
#else
AboutMenuItem.Click += AboutClick;
AppExitMenuItem.Click += AppExitClick;
CheckForUpdatesMenuItem.Click += CheckForUpdatesClick;
DebugViewMenuItem.Click += DebugViewClick;
OptionsMenuItem.Click += OptionsMenuItemClick;
#endif
// User Area Click
#if NET35
_CopyProtectScanButton!.Click += CopyProtectScanButtonClick;
_EnableParametersCheckBox!.Click += EnableParametersCheckBoxClick;
_MediaScanButton!.Click += MediaScanButtonClick;
_UpdateVolumeLabel!.Click += UpdateVolumeLabelClick;
_OutputPathBrowseButton!.Click += OutputPathBrowseButtonClick;
_StartStopButton!.Click += StartStopButtonClick;
#else
CopyProtectScanButton.Click += CopyProtectScanButtonClick;
EnableParametersCheckBox.Click += EnableParametersCheckBoxClick;
MediaScanButton.Click += MediaScanButtonClick;
UpdateVolumeLabel.Click += UpdateVolumeLabelClick;
OutputPathBrowseButton.Click += OutputPathBrowseButtonClick;
StartStopButton.Click += StartStopButtonClick;
#endif
// User Area SelectionChanged
#if NET35
_SystemTypeComboBox!.SelectionChanged += SystemTypeComboBoxSelectionChanged;
_MediaTypeComboBox!.SelectionChanged += MediaTypeComboBoxSelectionChanged;
_DriveLetterComboBox!.SelectionChanged += DriveLetterComboBoxSelectionChanged;
_DriveSpeedComboBox!.SelectionChanged += DriveSpeedComboBoxSelectionChanged;
_DumpingProgramComboBox!.SelectionChanged += DumpingProgramComboBoxSelectionChanged;
#else
SystemTypeComboBox.SelectionChanged += SystemTypeComboBoxSelectionChanged;
MediaTypeComboBox.SelectionChanged += MediaTypeComboBoxSelectionChanged;
DriveLetterComboBox.SelectionChanged += DriveLetterComboBoxSelectionChanged;
DriveSpeedComboBox.SelectionChanged += DriveSpeedComboBoxSelectionChanged;
DumpingProgramComboBox.SelectionChanged += DumpingProgramComboBoxSelectionChanged;
#endif
// User Area TextChanged
#if NET35
_OutputPathTextBox!.TextChanged += OutputPathTextBoxTextChanged;
#else
OutputPathTextBox.TextChanged += OutputPathTextBoxTextChanged;
#endif
}
/// <summary>
@@ -264,7 +345,7 @@ namespace MPF.UI.Core.Windows
theme.Apply();
}
#endregion
#endregion
#region Event Handlers

View File

@@ -464,7 +464,10 @@
<Label>
<Label.Content>
<TextBlock TextWrapping="Wrap"><Bold Foreground="Red">WARNING:</Bold> If you choose to enable validation and information retrieval, you are responsible for ensuring that all data populated matches your actual media. Some information may be marked to check for validity as a reminder, but all information should be subject to the same scrutiny.</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run FontWeight="Bold" Foreground="Red" Text="WARNING:" />
<Run Text="If you choose to enable validation and information retrieval, you are responsible for ensuring that all data populated matches your actual media. Some information may be marked to check for validity as a reminder, but all information should be subject to the same scrutiny." />
</TextBlock>
</Label.Content>
</Label>
</StackPanel>

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using MPF.Core.Data;
using MPF.Core.UI.ViewModels;
@@ -19,12 +20,28 @@ namespace MPF.UI.Core.Windows
/// </summary>
public OptionsViewModel OptionsViewModel => DataContext as OptionsViewModel ?? new OptionsViewModel(new Options());
#if NET35
private System.Windows.Controls.Button? _AaruPathButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "AaruPathButton");
private System.Windows.Controls.Button? _AcceptButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "AcceptButton");
private System.Windows.Controls.Button? _CancelButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "CancelButton");
private System.Windows.Controls.Button? _DefaultOutputPathButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "DefaultOutputPathButton");
private System.Windows.Controls.Button? _DiscImageCreatorPathButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "DiscImageCreatorPathButton");
private System.Windows.Controls.Button? _RedumperPathButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "RedumperPathButton");
private System.Windows.Controls.Button? _RedumpLoginTestButton => ItemHelper.FindChild<System.Windows.Controls.Button>(this, "RedumpLoginTestButton");
private PasswordBox? _RedumpPasswordBox => ItemHelper.FindChild<PasswordBox>(this, "RedumpPasswordBox");
private System.Windows.Controls.TextBox? _RedumpUsernameTextBox => ItemHelper.FindChild<System.Windows.Controls.TextBox>(this, "RedumpUsernameTextBox");
#endif
/// <summary>
/// Constructor
/// </summary>
public OptionsWindow(Options options)
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
#if NET40_OR_GREATER || NETCOREAPP
DumpSpeedCDTextBox.IsReadOnlyCaretVisible = false;
@@ -44,9 +61,24 @@ namespace MPF.UI.Core.Windows
DataContext = new OptionsViewModel(options);
// Set initial value for binding
#if NET35
_RedumpPasswordBox!.Password = options.RedumpPassword;
#else
RedumpPasswordBox.Password = options.RedumpPassword;
#endif
// Add handlers
#if NET35
_AaruPathButton!.Click += BrowseForPathClick;
_DiscImageCreatorPathButton!.Click += BrowseForPathClick;
_RedumperPathButton!.Click += BrowseForPathClick;
_DefaultOutputPathButton!.Click += BrowseForPathClick;
_AcceptButton!.Click += OnAcceptClick;
_CancelButton!.Click += OnCancelClick;
_RedumpPasswordBox!.PasswordChanged += OnPasswordChanged;
_RedumpLoginTestButton!.Click += OnRedumpTestClick;
#else
AaruPathButton.Click += BrowseForPathClick;
DiscImageCreatorPathButton.Click += BrowseForPathClick;
RedumperPathButton.Click += BrowseForPathClick;
@@ -56,6 +88,7 @@ namespace MPF.UI.Core.Windows
CancelButton.Click += OnCancelClick;
RedumpPasswordBox.PasswordChanged += OnPasswordChanged;
RedumpLoginTestButton.Click += OnRedumpTestClick;
#endif
}
/// <summary>
@@ -165,7 +198,11 @@ namespace MPF.UI.Core.Windows
/// </summary>
private async Task ValidateRedumpCredentials()
{
#if NET35
(bool? success, string? message) = await OptionsViewModel.TestRedumpLogin(_RedumpUsernameTextBox!.Text, _RedumpPasswordBox!.Password);
#else
(bool? success, string? message) = await OptionsViewModel.TestRedumpLogin(RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
#endif
if (success == true)
CustomMessageBox.Show(this, message, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
@@ -175,7 +212,7 @@ namespace MPF.UI.Core.Windows
CustomMessageBox.Show(this, message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
#endregion
#endregion
#region Event Handlers
@@ -208,7 +245,11 @@ namespace MPF.UI.Core.Windows
/// </summary>
private void OnPasswordChanged(object sender, EventArgs e)
{
#if NET35
OptionsViewModel.Options.RedumpPassword = _RedumpPasswordBox!.Password;
#else
OptionsViewModel.Options.RedumpPassword = RedumpPasswordBox.Password;
#endif
}
/// <summary>
@@ -224,6 +265,6 @@ namespace MPF.UI.Core.Windows
private async void OnRedumpTestClick(object sender, EventArgs e) => await ValidateRedumpCredentials();
#endif
#endregion
#endregion
}
}

View File

@@ -25,7 +25,7 @@
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
<Label.Content>
<TextBlock TextAlignment="Center"><Bold>Ring Code Guide</Bold></TextBlock>
<Run FontWeight="Bold" BaselineAlignment="Center" Text="Ring Code Guide" />
</Label.Content>
<Label.ContextMenu>
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
@@ -81,22 +81,34 @@
RenderOptions.BitmapScalingMode="HighQuality" />
<Label Grid.Row="1">
<Label.Content>
<TextBlock><Bold Foreground="Red">1. Mastering Ring:</Bold> Sony DADC&lt;tab&gt;A0100368905-0101&lt;tab&gt;13</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Red" Text="1. Mastering Ring:" />
<Run Text=" Sony DADC&lt;tab&gt;A0100368905-0101&lt;tab&gt;13" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="2">
<Label.Content>
<TextBlock><Bold Foreground="Green">2. Mastering SID:</Bold> IFPI L553</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Green" Text="2. Mastering SID:" />
<Run Text=" IFPI L553" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="3">
<Label.Content>
<TextBlock><Bold Foreground="Purple">3. Toolstamp/Mastering Code:</Bold> A2</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Purple" Text="3. Toolstamp/Mastering Code:" />
<Run Text=" A2" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="4">
<Label.Content>
<TextBlock><Bold Foreground="LightBlue">4. Mould SID:</Bold> IFPI 94V1</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="LightBlue" Text="4. Mould SID:" />
<Run Text=" IFPI 94V1" />
</TextBlock>
</Label.Content>
</Label>
</Grid>
@@ -122,27 +134,42 @@
RenderOptions.BitmapScalingMode="HighQuality" />
<Label Grid.Row="1">
<Label.Content>
<TextBlock><Bold Foreground="Red">1. Outer Mastering Ring:</Bold> IM01501A-L1&lt;tab&gt;03 +&lt;tab&gt;+</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Red" Text="1. Outer Mastering Ring:" />
<Run Text=" IM01501A-L1&lt;tab&gt;03 +&lt;tab&gt;+" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="2">
<Label.Content>
<TextBlock><Bold Foreground="Green">2. Inner Mastering Ring:</Bold> IM01501A-L0&lt;tab&gt;01 +&lt;tab&gt;+</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Green" Text="2. Inner Mastering Ring:" />
<Run Text=" IM01501A-L0&lt;tab&gt;01 +&lt;tab&gt;+" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="3">
<Label.Content>
<TextBlock><Bold Foreground="Purple">3. Outer Mastering SID:</Bold> IFPI LB48</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="Purple" Text="3. Outer Mastering SID:" />
<Run Text=" IFPI LB48" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="4">
<Label.Content>
<TextBlock><Bold Foreground="LightBlue">4. Inner Mastering SID:</Bold> IFPI LB48</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Foreground="LightBlue" Text="4. Inner Mastering SID:" />
<Run Text=" IFPI LB48" />
</TextBlock>
</Label.Content>
</Label>
<Label Grid.Row="5">
<Label.Content>
<TextBlock><Bold>Note:</Bold> See the 1-Layer guide for more details on additional fields</TextBlock>
<TextBlock>
<Run FontWeight="Bold" Text="Note:" />
<Run Text=" See the 1-Layer guide for more details on additional fields" />
</TextBlock>
</Label.Content>
</Label>
</Grid>

View File

@@ -7,7 +7,9 @@
{
public RingCodeGuideWindow()
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
#if NET452_OR_GREATER || NETCOREAPP
var chrome = new System.Windows.Shell.WindowChrome

View File

@@ -17,7 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.github\ISSUE_TEMPLATE\informational.md = .github\ISSUE_TEMPLATE\informational.md
.github\ISSUE_TEMPLATE\issue-report.md = .github\ISSUE_TEMPLATE\issue-report.md
publish-nix.sh = publish-nix.sh
publish-win.bat = publish-win.bat
publish-win.ps1 = publish-win.ps1
README.md = README.md
EndProjectSection
EndProject

View File

@@ -1,7 +1,6 @@
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:windows="clr-namespace:MPF.UI.Core.Windows;assembly=MPF.UI.Core"
x:Class="MPF.App">
<Application.MainWindow>
@@ -205,92 +204,7 @@
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom" />
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ComboBoxToggleButton}"/>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<!--<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>--> <!-- Not supported in .NET Framework 3.5 or 4.0 -->
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<SolidColorBrush x:Key="TextBox.Static.Background" Color="#FFFFFFFF"/>
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<!--<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>--> <!-- Not supported in .NET Framework 3.5 -->
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom" />
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ComboBoxToggleButton}"/>
<Border x:Name="border" Background="{DynamicResource TextBox.Static.Background}" Margin="{TemplateBinding BorderThickness}">
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{DynamicResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<!--<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>--> <!-- Not supported in .NET Framework 3.5 or 4.0 -->
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="CustomComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
<Setter Property="Background" Value="{DynamicResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ComboBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<!--<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>--> <!-- Not supported in .NET Framework 3.5 -->
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{DynamicResource ComboBoxTemplate}"/>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template" Value="{DynamicResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- ContextMenu -->
<SolidColorBrush x:Key="ContextMenu.Static.Border" Color="#FF888888"/>
@@ -336,8 +250,8 @@
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
<Border x:Name="SubMenuBorder" BorderBrush="{DynamicResource MenuItem.SubMenu.Border}" BorderThickness="1" Background="{DynamicResource MenuItem.SubMenu.Background}" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<!-- Grid RenderOptions.ClearTypeHint="Enabled">--> <!-- Not supported in .NET Framework 3.5 -->
<Grid>
<!--<Grid RenderOptions.ClearTypeHint="Enabled">--> <!-- Not supported in .NET Framework 3.5 -->
<Grid> <!-- Not supported in .NET Framework 3.5 -->
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
@@ -379,67 +293,6 @@
<SolidColorBrush x:Key="ProgressBar.Progress" Color="#FF06B025"/>
<SolidColorBrush x:Key="ProgressBar.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="ProgressBar.Border" Color="#FFBCBCBC"/>
<Style x:Key="CustomProgressBarStyle" TargetType="{x:Type ProgressBar}">
<Setter Property="Foreground" Value="{DynamicResource ProgressBar.Progress}"/>
<Setter Property="Background" Value="{DynamicResource ProgressBar.Background}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ProgressBar.Border}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid x:Name="TemplateRoot">
<!-- Not supported in .NET Framework 3.5 -->
<!--<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="Animation">
<EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.25"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0.25"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="Animation">
<EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
<EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>-->
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
<Rectangle x:Name="PART_Track"/>
<Grid x:Name="PART_Indicator" ClipToBounds="true" HorizontalAlignment="Left">
<Rectangle x:Name="Indicator" Fill="{TemplateBinding Foreground}"/>
<Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="LayoutTransform" TargetName="TemplateRoot">
<Setter.Value>
<RotateTransform Angle="-90"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsIndeterminate" Value="true">
<Setter Property="Visibility" TargetName="Indicator" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ScrollViewer -->
<SolidColorBrush x:Key="ScrollViewer.ScrollBar.Background" Color="LightGray"/>

View File

@@ -1,11 +1,7 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Microsoft.Windows.Themes;
using System.Windows.Markup;
namespace MPF
{
@@ -15,173 +11,485 @@ namespace MPF
public partial class App : Application
{
#if NET40_OR_GREATER || NETCOREAPP
#if NET35_OR_GREATER || NETCOREAPP
#region ControlTemplates
/// <summary>
/// ComboBoxTemplate ControlTemplate XAML (.NET Framework 4.0 and above)
/// </summary>
private const string _comboBoxTemplateDefault = @"<ControlTemplate TargetType=""{x:Type ComboBox}"">
<Grid x:Name=""templateRoot"" SnapsToDevicePixels=""true"">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""*""/>
<ColumnDefinition MinWidth=""{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"" Width=""0""/>
</Grid.ColumnDefinitions>
<Popup x:Name=""PART_Popup"" AllowsTransparency=""true"" Grid.ColumnSpan=""2"" IsOpen=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Margin=""1"" PopupAnimation=""{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"" Placement=""Bottom"">
<themes:SystemDropShadowChrome x:Name=""shadow"" Color=""Transparent"" MaxHeight=""{TemplateBinding MaxDropDownHeight}"" MinWidth=""{Binding ActualWidth, ElementName=templateRoot}"">
<Border x:Name=""dropDownBorder"" BorderBrush=""{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"" BorderThickness=""1"" Background=""{DynamicResource {x:Static SystemColors.WindowBrushKey}}"">
<ScrollViewer x:Name=""DropDownScrollViewer"">
<Grid x:Name=""grid"" RenderOptions.ClearTypeHint=""Enabled"">
<Canvas x:Name=""canvas"" HorizontalAlignment=""Left"" Height=""0"" VerticalAlignment=""Top"" Width=""0"">
<Rectangle x:Name=""opaqueRect"" Fill=""{Binding Background, ElementName=dropDownBorder}"" Height=""{Binding ActualHeight, ElementName=dropDownBorder}"" Width=""{Binding ActualWidth, ElementName=dropDownBorder}""/>
</Canvas>
<ItemsPresenter x:Name=""ItemsPresenter"" KeyboardNavigation.DirectionalNavigation=""Contained"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}""/>
</Grid>
</ScrollViewer>
</Border>
</themes:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name=""toggleButton"" BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}"" Grid.ColumnSpan=""2"" IsChecked=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Style=""{DynamicResource ComboBoxToggleButton}""/>
<ContentPresenter x:Name=""contentPresenter"" ContentTemplate=""{TemplateBinding SelectionBoxItemTemplate}"" ContentTemplateSelector=""{TemplateBinding ItemTemplateSelector}"" Content=""{TemplateBinding SelectionBoxItem}"" ContentStringFormat=""{TemplateBinding SelectionBoxItemStringFormat}"" HorizontalAlignment=""{TemplateBinding HorizontalContentAlignment}"" IsHitTestVisible=""false"" Margin=""{TemplateBinding Padding}"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}"" VerticalAlignment=""{TemplateBinding VerticalContentAlignment}""/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""HasDropShadow"" SourceName=""PART_Popup"" Value=""true"">
<Setter Property=""Margin"" TargetName=""shadow"" Value=""0,0,5,5""/>
<Setter Property=""Color"" TargetName=""shadow"" Value=""#71000000""/>
</Trigger>
<Trigger Property=""HasItems"" Value=""false"">
<Setter Property=""Height"" TargetName=""dropDownBorder"" Value=""95""/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property=""IsGrouping"" Value=""true""/>
<Condition Property=""VirtualizingPanel.IsVirtualizingWhenGrouping"" Value=""false""/>
</MultiTrigger.Conditions>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""false""/>
</MultiTrigger>
<Trigger Property=""ScrollViewer.CanContentScroll"" SourceName=""DropDownScrollViewer"" Value=""false"">
<Setter Property=""Canvas.Top"" TargetName=""opaqueRect"" Value=""{Binding VerticalOffset, ElementName=DropDownScrollViewer}""/>
<Setter Property=""Canvas.Left"" TargetName=""opaqueRect"" Value=""{Binding HorizontalOffset, ElementName=DropDownScrollViewer}""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>";
/// <summary>
/// ComboBoxTemplate ControlTemplate XAML (.NET Framework 3.5)
/// </summary>
private const string _comboBoxTemplateNet35 = @"<ControlTemplate TargetType=""{x:Type ComboBox}"">
<Grid x:Name=""templateRoot"" SnapsToDevicePixels=""true"">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""*""/>
<ColumnDefinition MinWidth=""{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"" Width=""0""/>
</Grid.ColumnDefinitions>
<Popup x:Name=""PART_Popup"" AllowsTransparency=""true"" Grid.ColumnSpan=""2"" IsOpen=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Margin=""1"" PopupAnimation=""{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"" Placement=""Bottom"">
<Border x:Name=""dropDownBorder"" BorderBrush=""{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"" BorderThickness=""1"" Background=""{DynamicResource {x:Static SystemColors.WindowBrushKey}}"">
<ScrollViewer x:Name=""DropDownScrollViewer"">
<Grid x:Name=""grid"">
<Canvas x:Name=""canvas"" HorizontalAlignment=""Left"" Height=""0"" VerticalAlignment=""Top"" Width=""0"">
<Rectangle x:Name=""opaqueRect"" Fill=""{Binding Background, ElementName=dropDownBorder}"" Height=""{Binding ActualHeight, ElementName=dropDownBorder}"" Width=""{Binding ActualWidth, ElementName=dropDownBorder}""/>
</Canvas>
<ItemsPresenter x:Name=""ItemsPresenter"" KeyboardNavigation.DirectionalNavigation=""Contained"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}""/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
<ToggleButton x:Name=""toggleButton"" BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}"" Grid.ColumnSpan=""2"" IsChecked=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Style=""{DynamicResource ComboBoxToggleButton}""/>
<ContentPresenter x:Name=""contentPresenter"" ContentTemplate=""{TemplateBinding SelectionBoxItemTemplate}"" ContentTemplateSelector=""{TemplateBinding ItemTemplateSelector}"" Content=""{TemplateBinding SelectionBoxItem}"" ContentStringFormat=""{TemplateBinding SelectionBoxItemStringFormat}"" HorizontalAlignment=""{TemplateBinding HorizontalContentAlignment}"" IsHitTestVisible=""false"" Margin=""{TemplateBinding Padding}"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}"" VerticalAlignment=""{TemplateBinding VerticalContentAlignment}""/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""HasItems"" Value=""false"">
<Setter Property=""Height"" TargetName=""dropDownBorder"" Value=""95""/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property=""IsGrouping"" Value=""true""/>
</MultiTrigger.Conditions>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""false""/>
</MultiTrigger>
<Trigger Property=""ScrollViewer.CanContentScroll"" SourceName=""DropDownScrollViewer"" Value=""false"">
<Setter Property=""Canvas.Top"" TargetName=""opaqueRect"" Value=""{Binding VerticalOffset, ElementName=DropDownScrollViewer}""/>
<Setter Property=""Canvas.Left"" TargetName=""opaqueRect"" Value=""{Binding HorizontalOffset, ElementName=DropDownScrollViewer}""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>";
/// <summary>
/// ComboBoxEditableTemplate ControlTemplate XAML (.NET Framework 4.0 and above)
/// </summary>
private const string _comboBoxEditableTemplateDefault = @"<ControlTemplate TargetType=""{x:Type ComboBox}"">
<Grid x:Name=""templateRoot"" SnapsToDevicePixels=""true"">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""*""/>
<ColumnDefinition MinWidth=""{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"" Width=""0""/>
</Grid.ColumnDefinitions>
<Popup x:Name=""PART_Popup"" AllowsTransparency=""true"" Grid.ColumnSpan=""2"" IsOpen=""{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"" PopupAnimation=""{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"" Placement=""Bottom"">
<themes:SystemDropShadowChrome x:Name=""shadow"" Color=""Transparent"" MaxHeight=""{TemplateBinding MaxDropDownHeight}"" MinWidth=""{Binding ActualWidth, ElementName=templateRoot}"">
<Border x:Name=""dropDownBorder"" BorderBrush=""{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"" BorderThickness=""1"" Background=""{DynamicResource {x:Static SystemColors.WindowBrushKey}}"">
<ScrollViewer x:Name=""DropDownScrollViewer"">
<Grid x:Name=""grid"" RenderOptions.ClearTypeHint=""Enabled"">
<Canvas x:Name=""canvas"" HorizontalAlignment=""Left"" Height=""0"" VerticalAlignment=""Top"" Width=""0"">
<Rectangle x:Name=""opaqueRect"" Fill=""{Binding Background, ElementName=dropDownBorder}"" Height=""{Binding ActualHeight, ElementName=dropDownBorder}"" Width=""{Binding ActualWidth, ElementName=dropDownBorder}""/>
</Canvas>
<ItemsPresenter x:Name=""ItemsPresenter"" KeyboardNavigation.DirectionalNavigation=""Contained"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}""/>
</Grid>
</ScrollViewer>
</Border>
</themes:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name=""toggleButton"" BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}"" Grid.ColumnSpan=""2"" IsChecked=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Style=""{DynamicResource ComboBoxToggleButton}""/>
<Border x:Name=""border"" Background=""{DynamicResource TextBox.Static.Background}"" Margin=""{TemplateBinding BorderThickness}"">
<TextBox x:Name=""PART_EditableTextBox"" HorizontalContentAlignment=""{TemplateBinding HorizontalContentAlignment}"" IsReadOnly=""{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"" Margin=""{TemplateBinding Padding}"" Style=""{DynamicResource ComboBoxEditableTextBox}"" VerticalContentAlignment=""{TemplateBinding VerticalContentAlignment}""/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""IsEnabled"" Value=""false"">
<Setter Property=""Opacity"" TargetName=""border"" Value=""0.56""/>
</Trigger>
<Trigger Property=""IsKeyboardFocusWithin"" Value=""true"">
<Setter Property=""Foreground"" Value=""Black""/>
</Trigger>
<Trigger Property=""HasDropShadow"" SourceName=""PART_Popup"" Value=""true"">
<Setter Property=""Margin"" TargetName=""shadow"" Value=""0,0,5,5""/>
<Setter Property=""Color"" TargetName=""shadow"" Value=""#71000000""/>
</Trigger>
<Trigger Property=""HasItems"" Value=""false"">
<Setter Property=""Height"" TargetName=""dropDownBorder"" Value=""95""/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property=""IsGrouping"" Value=""true""/>
<Condition Property=""VirtualizingPanel.IsVirtualizingWhenGrouping"" Value=""false""/>
</MultiTrigger.Conditions>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""false""/>
</MultiTrigger>
<Trigger Property=""ScrollViewer.CanContentScroll"" SourceName=""DropDownScrollViewer"" Value=""false"">
<Setter Property=""Canvas.Top"" TargetName=""opaqueRect"" Value=""{Binding VerticalOffset, ElementName=DropDownScrollViewer}""/>
<Setter Property=""Canvas.Left"" TargetName=""opaqueRect"" Value=""{Binding HorizontalOffset, ElementName=DropDownScrollViewer}""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>";
/// <summary>
/// ComboBoxEditableTemplate ControlTemplate XAML (.NET Framework 3.5)
/// </summary>
private const string _comboBoxEditableTemplateNet35 = @"<ControlTemplate TargetType=""{x:Type ComboBox}"">
<Grid x:Name=""templateRoot"" SnapsToDevicePixels=""true"">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""*""/>
<ColumnDefinition MinWidth=""{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"" Width=""0""/>
</Grid.ColumnDefinitions>
<Popup x:Name=""PART_Popup"" AllowsTransparency=""true"" Grid.ColumnSpan=""2"" IsOpen=""{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"" PopupAnimation=""{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"" Placement=""Bottom"">
<Border x:Name=""dropDownBorder"" BorderBrush=""{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"" BorderThickness=""1"" Background=""{DynamicResource {x:Static SystemColors.WindowBrushKey}}"">
<ScrollViewer x:Name=""DropDownScrollViewer"">
<Grid x:Name=""grid"">
<Canvas x:Name=""canvas"" HorizontalAlignment=""Left"" Height=""0"" VerticalAlignment=""Top"" Width=""0"">
<Rectangle x:Name=""opaqueRect"" Fill=""{Binding Background, ElementName=dropDownBorder}"" Height=""{Binding ActualHeight, ElementName=dropDownBorder}"" Width=""{Binding ActualWidth, ElementName=dropDownBorder}""/>
</Canvas>
<ItemsPresenter x:Name=""ItemsPresenter"" KeyboardNavigation.DirectionalNavigation=""Contained"" SnapsToDevicePixels=""{TemplateBinding SnapsToDevicePixels}""/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
<ToggleButton x:Name=""toggleButton"" BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}"" Grid.ColumnSpan=""2"" IsChecked=""{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"" Style=""{DynamicResource ComboBoxToggleButton}""/>
<Border x:Name=""border"" Background=""{DynamicResource TextBox.Static.Background}"" Margin=""{TemplateBinding BorderThickness}"">
<TextBox x:Name=""PART_EditableTextBox"" HorizontalContentAlignment=""{TemplateBinding HorizontalContentAlignment}"" IsReadOnly=""{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"" Margin=""{TemplateBinding Padding}"" Style=""{DynamicResource ComboBoxEditableTextBox}"" VerticalContentAlignment=""{TemplateBinding VerticalContentAlignment}""/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""IsEnabled"" Value=""false"">
<Setter Property=""Opacity"" TargetName=""border"" Value=""0.56""/>
</Trigger>
<Trigger Property=""IsKeyboardFocusWithin"" Value=""true"">
<Setter Property=""Foreground"" Value=""Black""/>
</Trigger>
<Trigger Property=""HasItems"" Value=""false"">
<Setter Property=""Height"" TargetName=""dropDownBorder"" Value=""95""/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property=""IsGrouping"" Value=""true""/>
</MultiTrigger.Conditions>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""false""/>
</MultiTrigger>
<Trigger Property=""ScrollViewer.CanContentScroll"" SourceName=""DropDownScrollViewer"" Value=""false"">
<Setter Property=""Canvas.Top"" TargetName=""opaqueRect"" Value=""{Binding VerticalOffset, ElementName=DropDownScrollViewer}""/>
<Setter Property=""Canvas.Left"" TargetName=""opaqueRect"" Value=""{Binding HorizontalOffset, ElementName=DropDownScrollViewer}""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>";
#endregion
#region Styles
/// <summary>
/// ComboBoxEditableTextBox Style XAML (.NET Framework 4.0 and above)
/// </summary>
private const string _comboBoxEditableTextBoxStyleDefault = @"<Style TargetType=""{x:Type TextBox}"">
<Setter Property=""OverridesDefaultStyle"" Value=""true""/>
<Setter Property=""AllowDrop"" Value=""true""/>
<Setter Property=""MinWidth"" Value=""0""/>
<Setter Property=""MinHeight"" Value=""0""/>
<Setter Property=""FocusVisualStyle"" Value=""{x:Null}""/>
<Setter Property=""ScrollViewer.PanningMode"" Value=""VerticalFirst""/>
<Setter Property=""Stylus.IsFlicksEnabled"" Value=""False""/>
<Setter Property=""Template"">
<Setter.Value>
<ControlTemplate TargetType=""{x:Type TextBox}"">
<ScrollViewer x:Name=""PART_ContentHost"" Background=""Transparent"" Focusable=""false"" HorizontalScrollBarVisibility=""Hidden"" VerticalScrollBarVisibility=""Hidden""/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>";
/// <summary>
/// ComboBoxEditableTextBox Style XAML (.NET Framework 3.5)
/// </summary>
private const string _comboBoxEditableTextBoxStyleNet35 = @"<Style TargetType=""{x:Type TextBox}"">
<Setter Property=""OverridesDefaultStyle"" Value=""true""/>
<Setter Property=""AllowDrop"" Value=""true""/>
<Setter Property=""MinWidth"" Value=""0""/>
<Setter Property=""MinHeight"" Value=""0""/>
<Setter Property=""FocusVisualStyle"" Value=""{x:Null}""/>
<Setter Property=""Stylus.IsFlicksEnabled"" Value=""False""/>
<Setter Property=""Template"">
<Setter.Value>
<ControlTemplate TargetType=""{x:Type TextBox}"">
<ScrollViewer x:Name=""PART_ContentHost"" Background=""Transparent"" Focusable=""false"" HorizontalScrollBarVisibility=""Hidden"" VerticalScrollBarVisibility=""Hidden""/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>";
/// <summary>
/// CustomComboBoxStyle Style XAML (.NET Framework 4.0 and above)
/// </summary>
private const string _customComboBoxStyleDefault = @"<Style x:Key=""CustomComboBoxStyle"" TargetType=""{x:Type ComboBox}"">
<Setter Property=""FocusVisualStyle"" Value=""{DynamicResource FocusVisual}""/>
<Setter Property=""Background"" Value=""{DynamicResource ComboBox.Static.Background}""/>
<Setter Property=""BorderBrush"" Value=""{DynamicResource ComboBox.Static.Border}""/>
<Setter Property=""Foreground"" Value=""{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}""/>
<Setter Property=""BorderThickness"" Value=""1""/>
<Setter Property=""ScrollViewer.HorizontalScrollBarVisibility"" Value=""Auto""/>
<Setter Property=""ScrollViewer.VerticalScrollBarVisibility"" Value=""Auto""/>
<Setter Property=""Padding"" Value=""6,3,5,3""/>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""true""/>
<Setter Property=""ScrollViewer.PanningMode"" Value=""VerticalFirst""/>
<Setter Property=""Stylus.IsFlicksEnabled"" Value=""False""/>
<Setter Property=""Template"" Value=""{DynamicResource ComboBoxTemplate}""/>
<Style.Triggers>
<Trigger Property=""IsEditable"" Value=""true"">
<Setter Property=""IsTabStop"" Value=""false""/>
<Setter Property=""Padding"" Value=""2""/>
<Setter Property=""Template"" Value=""{DynamicResource ComboBoxEditableTemplate}""/>
</Trigger>
</Style.Triggers>
</Style>";
/// <summary>
/// CustomComboBoxStyle Style XAML (.NET Framework 3.5)
/// </summary>
private const string _customComboBoxStyleNet35 = @"<Style TargetType=""{x:Type ComboBox}"">
<Setter Property=""FocusVisualStyle"" Value=""{DynamicResource FocusVisual}""/>
<Setter Property=""Background"" Value=""{DynamicResource ComboBox.Static.Background}""/>
<Setter Property=""BorderBrush"" Value=""{DynamicResource ComboBox.Static.Border}""/>
<Setter Property=""Foreground"" Value=""{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}""/>
<Setter Property=""BorderThickness"" Value=""1""/>
<Setter Property=""ScrollViewer.HorizontalScrollBarVisibility"" Value=""Auto""/>
<Setter Property=""ScrollViewer.VerticalScrollBarVisibility"" Value=""Auto""/>
<Setter Property=""Padding"" Value=""6,3,5,3""/>
<Setter Property=""ScrollViewer.CanContentScroll"" Value=""true""/>
<Setter Property=""Stylus.IsFlicksEnabled"" Value=""False""/>
<Setter Property=""Template"" Value=""{DynamicResource ComboBoxTemplate}""/>
<Style.Triggers>
<Trigger Property=""IsEditable"" Value=""true"">
<Setter Property=""IsTabStop"" Value=""false""/>
<Setter Property=""Padding"" Value=""2""/>
<Setter Property=""Template"" Value=""{DynamicResource ComboBoxEditableTemplate}""/>
</Trigger>
</Style.Triggers>
</Style>";
/// <summary>
/// CustomProgressBarStyle Style XAML (.NET Framework 4.0 and above)
/// </summary>
private const string _customProgressBarStyleDefault = @"<Style x:Key=""CustomProgressBarStyle"" TargetType=""{x:Type ProgressBar}"">
<Setter Property=""Foreground"" Value=""{DynamicResource ProgressBar.Progress}""/>
<Setter Property=""Background"" Value=""{DynamicResource ProgressBar.Background}""/>
<Setter Property=""BorderBrush"" Value=""{DynamicResource ProgressBar.Border}""/>
<Setter Property=""BorderThickness"" Value=""1""/>
<Setter Property=""Template"">
<Setter.Value>
<ControlTemplate TargetType=""{x:Type ProgressBar}"">
<Grid x:Name=""TemplateRoot"">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name=""CommonStates"">
<VisualState x:Name=""Determinate""/>
<VisualState x:Name=""Indeterminate"">
<Storyboard RepeatBehavior=""Forever"">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=""(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"" Storyboard.TargetName=""Animation"">
<EasingDoubleKeyFrame KeyTime=""0"" Value=""0.25""/>
<EasingDoubleKeyFrame KeyTime=""0:0:1"" Value=""0.25""/>
<EasingDoubleKeyFrame KeyTime=""0:0:2"" Value=""0.25""/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty=""(UIElement.RenderTransformOrigin)"" Storyboard.TargetName=""Animation"">
<EasingPointKeyFrame KeyTime=""0"" Value=""-0.5,0.5""/>
<EasingPointKeyFrame KeyTime=""0:0:1"" Value=""0.5,0.5""/>
<EasingPointKeyFrame KeyTime=""0:0:2"" Value=""1.5,0.5""/>
</PointAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}""/>
<Rectangle x:Name=""PART_Track""/>
<Grid x:Name=""PART_Indicator"" ClipToBounds=""true"" HorizontalAlignment=""Left"">
<Rectangle x:Name=""Indicator"" Fill=""{TemplateBinding Foreground}""/>
<Rectangle x:Name=""Animation"" Fill=""{TemplateBinding Foreground}"" RenderTransformOrigin=""0.5,0.5"">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""Orientation"" Value=""Vertical"">
<Setter Property=""LayoutTransform"" TargetName=""TemplateRoot"">
<Setter.Value>
<RotateTransform Angle=""-90""/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property=""IsIndeterminate"" Value=""true"">
<Setter Property=""Visibility"" TargetName=""Indicator"" Value=""Collapsed""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>";
/// <summary>
/// CustomProgressBarStyle Style XAML (.NET Framework 3.5)
/// </summary>
private const string _customProgressBarStyleNet35 = @"<Style TargetType=""{x:Type ProgressBar}"">
<Setter Property=""Foreground"" Value=""{DynamicResource ProgressBar.Progress}""/>
<Setter Property=""Background"" Value=""{DynamicResource ProgressBar.Background}""/>
<Setter Property=""BorderBrush"" Value=""{DynamicResource ProgressBar.Border}""/>
<Setter Property=""BorderThickness"" Value=""1""/>
<Setter Property=""Template"">
<Setter.Value>
<ControlTemplate TargetType=""{x:Type ProgressBar}"">
<Grid x:Name=""TemplateRoot"">
<Border BorderBrush=""{TemplateBinding BorderBrush}"" BorderThickness=""{TemplateBinding BorderThickness}"" Background=""{TemplateBinding Background}""/>
<Rectangle x:Name=""PART_Track""/>
<Grid x:Name=""PART_Indicator"" ClipToBounds=""true"" HorizontalAlignment=""Left"">
<Rectangle x:Name=""Indicator"" Fill=""{TemplateBinding Foreground}""/>
<Rectangle x:Name=""Animation"" Fill=""{TemplateBinding Foreground}"" RenderTransformOrigin=""0.5,0.5"">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property=""Orientation"" Value=""Vertical"">
<Setter Property=""LayoutTransform"" TargetName=""TemplateRoot"">
<Setter.Value>
<RotateTransform Angle=""-90""/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property=""IsIndeterminate"" Value=""true"">
<Setter Property=""Visibility"" TargetName=""Indicator"" Value=""Collapsed""/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>";
#endregion
public App()
{
#if NET40_OR_GREATER || NETCOREAPP
InitializeComponent();
#endif
AddDropShadowChrome("ComboBoxTemplate");
AddDropShadowChrome("ComboBoxEditableTemplate");
// Create control templates
CreateControlTemplate("ComboBoxTemplate");
CreateControlTemplate("ComboBoxEditableTemplate");
// Create styles
CreateStyle("ComboBoxEditableTextBox");
CreateStyle("CustomComboBoxStyle");
CreateStyle("CustomProgressBarStyle");
}
private void AddDropShadowChrome(string resourceName)
/// <summary>
/// Create an XAML parser context with the required namespaces
/// </summary>
private ParserContext CreateParserContext()
{
// Get the template resource
if (Resources[resourceName] is not ControlTemplate controlTemplate)
return;
var context = new ParserContext();
// Get the popup
if (controlTemplate.Resources["PART_Popup"] is not Popup popup)
return;
context.XmlnsDictionary[""] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
context.XmlnsDictionary["x"] = "http://schemas.microsoft.com/winfx/2006/xaml";
#if NETFRAMEWORK
context.XmlnsDictionary["themes"] = "clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero";
#else
context.XmlnsDictionary["themes"] = "clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2";
#endif
context.XamlTypeMapper = new XamlTypeMapper([]);
// Create the various nested items
var chrome = new SystemDropShadowChrome
{
Name = "shadow",
Color = Colors.Transparent,
};
var border = new Border
{
Name = "dropDownBorder",
BorderThickness = new Thickness(1),
};
var scrollViewer = new ScrollViewer { Name = "DropDownScrollViewer" };
var grid = new Grid { Name = "grid" };
RenderOptions.SetClearTypeHint(grid, ClearTypeHint.Enabled);
var canvas = new Canvas
{
Name = "canvas",
HorizontalAlignment = HorizontalAlignment.Left,
Height = 0,
VerticalAlignment = VerticalAlignment.Top,
Width = 0,
};
var rectangle = new Rectangle { Name = "opaqueRect" };
var itemsPresenter = new ItemsPresenter { Name = "ItemsPresenter" };
KeyboardNavigation.SetDirectionalNavigation(itemsPresenter, KeyboardNavigationMode.Contained);
return context;
}
// Set the bindings
BindingOperations.SetBinding(chrome, SystemDropShadowChrome.MaxHeightProperty, new Binding
/// <summary>
/// Create a named control template and add it to the current set of resources
/// </summary>
private void CreateControlTemplate(string resourceName)
{
var parserContext = CreateParserContext();
var controlTemplate = resourceName switch
{
Source = new TemplateBindingExtension(ComboBox.MaxDropDownHeightProperty),
});
BindingOperations.SetBinding(chrome, SystemDropShadowChrome.MinWidthProperty, new Binding
{
Source = ComboBox.ActualWidthProperty,
ElementName = "templateRoot",
});
BindingOperations.SetBinding(border, Border.BorderBrushProperty, new Binding
{
Source = new DynamicResourceExtension(new StaticResourceExtension(SystemColors.WindowFrameBrushKey)),
});
BindingOperations.SetBinding(border, Border.BackgroundProperty, new Binding
{
Source = new DynamicResourceExtension(new StaticResourceExtension(SystemColors.WindowBrushKey)),
});
BindingOperations.SetBinding(rectangle, Rectangle.FillProperty, new Binding
{
Source = Border.BackgroundProperty,
ElementName = "dropDownBorder",
});
BindingOperations.SetBinding(rectangle, Rectangle.HeightProperty, new Binding
{
Source = Border.ActualHeightProperty,
ElementName = "dropDownBorder",
});
BindingOperations.SetBinding(rectangle, Rectangle.WidthProperty, new Binding
{
Source = Border.ActualWidthProperty,
ElementName = "dropDownBorder",
});
BindingOperations.SetBinding(itemsPresenter, ItemsPresenter.SnapsToDevicePixelsProperty, new Binding
{
Source = new TemplateBindingExtension(ComboBox.SnapsToDevicePixelsProperty),
});
// Build the item tree
canvas.Children.Add(rectangle);
grid.Children.Add(canvas);
grid.Children.Add(itemsPresenter);
scrollViewer.Content = grid;
border.Child = scrollViewer;
chrome.Child = border;
// Add the tree to the popup
popup.Child = chrome;
// Get the triggers
var triggers = controlTemplate.Triggers;
if (triggers == null)
return;
// Create the new triggers
var hasDropShadow = new Trigger
{
Property = Popup.HasDropShadowProperty,
SourceName = "PART_Popup",
Value = "true",
};
var hasItems = new Trigger
{
Property = ComboBox.HasItemsProperty,
Value = "false",
};
var canContentScroll = new Trigger
{
Property = ScrollViewer.CanContentScrollProperty,
SourceName = "DropDownScrollViewer",
Value = "false",
#if NET35
"ComboBoxTemplate" => XamlReader.Parse(_comboBoxTemplateNet35, parserContext) as ControlTemplate,
"ComboBoxEditableTemplate" => XamlReader.Parse(_comboBoxEditableTemplateNet35, parserContext) as ControlTemplate,
#else
"ComboBoxTemplate" => XamlReader.Parse(_comboBoxTemplateDefault, parserContext) as ControlTemplate,
"ComboBoxEditableTemplate" => XamlReader.Parse(_comboBoxEditableTemplateDefault, parserContext) as ControlTemplate,
#endif
_ => throw new ArgumentException($"'{resourceName}' is not a recognized control template", nameof(resourceName)),
};
// Create and add the setters
hasDropShadow.Setters.Add(new Setter
{
Property = SystemDropShadowChrome.MarginProperty,
TargetName = "shadow",
Value = "0,0,5,5",
});
hasDropShadow.Setters.Add(new Setter
{
Property = SystemDropShadowChrome.ColorProperty,
TargetName = "shadow",
Value = "#71000000",
});
// Add the control template
Resources[resourceName] = controlTemplate;
}
hasItems.Setters.Add(new Setter
/// <summary>
/// Create a named style and add it to the current set of resources
/// </summary>
private void CreateStyle(string resourceName)
{
var parserContext = CreateParserContext();
var style = resourceName switch
{
Property = Border.HeightProperty,
TargetName = "dropDownBorder",
Value = "95",
});
#if NET35
"ComboBoxEditableTextBox" => XamlReader.Parse(_comboBoxEditableTextBoxStyleNet35, parserContext) as Style,
"CustomComboBoxStyle" => XamlReader.Parse(_customComboBoxStyleNet35, parserContext) as Style,
"CustomProgressBarStyle" => XamlReader.Parse(_customProgressBarStyleNet35, parserContext) as Style,
#else
"ComboBoxEditableTextBox" => XamlReader.Parse(_comboBoxEditableTextBoxStyleDefault, parserContext) as Style,
"CustomComboBoxStyle" => XamlReader.Parse(_customComboBoxStyleDefault, parserContext) as Style,
"CustomProgressBarStyle" => XamlReader.Parse(_customProgressBarStyleDefault, parserContext) as Style,
#endif
_ => throw new ArgumentException($"'{resourceName}' is not a recognized style", nameof(resourceName)),
};
canContentScroll.Setters.Add(new Setter
{
Property = Canvas.TopProperty,
TargetName = "opaqueRect",
Value = new Binding
{
Source = ScrollViewer.VerticalOffsetProperty,
ElementName = "DropDownScrollViewer",
},
});
canContentScroll.Setters.Add(new Setter
{
Property = Canvas.LeftProperty,
TargetName = "opaqueRect",
Value = new Binding
{
Source = ScrollViewer.HorizontalOffsetProperty,
ElementName = "DropDownScrollViewer",
},
});
// Add the new triggers
triggers.Add(hasDropShadow);
triggers.Add(hasItems);
triggers.Add(canContentScroll);
// Add the style
Resources[resourceName] = style;
}
#endif
}

View File

@@ -2,16 +2,17 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0-windows;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
<TargetFrameworks>net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0-windows;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
<OutputType>WinExe</OutputType>
<ApplicationIcon>Images\Icon.ico</ApplicationIcon>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<ImportFrameworkWinFXTargets Condition="$(TargetFramework.StartsWith(`net3`))">true</ImportFrameworkWinFXTargets>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<VersionPrefix>3.0.1</VersionPrefix>
<VersionPrefix>3.0.2</VersionPrefix>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
@@ -25,6 +26,14 @@
</PropertyGroup>
<!-- Special handling for Aero2 on non-Framework .NET -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net4`))">
<ReferenceWpfAeroTheme>true</ReferenceWpfAeroTheme>
<ReferenceWpfAero2Theme>false</ReferenceWpfAero2Theme>
<ReferenceWpfAeroLiteTheme>false</ReferenceWpfAeroLiteTheme>
<ReferenceWpfClassicTheme>false</ReferenceWpfClassicTheme>
<ReferenceWpfLunaTheme>false</ReferenceWpfLunaTheme>
<ReferenceWpfRoyaleTheme>false</ReferenceWpfRoyaleTheme>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`)) OR $(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<ReferenceWpfAeroTheme>false</ReferenceWpfAeroTheme>
<ReferenceWpfAero2Theme>true</ReferenceWpfAero2Theme>
@@ -47,6 +56,13 @@
<ProjectReference Include="..\MPF.UI.Core\MPF.UI.Core.csproj" />
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net3`))">
<Reference Include="PresentationBuildTasks" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
<Reference Include="PresentationCore" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll" />
<Reference Include="PresentationFramework" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll" />
<Reference Include="WindowsBase" HintPath="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
<Reference Include="PresentationFramework.Aero" />
</ItemGroup>
@@ -66,36 +82,36 @@
</ItemGroup>
<!-- Special handling for Aero2 on non-Framework .NET -->
<Target Name="SelectWpfThemeAssembly" AfterTargets="ResolveAssemblyReferences" Condition="'$(ReferenceWpfAeroTheme)' == 'true' Or&#xD;&#xA; '$(ReferenceWpfAero2Theme)' == 'true' Or&#xD;&#xA; '$(ReferenceWpfAeroLiteTheme)' == 'true' Or&#xD;&#xA; '$(ReferenceWpfClassicTheme)' == 'true' Or &#xD;&#xA; '$(ReferenceWpfLunaTheme)' == 'true' Or&#xD;&#xA; '$(ReferenceWpfRoyaleTheme)' == 'true'">
<ItemGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`)) OR $(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.Aero'">
<Target Name="SelectWpfThemeAssembly" AfterTargets="ResolveAssemblyReferences" Condition="'$(ReferenceWpfAeroTheme)' == 'true' OR '$(ReferenceWpfAero2Theme)' == 'true' OR '$(ReferenceWpfAeroLiteTheme)' == 'true' OR '$(ReferenceWpfClassicTheme)' == 'true' OR '$(ReferenceWpfLunaTheme)' == 'true' OR '$(ReferenceWpfRoyaleTheme)' == 'true'">
<ItemGroup>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.Aero'">
<Aliases Condition="'$(WpfAeroThemeAliases)'!=''">$(WpfAeroThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.Aero2'">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.Aero2'">
<Aliases Condition="'$(WpfAero2ThemeAliases)'!=''">$(WpfAero2ThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.AeroLite'">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.AeroLite'">
<Aliases Condition="'$(WpfAeroLiteThemeAliases)'!=''">$(WpfAeroLiteThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.Classic'">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.Classic'">
<Aliases Condition="'$(WpfClassicThemeAliases)'!=''">$(WpfClassicThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.Luna'">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.Luna'">
<Aliases Condition="'$(WpfLunaThemeAliases)'!=''">$(WpfLunaThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' And &#xD;&#xA; '%(ReferencePath.FileName)'=='PresentationFramework.Royale'">
<_WpfThemeAssemblies Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)'=='Microsoft.WindowsDesktop.App.Ref' AND '%(ReferencePath.FileName)'=='PresentationFramework.Royale'">
<Aliases Condition="'$(WpfRoyaleThemeAliases)'!=''">$(WpfRoyaleThemeAliases)</Aliases>
</_WpfThemeAssemblies>
<ReferencePath Remove="@(_WpfThemeAssemblies)" />
<ReferencePath Include="@(_WpfThemeAssemblies)" Condition="('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Aero' And '$(ReferenceWpfAeroTheme)'=='true') Or &#xD;&#xA; ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Aero2' And '$(ReferenceWpfAero2Theme)'=='true') Or &#xD;&#xA; ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.AeroLite' And '$(ReferenceWpfAeroLiteTheme)'=='true') Or &#xD;&#xA; ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Classic' And '$(ReferenceWpfClassicTheme)'=='true') Or &#xD;&#xA; ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Luna' And '$(ReferenceWpfLunaTheme)'=='true') Or&#xD;&#xA; ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Royale' And '$(ReferenceWpfRoyaleTheme)'=='true')" />
<ReferencePath Include="@(_WpfThemeAssemblies)" Condition="('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Aero' AND'$(ReferenceWpfAeroTheme)'=='true') OR ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Aero2' AND '$(ReferenceWpfAero2Theme)'=='true') OR ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.AeroLite' AND '$(ReferenceWpfAeroLiteTheme)'=='true') OR ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Classic' AND '$(ReferenceWpfClassicTheme)'=='true') OR ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Luna' AND '$(ReferenceWpfLunaTheme)'=='true') OR ('%(_WpfThemeAssemblies.FileName)'=='PresentationFramework.Royale' AND '$(ReferenceWpfRoyaleTheme)'=='true')" />
</ItemGroup>
</Target>
</Project>
</Project>

View File

@@ -60,9 +60,9 @@ Choose one of `win-x64`, `linux-x64`, or `osx-x64` depending on the machine you
### Build Scripts
Windows users may run `publish-win.bat` and Linux users may run `publish-nix.sh` to perform a full release build.
Windows users may run `publish-win.ps1` and Linux users may run `publish-nix.sh` to perform a full release build.
- `publish-win.bat` will build and package all variants of MPF UI and MPF.Check
- `publish-win.ps1` will build and package all variants of MPF UI and MPF.Check
- The script requires [7-zip commandline](https://www.7-zip.org/download.html) and [Git for Windows](https://git-scm.com/downloads) to be installed and in `PATH`
- `publish-nix.sh` will _only_ build and package all variants of MPF.Check
- The script requires `zip` and `git` to be installed and in `PATH`

View File

@@ -1,5 +1,5 @@
# version format
version: 3.0.1-{build}
version: 3.0.2-{build}
# pull request template
pull_requests:
@@ -48,8 +48,8 @@ after_build:
- 7z e DiscImageCreator_20230606.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Creator Release_ANSI\*
# Redumper
- ps: appveyor DownloadFile https://github.com/superg/redumper/releases/download/build_268/redumper-2023.11.27_build268-win64.zip
- 7z e redumper-2023.11.27_build268-win64.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Redumper redumper-2023.11.27_build268-win64\bin\*
- ps: appveyor DownloadFile https://github.com/superg/redumper/releases/download/build_271/redumper-2023.11.30_build271-win64.zip
- 7z e redumper-2023.11.30_build271-win64.zip -oMPF\bin\Debug\net8.0-windows\win-x64\publish\Programs\Redumper redumper-2023.11.30_build271-win64\bin\*
# Create MPF Debug archives
- cd %APPVEYOR_BUILD_FOLDER%\MPF\bin\Debug\net8.0-windows\win-x64\publish\

157
publish-win.ps1 Normal file
View File

@@ -0,0 +1,157 @@
# This batch file assumes the following:
# - .NET 8.0 (or newer) SDK is installed and in PATH
# - 7-zip commandline (7z.exe) is installed and in PATH
# - Git for Windows is installed and in PATH
# - The relevant commandline programs are already downloaded
# and put into their respective folders
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
# Optional parameters
param(
[Parameter(Mandatory = $false)]
[Alias("UseAll")]
[switch]$USE_ALL,
[Parameter(Mandatory = $false)]
[Alias("IncludePrograms")]
[switch]$INCLUDE_PROGRAMS,
[Parameter(Mandatory = $false)]
[Alias("NoBuild")]
[switch]$NO_BUILD,
[Parameter(Mandatory = $false)]
[Alias("NoArchive")]
[switch]$NO_ARCHIVE
)
# Set the current directory as a variable
$BUILD_FOLDER = $PSScriptRoot
# Set the current commit hash
$COMMIT = git log --pretty=format:"%H" -1
# Create the build matrix arrays
$UI_FRAMEWORKS = @('net6.0-windows', 'net8.0-windows')
$UI_RUNTIMES = @('win-x64')
$CHECK_FRAMEWORKS = @('net6.0', 'net8.0')
$CHECK_RUNTIMES = @('win-x64', 'linux-x64', 'osx-x64')
# Use expanded lists, if requested
if ($USE_ALL.IsPresent)
{
$UI_FRAMEWORKS = @('net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0-windows', 'net6.0-windows', 'net7.0-windows', 'net8.0-windows')
$UI_RUNTIMES = @('win-x86', 'win-x64')
$CHECK_FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
$CHECK_RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
}
# Create the filter arrays
$SINGLE_FILE_CAPABLE = @('net5.0', 'net5.0-windows', 'net6.0', 'net6.0-windows', 'net7.0', 'net7.0-windows', 'net8.0', 'net8.0-windows')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0')
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64')
# Only build if requested
if (!$NO_BUILD.IsPresent)
{
# Restore Nuget packages for all builds
Write-Host "Restoring Nuget packages"
dotnet restore
# Build UI
foreach ($FRAMEWORK in $UI_FRAMEWORKS)
{
foreach ($RUNTIME in $UI_RUNTIMES)
{
# Only .NET 5 and above can publish to a single file
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
{
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
}
else
{
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
dotnet publish MPF\MPF.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
}
}
}
# Build Check
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS)
{
foreach ($RUNTIME in $CHECK_RUNTIMES)
{
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
continue
}
# Only .NET 5 and above can publish to a single file
if ($SINGLE_FILE_CAPABLE -contains $FRAMEWORK)
{
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false
}
else
{
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Debug --self-contained true --version-suffix $COMMIT
dotnet publish MPF.Check\MPF.Check.csproj -f $FRAMEWORK -r $RUNTIME -c Release --self-contained true --version-suffix $COMMIT -p:DebugType=None -p:DebugSymbols=false
}
}
}
}
# Only create archives if requested
if (!$NO_ARCHIVE.IsPresent)
{
# Create UI archives
foreach ($FRAMEWORK in $UI_FRAMEWORKS)
{
foreach ($RUNTIME in $UI_RUNTIMES)
{
Set-Location -Path $BUILD_FOLDER\MPF\bin\Debug\$FRAMEWORK\$RUNTIME\publish\
if ($INCLUDE_PROGRAMS.IsPresent)
{
7z a -tzip $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
else
{
7z a -tzip -x!Programs\* $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_debug.zip *
}
Set-Location -Path $BUILD_FOLDER\MPF\bin\Release\$FRAMEWORK\$RUNTIME\publish\
if ($INCLUDE_PROGRAMS.IsPresent)
{
7z a -tzip $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_release.zip *
}
else
{
7z a -tzip -x!Programs\* $BUILD_FOLDER\MPF_${FRAMEWORK}_${RUNTIME}_release.zip *
}
}
}
# Create Check archives
foreach ($FRAMEWORK in $CHECK_FRAMEWORKS)
{
foreach ($RUNTIME in $CHECK_RUNTIMES)
{
# If we have an invalid combination of framework and runtime
if ($VALID_CROSS_PLATFORM_FRAMEWORKS -notcontains $FRAMEWORK -and $VALID_CROSS_PLATFORM_RUNTIMES -contains $RUNTIME)
{
continue
}
Set-Location -Path $BUILD_FOLDER\MPF.Check\bin\Debug\$FRAMEWORK\$RUNTIME\publish\
7z a -tzip $BUILD_FOLDER\MPF.Check_${FRAMEWORK}_${RUNTIME}_debug.zip *
Set-Location -Path $BUILD_FOLDER\MPF.Check\bin\Release\$FRAMEWORK\${RUNTIME}\publish\
7z a -tzip $BUILD_FOLDER\MPF.Check_${FRAMEWORK}_${RUNTIME}_release.zip *
}
}
# Reset the directory
Set-Location -Path $PSScriptRoot
}