Skip to content

Commit

Permalink
Merge pull request #12 from tekgator/dev
Browse files Browse the repository at this point in the history
Add Icons to Launcher and Game interface / Add WPF sample application
  • Loading branch information
tekgator authored Sep 1, 2022
2 parents 8dcca34 + ca18a67 commit 18761d5
Show file tree
Hide file tree
Showing 73 changed files with 2,249 additions and 20 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased]


## [1.1.2] - 2022-01-09
### Added
- Add ExecutableIcon property on IGame interface / implementations
- Add ExecutableIcon property on ILauncher interface / implementations
- Add WPF GUI demo application


## [1.1.1] - 2022-27-08
### Fixed
- Refresh caused an dead lock in UI applications due to incorrect async call
- Refresh on LauncherManager also returns the Launchers collection so no extra GetLaunchers call need to be made


## [1.1.0] - 2022-27-08
### Fixed
- disable 0649 to avoid compiler warning for MEF variables
Expand Down
9 changes: 8 additions & 1 deletion GameLib.Core/IGame.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace GameLib.Core;
using System.Drawing;

namespace GameLib.Core;

public interface IGame
{
Expand Down Expand Up @@ -32,6 +34,11 @@ public interface IGame
/// </summary>
public string Executable { get; }

/// <summary>
/// The extracted icon of the game executable
/// </summary>
public Icon? ExecutableIcon { get; }

/// <summary>
/// Working directory of the game
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions GameLib.Core/ILauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public interface ILauncher
/// </summary>
public string Executable { get; }

/// <summary>
/// The extracted icon of the launcher executable
/// </summary>
public Icon? ExecutableIcon { get; }

/// <summary>
/// The installed games of the Launcher
/// NOTE: if no cache is available list will be empty, Refresh must be called first
Expand Down
22 changes: 21 additions & 1 deletion GameLib.Core/Util/PathUtil.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using System.Drawing;
using System.Text.RegularExpressions;

namespace Gamelib.Core.Util;

Expand Down Expand Up @@ -89,4 +90,23 @@ public static bool IsExecutable(string? path) =>

return creationDateTime;
}

/// <summary>
/// Returns the extracted default icon of the file
/// </summary>
/// <param name="path"></param>
/// <returns>The extracted icon of the file; otherwise <see langword="null"/></returns>
public static Icon? GetFileIcon(string? path)
{
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
try
{
return Icon.ExtractAssociatedIcon(path);
}
catch { /* ignore */ }
}

return null;
}
}
21 changes: 21 additions & 0 deletions GameLib.Demo/GameLib.Demo.Wpf/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Application
x:Class="GameLib.Demo.Wpf.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GameLib.Demo.Wpf"
xmlns:system="http://schemas.microsoft.com/winfx/2009/xaml">
<Application.Resources>
<SolidColorBrush x:Key="NavigationBarBackgroundColor" Color="#0D47A1" />
<SolidColorBrush x:Key="NavigationBarSelectedItemBackgroundColor" Color="#3162AF" />
<SolidColorBrush x:Key="NavigationBarForegroundColor" Color="#FFFFFF" />

<SolidColorBrush x:Key="PrimaryBackgroundColor" Color="#303030" />
<SolidColorBrush x:Key="PrimaryForegroundColor" Color="#FFFFFF" />

<SolidColorBrush x:Key="SecondaryBackgroundColor" Color="#333333" />
<SolidColorBrush x:Key="SecondaryForegroundColor" Color="#7fc9ff" />

<SolidColorBrush x:Key="ThirdBackgroundColor" Color="#444444" />
<SolidColorBrush x:Key="ThirdForegroundColor" Color="#bae0ff" />
</Application.Resources>
</Application>
85 changes: 85 additions & 0 deletions GameLib.Demo/GameLib.Demo.Wpf/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using GameLib.Demo.Wpf.Services;
using GameLib.Demo.Wpf.Store;
using GameLib.Demo.Wpf.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Markup;

