2019-09-19 11:56:43 +10:00
using Microsoft.AppCenter.Analytics ;
using Microsoft.Toolkit.Uwp.Helpers ;
using MVVM ;
2020-08-06 06:48:31 +10:00
using SixLabors.ImageSharp.Formats.Png ;
using SixLabors.ImageSharp.PixelFormats ;
2020-01-03 09:44:49 +11:00
using SixLabors.ImageSharp.Processing ;
using SixLabors.ImageSharp.Processing.Processors.Transforms ;
2019-09-19 11:56:43 +10:00
using System ;
using System.Collections.Generic ;
2020-01-03 09:44:49 +11:00
using System.Collections.ObjectModel ;
2019-09-19 11:56:43 +10:00
using System.IO ;
using System.Threading.Tasks ;
using Windows.Storage ;
2019-09-20 22:06:46 +10:00
using Windows.Storage.FileProperties ;
2019-09-19 14:24:58 +10:00
using Windows.Storage.Pickers ;
2020-01-26 15:21:06 +11:00
using Windows.UI ;
2020-03-02 10:16:03 +11:00
using Windows.UI.Xaml ;
2019-09-19 14:24:58 +10:00
using Windows.UI.Xaml.Media ;
using Windows.UI.Xaml.Media.Imaging ;
2019-09-19 11:56:43 +10:00
namespace UWP_Visual_Asset_Generator.ViewModels
{
public class MainViewModel : ValleyBaseViewModel
{
private SettingsViewModel _settings ;
2021-05-12 19:39:16 -04:00
2019-09-19 11:56:43 +10:00
private bool _showFeedbackControl = false ;
private bool _showGettingStartedControl = false ;
2019-09-19 12:34:02 +10:00
private bool _showEditCurrentImage = false ;
2019-09-20 05:53:25 +10:00
private bool _previewWithAccentColour = false ;
2020-01-26 15:21:06 +11:00
private bool _showBackgroundColorSelector = false ;
2020-02-28 06:06:13 +11:00
private bool _useTransparentBackground = true ;
2021-05-12 19:39:16 -04:00
private bool _isFirstRun = SystemInformation . Instance . IsFirstRun ;
2020-01-26 21:54:48 +11:00
private Color _backgroundColour = Color . FromArgb ( 0 , 0 , 0 , 0 ) ;
public const string mruOutputFolderMetadata = "OutputFolder" ;
2019-09-19 11:56:43 +10:00
2019-09-19 14:24:58 +10:00
private StorageFile _originalLogoFile ;
private ImageSource _originalLogoImageSource ;
2019-09-19 20:14:34 +10:00
private StorageFolder _outputFolder ;
2019-09-20 22:06:46 +10:00
public WriteableBitmap originalWriteableBitmap ;
2019-09-19 14:24:58 +10:00
2019-09-19 21:38:07 +10:00
private AssetTypeListViewModel _assetTypes ;
2019-09-19 11:56:43 +10:00
private const string WinStoreProductID = "9MZ6QRQTDKF2" ;
2020-01-03 09:44:49 +11:00
private ObservableCollection < KeyValuePair < string , IResampler > > _resamplers = new ObservableCollection < KeyValuePair < string , IResampler > > ( )
2021-05-12 19:39:16 -04:00
{
2020-08-06 06:48:31 +10:00
new KeyValuePair < string , IResampler > ( "Average" , KnownResamplers . Box ) ,
new KeyValuePair < string , IResampler > ( "Bicubic" , KnownResamplers . Bicubic ) ,
new KeyValuePair < string , IResampler > ( "Nearest Neighbour" , KnownResamplers . NearestNeighbor ) ,
new KeyValuePair < string , IResampler > ( "Box" , KnownResamplers . Box ) ,
new KeyValuePair < string , IResampler > ( "CatmullRom" , KnownResamplers . CatmullRom ) ,
new KeyValuePair < string , IResampler > ( "Hermite" , KnownResamplers . Hermite ) ,
new KeyValuePair < string , IResampler > ( "Lanczos2" , KnownResamplers . Lanczos2 ) ,
new KeyValuePair < string , IResampler > ( "Lanczos3" , KnownResamplers . Lanczos3 ) ,
new KeyValuePair < string , IResampler > ( "Lanczos5" , KnownResamplers . Lanczos5 ) ,
new KeyValuePair < string , IResampler > ( "Lanczos8" , KnownResamplers . Lanczos8 ) ,
new KeyValuePair < string , IResampler > ( "MitchellNetravali" , KnownResamplers . MitchellNetravali ) ,
new KeyValuePair < string , IResampler > ( "Robidoux" , KnownResamplers . Robidoux ) ,
new KeyValuePair < string , IResampler > ( "RobidouxSharp" , KnownResamplers . RobidouxSharp ) ,
new KeyValuePair < string , IResampler > ( "Spline" , KnownResamplers . Spline ) ,
new KeyValuePair < string , IResampler > ( "Triangle" , KnownResamplers . Triangle ) ,
new KeyValuePair < string , IResampler > ( "Welch" , KnownResamplers . Welch )
2020-01-03 09:44:49 +11:00
} ;
private KeyValuePair < string , IResampler > _selectedResampler ;
2020-08-06 06:48:31 +10:00
private ObservableCollection < KeyValuePair < string , PixelColorBlendingMode > > _blendingModes = new ObservableCollection < KeyValuePair < string , PixelColorBlendingMode > > ( )
2021-05-12 19:39:16 -04:00
{
2020-08-06 06:48:31 +10:00
new KeyValuePair < string , PixelColorBlendingMode > ( "Add" , PixelColorBlendingMode . Add ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Darken" , PixelColorBlendingMode . Darken ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "HardLight" , PixelColorBlendingMode . HardLight ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Lighten" , PixelColorBlendingMode . Lighten ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Multiply" , PixelColorBlendingMode . Multiply ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Normal" , PixelColorBlendingMode . Normal ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Overlay" , PixelColorBlendingMode . Overlay ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Screen" , PixelColorBlendingMode . Screen ) ,
new KeyValuePair < string , PixelColorBlendingMode > ( "Subtract" , PixelColorBlendingMode . Subtract )
} ;
private KeyValuePair < string , PixelColorBlendingMode > _selectedBlendingMode ;
private ObservableCollection < KeyValuePair < string , PixelAlphaCompositionMode > > _alphaModes = new ObservableCollection < KeyValuePair < string , PixelAlphaCompositionMode > > ( )
2021-05-12 19:39:16 -04:00
{
2020-08-06 06:48:31 +10:00
new KeyValuePair < string , PixelAlphaCompositionMode > ( "The Logo where they don't overlap otherwise dest in overlapping parts." , PixelAlphaCompositionMode . DestAtop ) ,
new KeyValuePair < string , PixelAlphaCompositionMode > ( "The Background over the Logo." , PixelAlphaCompositionMode . DestOver ) ,
new KeyValuePair < string , PixelAlphaCompositionMode > ( "Returns the Logo colors." , PixelAlphaCompositionMode . Src ) ,
new KeyValuePair < string , PixelAlphaCompositionMode > ( "The Background where the Background and Logo overlap." , PixelAlphaCompositionMode . SrcOut ) ,
new KeyValuePair < string , PixelAlphaCompositionMode > ( "Returns the Background over the Logo." , PixelAlphaCompositionMode . SrcOver ) ,
new KeyValuePair < string , PixelAlphaCompositionMode > ( "Clear where they overlap." , PixelAlphaCompositionMode . Xor )
} ;
private KeyValuePair < string , PixelAlphaCompositionMode > _selectedAlphaMode ;
private ObservableCollection < KeyValuePair < string , PngCompressionLevel > > _pngCompressionOptions = new ObservableCollection < KeyValuePair < string , PngCompressionLevel > > ( )
2021-05-12 19:39:16 -04:00
{
2020-08-06 06:48:31 +10:00
new KeyValuePair < string , PngCompressionLevel > ( "Fastest (level 1)" , PngCompressionLevel . BestSpeed ) ,
new KeyValuePair < string , PngCompressionLevel > ( "Best (level 9)" , PngCompressionLevel . BestCompression ) ,
new KeyValuePair < string , PngCompressionLevel > ( "Default (Level 6)" , PngCompressionLevel . DefaultCompression ) ,
new KeyValuePair < string , PngCompressionLevel > ( "No Compression (level 0)" , PngCompressionLevel . NoCompression )
} ;
private KeyValuePair < string , PngCompressionLevel > _selectedPNGCompression ;
2019-09-19 11:56:43 +10:00
public MainViewModel ( )
{
LogFirstUseMetrics ( ) ;
2020-01-03 09:44:49 +11:00
_selectedResampler = _resamplers [ 1 ] ;
2020-08-06 06:48:31 +10:00
_selectedBlendingMode = _blendingModes [ 5 ] ;
_selectedAlphaMode = _alphaModes [ 3 ] ;
_selectedPNGCompression = _pngCompressionOptions [ 2 ] ;
2019-11-20 06:11:57 +11:00
2020-01-03 09:44:49 +11:00
SetupOutputFolder ( ) ;
}
private async Task SetupOutputFolder ( )
{
2020-01-26 21:54:48 +11:00
IStorageItem item = null ;
var mru = Windows . Storage . AccessCache . StorageApplicationPermissions . MostRecentlyUsedList ;
foreach ( Windows . Storage . AccessCache . AccessListEntry entry in mru . Entries )
{
if ( entry . Metadata . Equals ( mruOutputFolderMetadata ) )
{
var mruToken = entry . Token ;
item = await mru . GetItemAsync ( mruToken ) ;
break ;
}
}
if ( item = = null )
{
OutputFolder = await KnownFolders . PicturesLibrary . CreateFolderAsync ( "Asset Generator" , CreationCollisionOption . OpenIfExists ) ;
}
else
{
try
{
OutputFolder = item as StorageFolder ;
}
catch ( Exception ex )
{
OutputFolder = await KnownFolders . PicturesLibrary . CreateFolderAsync ( "Asset Generator" , CreationCollisionOption . OpenIfExists ) ;
}
}
2019-09-19 11:56:43 +10:00
}
2019-09-19 14:24:58 +10:00
#region public properties
2020-01-03 09:44:49 +11:00
2020-08-06 06:48:31 +10:00
public ObservableCollection < KeyValuePair < string , PngCompressionLevel > > PNGCompressionOptions
{
get
{
return _pngCompressionOptions ;
}
}
public KeyValuePair < string , PngCompressionLevel > SelectedPNGCompression
{
get
{
return _selectedPNGCompression ;
}
set
{
if ( _selectedPNGCompression . Key ! = value . Key )
{
_selectedPNGCompression = value ;
NotifyPropertyChanged ( "SelectedPNGCompression" ) ;
}
}
}
2020-01-03 09:44:49 +11:00
public ObservableCollection < KeyValuePair < string , IResampler > > Resamplers
{
get
{
return _resamplers ;
}
}
public KeyValuePair < string , IResampler > SelectedResampler
{
get
{
return _selectedResampler ;
}
set
{
if ( _selectedResampler . Key ! = value . Key )
{
_selectedResampler = value ;
NotifyPropertyChanged ( "SelectedResampler" ) ;
AssetTypes . ApplyLogo ( ) ;
}
}
}
2020-08-06 06:48:31 +10:00
public ObservableCollection < KeyValuePair < string , PixelColorBlendingMode > > BlendingModes
{
get
{
return _blendingModes ;
}
}
public KeyValuePair < string , PixelColorBlendingMode > SelectedBlendingMode
{
get
{
return _selectedBlendingMode ;
}
set
{
if ( _selectedBlendingMode . Key ! = value . Key )
{
_selectedBlendingMode = value ;
NotifyPropertyChanged ( "SelectedBlendingMode" ) ;
AssetTypes . ApplyLogo ( ) ;
}
}
}
public ObservableCollection < KeyValuePair < string , PixelAlphaCompositionMode > > AlphaModes
{
get
{
return _alphaModes ;
}
}
public KeyValuePair < string , PixelAlphaCompositionMode > SelectedAlphaMode
{
get
{
return _selectedAlphaMode ;
}
set
{
if ( _selectedAlphaMode . Key ! = value . Key )
{
_selectedAlphaMode = value ;
NotifyPropertyChanged ( "SelectedAlphaMode" ) ;
AssetTypes . ApplyLogo ( ) ;
}
}
}
2019-09-20 05:53:25 +10:00
public bool SaveEnabled
{
get
{
2020-01-26 21:54:48 +11:00
return ( OutputFolder ! = null & & OriginalLogoFile ! = null ) ;
2019-09-20 05:53:25 +10:00
}
}
2020-04-24 12:46:15 -04:00
public bool IsFirstRun
{
get
{
return _isFirstRun ;
}
set
{
if ( _isFirstRun ! = value )
{
_isFirstRun = value ;
NotifyPropertyChanged ( "IsFirstRun" ) ;
}
}
}
2020-01-26 15:21:06 +11:00
public bool ShowBackgroundColorSelector
{
get
{
return _showBackgroundColorSelector ;
}
set
{
2020-02-28 06:06:13 +11:00
if ( _showBackgroundColorSelector ! = value )
{
_showBackgroundColorSelector = value ;
NotifyPropertyChanged ( "ShowBackgroundColorSelector" ) ;
}
}
}
public bool UseTransparentBackground
{
get
{
return _useTransparentBackground ;
}
set
{
if ( _useTransparentBackground ! = value )
{
_useTransparentBackground = value ;
NotifyPropertyChanged ( "UseTransparentBackground" ) ;
NotifyPropertyChanged ( "UseColouredBackground" ) ;
}
}
}
public bool UseColouredBackground
{
get
{
return ! _useTransparentBackground ;
2020-01-26 15:21:06 +11:00
}
}
public Color BackgroundColour
{
get
{
return _backgroundColour ;
}
set
{
if ( _backgroundColour ! = value )
{
_backgroundColour = value ;
if ( _backgroundColour . A = = 0 )
{
_backgroundColour . A = 255 ;
}
NotifyPropertyChanged ( "BackgroundColour" ) ;
NotifyPropertyChanged ( "BackgroundColourBrush" ) ;
}
}
}
public Brush BackgroundColourBrush
{
get
{
return new SolidColorBrush ( _backgroundColour ) ;
}
}
2019-09-20 05:53:25 +10:00
public bool PreviewWithAccentColour
{
get
{
return _previewWithAccentColour ;
}
set
{
2020-02-28 06:06:13 +11:00
if ( _previewWithAccentColour ! = value )
{
_previewWithAccentColour = value ;
NotifyPropertyChanged ( "PreviewWithAccentColour" ) ;
2020-03-02 10:16:03 +11:00
NotifyPropertyChanged ( "PreviewWithAccentColourBrush" ) ;
2020-02-28 06:06:13 +11:00
}
2019-09-20 05:53:25 +10:00
}
2021-05-12 19:39:16 -04:00
}
2020-03-02 10:16:03 +11:00
public Color PreviewWithAccentColourBrush
{
get
{
if ( PreviewWithAccentColour )
{
try
{
var color = ( Color ) Application . Current . Resources [ "SystemAccentColor" ] ;
return color ;
}
catch ( Exception ex )
{
return Colors . RoyalBlue ;
}
}
else
{
return Colors . Transparent ;
}
}
}
2019-09-20 05:53:25 +10:00
2019-09-19 11:56:43 +10:00
public bool ShowFeedbackControl
{
get
{
return _showFeedbackControl ;
}
set
{
2020-02-28 06:06:13 +11:00
if ( _showFeedbackControl ! = value )
{
_showFeedbackControl = value ;
NotifyPropertyChanged ( "ShowFeedbackControl" ) ;
}
2019-09-19 11:56:43 +10:00
}
}
2019-09-19 20:14:34 +10:00
public StorageFolder OutputFolder
{
get
{
2021-05-12 19:39:16 -04:00
return _outputFolder ;
2019-09-19 20:14:34 +10:00
}
set
{
2020-02-28 06:06:13 +11:00
if ( _outputFolder ! = value )
{
_outputFolder = value ;
NotifyPropertyChanged ( "OutputFolder" ) ;
NotifyPropertyChanged ( "SaveEnabled" ) ;
}
2019-09-19 20:14:34 +10:00
}
}
2019-09-19 14:24:58 +10:00
public StorageFile OriginalLogoFile
{
get
{
return _originalLogoFile ;
}
}
2021-05-12 19:39:16 -04:00
2019-09-19 14:24:58 +10:00
public ImageSource OriginalLogoImageSource
{
get
{
return _originalLogoImageSource ;
}
set
{
_originalLogoImageSource = value ;
NotifyPropertyChanged ( "OriginalLogoImageSource" ) ;
}
}
2019-09-19 11:56:43 +10:00
public bool ShowGettingStartedControl
{
get
{
return _showGettingStartedControl ;
}
set
{
2020-02-28 06:06:13 +11:00
if ( _showGettingStartedControl ! = value )
{
_showGettingStartedControl = value ;
NotifyPropertyChanged ( "ShowGettingStartedControl" ) ;
}
2019-09-19 11:56:43 +10:00
}
}
2019-09-19 12:34:02 +10:00
public bool ShowEditCurrentImage
{
get
{
return _showEditCurrentImage ;
}
set
{
2020-02-28 06:06:13 +11:00
if ( _showEditCurrentImage ! = value )
{
_showEditCurrentImage = value ;
NotifyPropertyChanged ( "ShowEditCurrentImage" ) ;
}
2019-09-19 12:34:02 +10:00
}
}
2019-09-19 11:56:43 +10:00
public SettingsViewModel Settings
{
get
{
if ( _settings = = null )
{
_settings = new SettingsViewModel ( ) ;
}
return _settings ;
}
set
{
_settings = value ;
NotifyPropertyChanged ( "Settings" ) ;
}
}
2019-09-19 21:38:07 +10:00
public AssetTypeListViewModel AssetTypes
{
get
{
if ( _assetTypes = = null )
{
_assetTypes = new AssetTypeListViewModel ( ) ;
_assetTypes . Load ( ) ;
}
return _assetTypes ;
}
set
{
_assetTypes = value ;
NotifyPropertyChanged ( "AssetTypes" ) ;
}
}
2019-09-19 14:24:58 +10:00
#endregion public properties
#region functions
/// <summary>
/// Sets the original image to create assets from.
/// </summary>
/// <returns>
/// Returns a bool if successful
/// </returns>
/// <param name="fileToLoad"> a nullable param, if you have a StorageFile pass it here and it will load. Otherwise it will execute a FilePicker.</param>
public async Task < bool > LoadOriginalImageFromFileAsync ( StorageFile fileToLoad = null )
{
var result = false ;
if ( fileToLoad = = null )
{
var picker = new FileOpenPicker ( ) ;
picker . FileTypeFilter . Add ( ".png" ) ;
picker . SuggestedStartLocation = PickerLocationId . PicturesLibrary ;
_originalLogoFile = await picker . PickSingleFileAsync ( ) ;
}
else
{
_originalLogoFile = fileToLoad ;
}
if ( _originalLogoFile ! = null )
{
NotifyPropertyChanged ( "OriginalLogoFile" ) ;
using ( var randomAccessStream = await _originalLogoFile . OpenAsync ( FileAccessMode . Read ) )
{
var b = new BitmapImage ( ) ;
await b . SetSourceAsync ( randomAccessStream ) ;
OriginalLogoImageSource = b ;
}
2019-10-01 13:25:38 +10:00
await LogoAsWriteableBitmap ( ) ;
2019-09-20 22:06:46 +10:00
AssetTypes . ApplyLogo ( ) ;
2019-09-19 14:24:58 +10:00
result = true ;
}
2020-01-26 21:54:48 +11:00
NotifyPropertyChanged ( "SaveEnabled" ) ;
2019-09-19 14:24:58 +10:00
return result ;
}
2019-09-19 20:14:34 +10:00
/// <summary>
/// Sets the output folder to save generated files to.
/// </summary>
/// <returns>
/// Returns a bool if successful
/// </returns>
public async Task < bool > SetOutputFolderAsync ( )
{
var result = false ;
var picker = new FolderPicker ( ) ;
picker . SuggestedStartLocation = PickerLocationId . PicturesLibrary ;
picker . FileTypeFilter . Add ( "*" ) ;
var folder = await picker . PickSingleFolderAsync ( ) ;
if ( folder ! = null )
{
OutputFolder = folder ;
2020-01-26 21:54:48 +11:00
var mru = Windows . Storage . AccessCache . StorageApplicationPermissions . MostRecentlyUsedList ;
mru . Clear ( ) ;
string mruToken = mru . Add ( OutputFolder , mruOutputFolderMetadata ) ;
Settings . LastOutputDirectoryToken = mruToken ;
2019-09-19 20:14:34 +10:00
result = true ;
}
return result ;
}
2019-09-20 22:06:46 +10:00
public async Task LogoAsWriteableBitmap ( )
{
ImageProperties properties = await OriginalLogoFile . Properties . GetImagePropertiesAsync ( ) ;
originalWriteableBitmap = new WriteableBitmap ( ( int ) properties . Width , ( int ) properties . Height ) ;
originalWriteableBitmap . SetSource ( ( await OriginalLogoFile . OpenReadAsync ( ) ) . AsStream ( ) . AsRandomAccessStream ( ) ) ;
}
2019-09-19 20:14:34 +10:00
2019-09-19 11:56:43 +10:00
async public void ReviewThisApp ( )
{
await Windows . System . Launcher . LaunchUriAsync ( new Uri ( "ms-windows-store://review/?ProductID=" + WinStoreProductID ) ) ;
}
private async Task LogFirstUseMetrics ( )
{
2021-05-12 19:39:16 -04:00
if ( SystemInformation . Instance . IsFirstRun )
2019-09-19 11:56:43 +10:00
{
var t = App . Current . RequestedTheme . ToString ( ) ;
Analytics . TrackEvent ( "OS Theme On First Run is: " + t ) ;
}
}
2019-09-19 14:24:58 +10:00
#endregion functions
2019-09-19 11:56:43 +10:00
}
}