namespace GameLib.Demo.Wpf;

public partial class App : Application
{
private readonly IServiceProvider _serviceProvider;

public App()
{
// apply user culture to application
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

IServiceCollection services = new ServiceCollection();

services.AddSingleton<NavigationStore>();

services.AddSingleton<INavigationService<HomeViewModel>>(s => CreateHomeNavigationService(s));
services.AddTransient<HomeViewModel>();

services.AddSingleton<INavigationService<LauncherViewModel>>(s => CreateLauncherNavigationService(s));
services.AddTransient<LauncherViewModel>();

services.AddSingleton<INavigationService<GameViewModel>>(s => CreateGameNavigationService(s));
services.AddTransient<GameViewModel>();

services.AddSingleton<NavigationBarViewModel>(CreateNavigationBarViewModel);

services.AddSingleton<MainViewModel>();
services.AddSingleton<MainWindow>(s => new MainWindow()
{
DataContext = s.GetRequiredService<MainViewModel>()
});

services.AddSingleton<LauncherManager>();

_serviceProvider = services.BuildServiceProvider();
}

protected override void OnStartup(StartupEventArgs e)
{
MainWindow = _serviceProvider.GetRequiredService<MainWindow>();
MainWindow.Show();

base.OnStartup(e);
}

private static INavigationService<HomeViewModel> CreateHomeNavigationService(IServiceProvider serviceProvider)
{
return new NavigationService<HomeViewModel>(
serviceProvider.GetRequiredService<NavigationStore>(),
() => serviceProvider.GetRequiredService<HomeViewModel>());
}

private static INavigationService<LauncherViewModel> CreateLauncherNavigationService(IServiceProvider serviceProvider)
{
return new NavigationService<LauncherViewModel>(
serviceProvider.GetRequiredService<NavigationStore>(),
() => serviceProvider.GetRequiredService<LauncherViewModel>());
}

private static INavigationService<GameViewModel> CreateGameNavigationService(IServiceProvider serviceProvider)
{
return new NavigationService<GameViewModel>(
serviceProvider.GetRequiredService<NavigationStore>(),
() => serviceProvider.GetRequiredService<GameViewModel>());
}

private static NavigationBarViewModel CreateNavigationBarViewModel(IServiceProvider serviceProvider)
{
return new NavigationBarViewModel(
CreateHomeNavigationService(serviceProvider),
CreateLauncherNavigationService(serviceProvider),
CreateGameNavigationService(serviceProvider));
}
}
10 changes: 10 additions & 0 deletions GameLib.Demo/GameLib.Demo.Wpf/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Drawing;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

namespace GameLib.Demo.Wpf.Converters;

public class IconToImageSourceConverter : IValueConverter
{
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Icon icon)
{
try
{
if (icon is not null)
{
return Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
}
catch { /* ignore */ }
}

return null;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace GameLib.Demo.Wpf.Converters;

public class ImageToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Image image)
{
using var ms = new MemoryStream();

image.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);

var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = ms;
bitmapImage.EndInit();
bitmapImage.Freeze();

return bitmapImage;
}

throw new NotImplementedException();
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is BitmapImage bitmapImage)
{
using var ms = new MemoryStream();

BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(ms);
Bitmap bitmap = new(ms);

return new Bitmap(bitmap);
}

throw new NotImplementedException();
}
}
102 changes: 102 additions & 0 deletions GameLib.Demo/GameLib.Demo.Wpf/GameLib.Demo.Wpf.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1293.44" />
<PackageReference Include="WpfAnimatedGif" Version="2.0.2" />
</ItemGroup>

<!--
// Temporary bug fix for duplicating code from source code generators in .NET 6.0 (MVVM Toolkit)
// (https://github.com/dotnet/core/blob/main/release-notes/6.0/known-issues.md#issues-building-wpf-application-with-windows-desktop-607-and-608)
-->
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
<ItemGroup>
<FilteredAnalyzer Include="@(Analyzer-&gt;Distinct())" />
<Analyzer Remove="@(Analyzer)" />
<Analyzer Include="@(FilteredAnalyzer)" />
</ItemGroup>
</Target>

<ItemGroup>
<None Remove="Resources\about-black.png" />
<None Remove="Resources\about-white.png" />
<None Remove="Resources\check-color.png" />
<None Remove="Resources\contribute-black.png" />
<None Remove="Resources\contribute-white.png" />
<None Remove="Resources\copy-black.png" />
<None Remove="Resources\copy-white.png" />
<None Remove="Resources\cross-color.png" />
<None Remove="Resources\game-black.png" />
<None Remove="Resources\game-white.png" />
<None Remove="Resources\GameLibNET-Logo-64px.png" />
<None Remove="Resources\github-black.png" />
<None Remove="Resources\github-white.png" />
<None Remove="Resources\home-black.png" />
<None Remove="Resources\home-white.png" />
<None Remove="Resources\icon.ico" />
<None Remove="Resources\launcher-black.png" />
<None Remove="Resources\launcher-white.png" />
<None Remove="Resources\navigation-drawer-black.png" />
<None Remove="Resources\navigation-drawer-white.png" />
<None Remove="Resources\open-black.png" />
<None Remove="Resources\open-white.png" />
<None Remove="Resources\play-black.png" />
<None Remove="Resources\play-white.png" />
<None Remove="Resources\refresh-black.png" />
<None Remove="Resources\refresh-white.png" />
<None Remove="Resources\spinner-white.gif" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\GameLib.Plugin\GameLib.Plugin.Epic\GameLib.Plugin.Epic.csproj" />
<ProjectReference Include="..\..\GameLib.Plugin\GameLib.Plugin.Gog\GameLib.Plugin.Gog.csproj" />
<ProjectReference Include="..\..\GameLib.Plugin\GameLib.Plugin.Origin\GameLib.Plugin.Origin.csproj" />
<ProjectReference Include="..\..\GameLib.Plugin\GameLib.Plugin.Steam\GameLib.Plugin.Steam.csproj" />
<ProjectReference Include="..\..\GameLib.Plugin\GameLib.Plugin.Ubisoft\GameLib.Plugin.Ubisoft.csproj" />
<ProjectReference Include="..\..\GameLib\GameLib.csproj" />
</ItemGroup>

<ItemGroup>
<Resource Include="Resources\about-black.png" />
<Resource Include="Resources\about-white.png" />
<Resource Include="Resources\check-color.png" />
<Resource Include="Resources\contribute-black.png" />
<Resource Include="Resources\contribute-white.png" />
<Resource Include="Resources\copy-black.png" />
<Resource Include="Resources\copy-white.png" />
<Resource Include="Resources\cross-color.png" />
<Resource Include="Resources\game-black.png" />
<Resource Include="Resources\game-white.png" />
<Resource Include="Resources\GameLibNET-Logo-64px.png" />
<Resource Include="Resources\github-black.png" />
<Resource Include="Resources\github-white.png" />
<Resource Include="Resources\home-black.png" />
<Resource Include="Resources\home-white.png" />
<Resource Include="Resources\icon.ico" />
<Resource Include="Resources\launcher-black.png" />
<Resource Include="Resources\launcher-white.png" />
<Resource Include="Resources\navigation-drawer-black.png" />
<Resource Include="Resources\navigation-drawer-white.png" />
<Resource Include="Resources\open-black.png" />
<Resource Include="Resources\open-white.png" />
<Resource Include="Resources\play-black.png" />
<Resource Include="Resources\play-white.png" />
<Resource Include="Resources\refresh-black.png" />
<Resource Include="Resources\refresh-white.png" />
<Resource Include="Resources\spinner-white.gif" />
</ItemGroup>



</Project>
Loading

0 comments on commit 18761d5

Please sign in to comment.