mirror of
https://github.com/chibicitiberiu/drumkit.git
synced 2024-02-24 10:53:32 +00:00
Latest build (version 2.2)
This commit is contained in:
@ -13,6 +13,7 @@
|
||||
Required by Visual Studio project and item templates
|
||||
-->
|
||||
<ResourceDictionary Source="Common/StandardStyles.xaml"/>
|
||||
<ResourceDictionary Source="Common/TextButtonStyles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
@ -80,22 +80,10 @@ namespace DrumKit
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private async void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
try {
|
||||
await DataManager.Close();
|
||||
}
|
||||
|
||||
catch (Exception ex) {
|
||||
Log.Error("Exception in OnSuspending method!");
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
Log.Write("Application suspended.");
|
||||
|
||||
//TODO:::...
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
|
BIN
DrumKit/AppPackages/DrumKit_2.1.0.26_AnyCPU.appxupload
Normal file
BIN
DrumKit/AppPackages/DrumKit_2.1.0.26_AnyCPU.appxupload
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
DrumKit/AppPackages/DrumKit_2.2.0.27_AnyCPU.appxupload
Normal file
BIN
DrumKit/AppPackages/DrumKit_2.2.0.27_AnyCPU.appxupload
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,328 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit.Archiving
|
||||
{
|
||||
public class TarballReader
|
||||
{
|
||||
#region Data types etc
|
||||
/// <summary>
|
||||
/// Tarball header structure
|
||||
/// </summary>
|
||||
private struct TarballHeader
|
||||
{
|
||||
public string FileName;
|
||||
public uint FileMode;
|
||||
public uint OwnerId, GroupId;
|
||||
public int Size;
|
||||
public DateTime LastModified;
|
||||
public uint Checksum;
|
||||
public byte LinkIndicator;
|
||||
public string LinkedFile;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private attributes
|
||||
private Stream stream;
|
||||
private TarballHeader header;
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Creates a new instance of a tarball archive reader.
|
||||
/// </summary>
|
||||
public TarballReader()
|
||||
{
|
||||
stream = null;
|
||||
header = new TarballHeader();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public functions (unpack)
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a temporary folder.
|
||||
/// </summary>
|
||||
/// <param name="file">An URI to the tarball file.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack (Uri file)
|
||||
{
|
||||
var stfile = await StorageFile.GetFileFromApplicationUriAsync(file);
|
||||
return await this.Unpack(stfile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a specified folder.
|
||||
/// </summary>
|
||||
/// <param name="file">An URI to the tarball file.</param>
|
||||
/// <param name="destination">A folder where files will be unpacked.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack(Uri file, StorageFolder destination)
|
||||
{
|
||||
var stfile = await StorageFile.GetFileFromApplicationUriAsync(file);
|
||||
return await this.Unpack(stfile, destination);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a temporary folder.
|
||||
/// </summary>
|
||||
/// <param name="file">A path to the tarball file.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack(string file)
|
||||
{
|
||||
var stfile = await StorageFile.GetFileFromPathAsync(file);
|
||||
return await this.Unpack(stfile);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a specified folder.
|
||||
/// </summary>
|
||||
/// <param name="file">A path to the tarball file.</param>
|
||||
/// <param name="destination">A folder where files will be unpacked.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack(string file, StorageFolder destination)
|
||||
{
|
||||
var stfile = await StorageFile.GetFileFromPathAsync(file);
|
||||
return await this.Unpack(stfile, destination);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a temporary folder.
|
||||
/// </summary>
|
||||
/// <param name="file">The tarball file.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack(StorageFile file)
|
||||
{
|
||||
// Prepare temp folder
|
||||
var dest = await this.CreateTempFolder();
|
||||
|
||||
// Unpack
|
||||
await this.Initialize(file);
|
||||
await this.UnpackFiles(dest);
|
||||
this.Dispose();
|
||||
|
||||
// Results
|
||||
return dest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks a tarball in a specified folder.
|
||||
/// </summary>
|
||||
/// <param name="file">The tarball file.</param>
|
||||
/// <param name="destination">A folder where files will be unpacked.</param>
|
||||
/// <returns>Storage folder pointing to where the files were unpacked.</returns>
|
||||
public async Task<StorageFolder> Unpack(StorageFile file, StorageFolder destination)
|
||||
{
|
||||
// Unpack
|
||||
await this.Initialize(file);
|
||||
await this.UnpackFiles(destination);
|
||||
this.Dispose();
|
||||
|
||||
// Results
|
||||
return destination;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialize, dispose
|
||||
/// <summary>
|
||||
/// Performs initialization actions before unpacking (such as opening the stream).
|
||||
/// </summary>
|
||||
private async Task Initialize(StorageFile file)
|
||||
{
|
||||
var str = await file.OpenReadAsync();
|
||||
this.stream = str.AsStream();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs cleanups after unpacking finished.
|
||||
/// </summary>
|
||||
private void Dispose()
|
||||
{
|
||||
// Clean up
|
||||
this.stream.Dispose();
|
||||
this.stream = null;
|
||||
|
||||
this.header = new TarballHeader();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Headers
|
||||
/// <summary>
|
||||
/// Calculates the checksum from a header.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The header bytes</param>
|
||||
private uint CalculateChecksum(byte[] buffer)
|
||||
{
|
||||
uint result = 0;
|
||||
|
||||
// Calculate sum of all bytes, with the exception of bytes 148-155
|
||||
// (checksum field). These are all assumed to be 0x20.
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
if (i >= 148 && i < 156)
|
||||
result += 0x20;
|
||||
else result += Convert.ToUInt32(buffer[i]);
|
||||
|
||||
// Done
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts binary data to a TarballHeader.
|
||||
/// </summary>
|
||||
private TarballHeader ParseHeaderFields(byte[] buffer)
|
||||
{
|
||||
TarballHeader header = new TarballHeader();
|
||||
string temp;
|
||||
|
||||
// File name
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 100).Trim('\0', ' ');
|
||||
header.FileName = temp;
|
||||
|
||||
// File mode
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 100, 8).Trim('\0', ' ');
|
||||
header.FileMode = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToUInt32(temp, 8);
|
||||
|
||||
// Owner id
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 108, 8).Trim('\0', ' ');
|
||||
header.OwnerId = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToUInt32(temp, 8);
|
||||
|
||||
// Group id
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 116, 8).Trim('\0', ' ');
|
||||
header.GroupId = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToUInt32(temp, 8);
|
||||
|
||||
// Size
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 124, 12).Trim('\0', ' ');
|
||||
header.Size = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToInt32(temp, 8);
|
||||
|
||||
// Last modified date
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 136, 12).Trim('\0', ' ');
|
||||
int seconds = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToInt32(temp, 8);
|
||||
header.LastModified = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(seconds).ToLocalTime();
|
||||
|
||||
// Checksum
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 148, 8).Trim('\0', ' ');
|
||||
header.Checksum = (string.IsNullOrEmpty(temp)) ? 0 : Convert.ToUInt32(temp, 8);
|
||||
|
||||
// Link indicator
|
||||
header.LinkIndicator = buffer[156];
|
||||
|
||||
// Linked file
|
||||
temp = SharpDX.Text.ASCIIEncoding.ASCII.GetString(buffer, 157, 100).Trim('\0', ' ');
|
||||
header.LinkedFile = temp;
|
||||
|
||||
// Done
|
||||
return header;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a file header.
|
||||
/// </summary>
|
||||
/// <returns>True if another header was read, false otherwise.</returns>
|
||||
private async Task<bool> ReadNextFileHeader()
|
||||
{
|
||||
byte[] buffer = new byte[512];
|
||||
|
||||
// Check current position
|
||||
if (stream.Position >= stream.Length)
|
||||
return false;
|
||||
|
||||
// Read header
|
||||
await stream.ReadAsync(buffer, 0, 512);
|
||||
|
||||
// Parse header fields
|
||||
this.header = this.ParseHeaderFields(buffer);
|
||||
|
||||
// Verify checksum
|
||||
uint checksum = this.CalculateChecksum(buffer);
|
||||
|
||||
if (checksum == 256) // If 256 (only the checksum bytes different than 0), then
|
||||
return false; // we most likely hit an invalid entry, probably marking the
|
||||
// end of the file
|
||||
if (checksum != header.Checksum)
|
||||
throw new IOException("Invalid checksum!");
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region File system helpers
|
||||
/// <summary>
|
||||
/// Creates a temporary folder.
|
||||
/// </summary>
|
||||
private async Task<StorageFolder> CreateTempFolder()
|
||||
{
|
||||
// Generate file name
|
||||
string name = "tar" + DateTime.Now.Ticks.ToString();
|
||||
|
||||
// Create file
|
||||
var temp = ApplicationData.Current.TemporaryFolder;
|
||||
return await temp.CreateFolderAsync(name, CreationCollisionOption.GenerateUniqueName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unpack
|
||||
/// <summary>
|
||||
/// Unpacks a file using the information from the header.
|
||||
/// The function assumes the header was previously read.
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination file.</param>
|
||||
private async Task UnpackNextFile(StorageFile destination)
|
||||
{
|
||||
// Open destination file
|
||||
var str = await destination.OpenAsync(FileAccessMode.ReadWrite);
|
||||
var iostr = str.AsStream();
|
||||
|
||||
// Write data
|
||||
var buffer = new byte[512];
|
||||
int read = 0, total = 0;
|
||||
|
||||
while (total < this.header.Size)
|
||||
{
|
||||
read = await this.stream.ReadAsync(buffer, 0, 512);
|
||||
await iostr.WriteAsync(buffer, 0, Math.Min(read, this.header.Size - total));
|
||||
total += read;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
await iostr.FlushAsync();
|
||||
iostr.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the files from the loaded tarball.
|
||||
/// </summary>
|
||||
/// <param name="destination">Destination folder.</param>
|
||||
private async Task UnpackFiles(StorageFolder destination)
|
||||
{
|
||||
if (this.stream == null)
|
||||
throw new ArgumentNullException("No file opened!");
|
||||
|
||||
while (await this.ReadNextFileHeader())
|
||||
{
|
||||
// Directory?
|
||||
if (this.header.FileName.EndsWith("/"))
|
||||
await IOHelper.CreateFolderRelativeAsync(destination, this.header.FileName);
|
||||
|
||||
// Create file
|
||||
else
|
||||
{
|
||||
var file = await IOHelper.CreateFileRelativeAsync(destination, this.header.FileName);
|
||||
await this.UnpackNextFile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 325 KiB |
Binary file not shown.
Binary file not shown.
BIN
DrumKit/Build/ApplicationData/Drumkits/Default/Sounds/Ride06.wav
Normal file
BIN
DrumKit/Build/ApplicationData/Drumkits/Default/Sounds/Ride06.wav
Normal file
Binary file not shown.
@ -89,56 +89,10 @@
|
||||
<image>Images/plate.png</image>
|
||||
<imagePressed>Images/platePressed.png</imagePressed>
|
||||
<sounds>
|
||||
<sound intensity="0">Sounds/Ride04.wav</sound>
|
||||
<sound intensity="0">Sounds/Ride06.wav</sound>
|
||||
</sounds>
|
||||
</drum>
|
||||
|
||||
</drums>
|
||||
|
||||
<!--
|
||||
[Kick]
|
||||
position=.41,.2
|
||||
size=.3
|
||||
image=ms-appx:///Assets/Drums/big_drum_of.png
|
||||
sound,0=ms-appx:///Assets/Sounds/Kick07.wav
|
||||
[Snare]
|
||||
position=.16,.34
|
||||
size=.25
|
||||
image=ms-appx:///Assets/Drums/drum_of.png
|
||||
sound,0=ms-appx:///Assets/Sounds/Snare08.wav
|
||||
[High Tom]
|
||||
position=.33,.05
|
||||
size=.22
|
||||
image=ms-appx:///Assets/Drums/drum_of.png
|
||||
sound,0=ms-appx:///Assets/Sounds/TomHigh04.wav
|
||||
[Low Tom]
|
||||
position=.55,.05
|
||||
size=.22
|
||||
image=ms-appx:///Assets/Drums/drum_of.png
|
||||
sound,0=ms-appx:///Assets/Sounds/TomLow04.wav
|
||||
[Floor Tom]
|
||||
position=.66,.44
|
||||
size=.29
|
||||
image=ms-appx:///Assets/Drums/drum_of.png
|
||||
sound,0=ms-appx:///Assets/Sounds/Floor04.wav
|
||||
[Hi-Hat Closed]
|
||||
position=.10,.87
|
||||
size=.05
|
||||
image=ms-appx:///Assets/Drums/HiHat_off.png
|
||||
sound,0=ms-appx:///Assets/Sounds/HiHatClosed04.wav
|
||||
[Hi-Hat Opened]
|
||||
position=.03,.55
|
||||
size=.21
|
||||
image=ms-appx:///Assets/Drums/plate_off.png
|
||||
sound,0=ms-appx:///Assets/Sounds/HiHatOpen04.wav
|
||||
[Crash]
|
||||
position=.1,.02
|
||||
size=.25
|
||||
image=ms-appx:///Assets/Drums/plate_off.png
|
||||
sound,0=ms-appx:///Assets/Sounds/Crash05.wav
|
||||
[Ride]
|
||||
position=.72,.04
|
||||
size=.25
|
||||
image=ms-appx:///Assets/Drums/plate_off.png
|
||||
sound,0=ms-appx:///Assets/Sounds/Ride04.wav-->
|
||||
|
||||
</drumkit>
|
@ -2,76 +2,222 @@
|
||||
|
||||
<drumkitLayoutCollection>
|
||||
|
||||
<items>
|
||||
<!-- Standard layout - all views -->
|
||||
<drumkitLayout>
|
||||
<name>Standard layout</name>
|
||||
<targetView>Snapped|Landscape|Filled|Portrait</targetView>
|
||||
<isDefault>true</isDefault>
|
||||
<items>
|
||||
<!-- Standard layout - all views -->
|
||||
<drumkitLayout>
|
||||
<name>Standard layout</name>
|
||||
<targetView>All</targetView>
|
||||
<isDefault>true</isDefault>
|
||||
|
||||
<drums>
|
||||
<drumLayout targetId="defaultkick">
|
||||
<size>.3</size>
|
||||
<x>.41</x>
|
||||
<y>.2</y>
|
||||
<zindex>0</zindex>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultsnare">
|
||||
<size>.25</size>
|
||||
<x>.16</x>
|
||||
<y>.34</y>
|
||||
<zindex>2</zindex>
|
||||
<angle>61</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthitom">
|
||||
<size>.22</size>
|
||||
<x>.33</x>
|
||||
<y>.05</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>150</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultlotom">
|
||||
<size>.22</size>
|
||||
<x>.55</x>
|
||||
<y>.05</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>150</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultfltom">
|
||||
<size>.29</size>
|
||||
<x>.66</x>
|
||||
<y>.44</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>-30</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatcl">
|
||||
<size>.055</size>
|
||||
<x>.11</x>
|
||||
<y>.89</y>
|
||||
<zindex>3</zindex>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatop">
|
||||
<size>.21</size>
|
||||
<x>.03</x>
|
||||
<y>.55</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>80</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultcrash">
|
||||
<size>.26</size>
|
||||
<x>.1</x>
|
||||
<y>.02</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>80</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultride">
|
||||
<size>.25</size>
|
||||
<x>.72</x>
|
||||
<y>.04</y>
|
||||
<zindex>4</zindex>
|
||||
</drumLayout>
|
||||
</drums>
|
||||
</drumkitLayout>
|
||||
|
||||
<drumkitLayout>
|
||||
<name>Portrait layout</name>
|
||||
<targetView>Portrait</targetView>
|
||||
<isDefault>true</isDefault>
|
||||
|
||||
<drums>
|
||||
<drumLayout targetId="defaultkick">
|
||||
<size>0.53359375</size>
|
||||
<x>.2</x>
|
||||
<y>.39</y>
|
||||
<zindex>0</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultsnare">
|
||||
<size>0.4446614583</size>
|
||||
<x>.34</x>
|
||||
<y>.64</y>
|
||||
<zindex>2</zindex>
|
||||
<angle>-29</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthitom">
|
||||
<size>0.3913020833</size>
|
||||
<x>.05</x>
|
||||
<y>.47</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>60</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultlotom">
|
||||
<size>0.3913020833</size>
|
||||
<x>.05</x>
|
||||
<y>.25</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>60</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultfltom">
|
||||
<size>0.5158072917</size>
|
||||
<x>.44</x>
|
||||
<y>.14</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>-120</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatcl">
|
||||
<size>0.0978255208</size>
|
||||
<x>.89</x>
|
||||
<y>.69</y>
|
||||
<zindex>3</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatop">
|
||||
<size>0.373515625</size>
|
||||
<x>.55</x>
|
||||
<y>.77</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-10</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultcrash">
|
||||
<size>0.4624479167</size>
|
||||
<x>.02</x>
|
||||
<y>.7</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-10</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultride">
|
||||
<size>0.4446614583</size>
|
||||
<x>.04</x>
|
||||
<y>.08</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
</drums>
|
||||
|
||||
</drumkitLayout>
|
||||
|
||||
<drumkitLayout>
|
||||
<name>Snapped layout</name>
|
||||
<targetView>Snapped</targetView>
|
||||
<isDefault>true</isDefault>
|
||||
|
||||
<drums>
|
||||
<drumLayout targetId="defaultkick">
|
||||
<size>0.6</size>
|
||||
<x>0.49444900512695339</x>
|
||||
<y>0.32627955277760762</y>
|
||||
<zindex>0</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultsnare">
|
||||
<size>0.5</size>
|
||||
<x>0.39433132171630869</x>
|
||||
<y>0.56396647930145249</y>
|
||||
<zindex>2</zindex>
|
||||
<angle>61</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthitom">
|
||||
<size>0.44</size>
|
||||
<x>0.057991533279419152</x>
|
||||
<y>0.43292328516642276</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>60</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultlotom">
|
||||
<size>0.44</size>
|
||||
<x>0.087597298622131434</x>
|
||||
<y>0.26619099378585825</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>60</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultfltom">
|
||||
<size>0.58</size>
|
||||
<x>0.47881852149963317</x>
|
||||
<y>0.10023623943328863</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>-120</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatcl">
|
||||
<size>0.11</size>
|
||||
<x>0.83815117835998587</x>
|
||||
<y>0.80136797269185378</y>
|
||||
<zindex>3</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatop">
|
||||
<size>0.42</size>
|
||||
<x>0.45826869487762456</x>
|
||||
<y>0.74660433133443138</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-10</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultcrash">
|
||||
<size>0.52</size>
|
||||
<x>-0.015512061119079568</x>
|
||||
<y>0.62290350516637261</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-10</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultride">
|
||||
<size>0.5</size>
|
||||
<x>0.019840950965881135</x>
|
||||
<y>0.06086617549260457</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>-90</angle>
|
||||
</drumLayout>
|
||||
</drums>
|
||||
|
||||
</drumkitLayout>
|
||||
</items>
|
||||
|
||||
<drums>
|
||||
<drumLayout targetId="defaultkick">
|
||||
<size>.3</size>
|
||||
<x>.41</x>
|
||||
<y>.2</y>
|
||||
<zindex>0</zindex>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultsnare">
|
||||
<size>.25</size>
|
||||
<x>.16</x>
|
||||
<y>.34</y>
|
||||
<zindex>2</zindex>
|
||||
<angle>61</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthitom">
|
||||
<size>.22</size>
|
||||
<x>.33</x>
|
||||
<y>.05</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>150</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultlotom">
|
||||
<size>.22</size>
|
||||
<x>.55</x>
|
||||
<y>.05</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>150</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultfltom">
|
||||
<size>.29</size>
|
||||
<x>.66</x>
|
||||
<y>.44</y>
|
||||
<zindex>1</zindex>
|
||||
<angle>-30</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatcl">
|
||||
<size>.055</size>
|
||||
<x>.11</x>
|
||||
<y>.89</y>
|
||||
<zindex>3</zindex>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaulthihatop">
|
||||
<size>.21</size>
|
||||
<x>.03</x>
|
||||
<y>.55</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>80</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultcrash">
|
||||
<size>.26</size>
|
||||
<x>.1</x>
|
||||
<y>.02</y>
|
||||
<zindex>4</zindex>
|
||||
<angle>80</angle>
|
||||
</drumLayout>
|
||||
<drumLayout targetId="defaultride">
|
||||
<size>.25</size>
|
||||
<x>.72</x>
|
||||
<y>.04</y>
|
||||
<zindex>4</zindex>
|
||||
</drumLayout>
|
||||
</drums>
|
||||
</drumkitLayout>
|
||||
</items>
|
||||
|
||||
</drumkitLayoutCollection>
|
@ -27,7 +27,10 @@
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<x:String x:Key="ChevronGlyph"></x:String>
|
||||
|
||||
|
||||
<!-- User defined brushes -->
|
||||
<SolidColorBrush x:Key="ApplicationBackgroundColor" Color="#164646" />
|
||||
|
||||
<!-- RichTextBlock styles -->
|
||||
|
||||
<Style x:Key="BasicRichTextStyle" TargetType="RichTextBlock">
|
||||
@ -233,6 +236,11 @@
|
||||
<Setter Property="Foreground" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyButtonStyle" TargetType="Button" BasedOn="{StaticResource TextButtonStyle}">
|
||||
<Setter Property="Margin" Value="0,0,14,0" />
|
||||
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
TextRadioButtonStyle is used to style a RadioButton using subheader-styled text with no other adornment.
|
||||
This style is used in the SearchResultsPage to allow selection among filters.
|
||||
@ -429,8 +437,20 @@
|
||||
<Setter Property="AutomationProperties.Name" Value="Video"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
|
||||
<Style x:Key="DeleteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="DeleteAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Delete"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SaveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Save"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
|
||||
<Style x:Key="SkipBackAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="SkipBackAppBarButton"/>
|
||||
@ -443,16 +463,7 @@
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SaveAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="SaveAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Save"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
<Style x:Key="DeleteAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="DeleteAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Delete"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DiscardAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="DiscardAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Discard"/>
|
||||
@ -523,12 +534,15 @@
|
||||
<Setter Property="AutomationProperties.Name" Value="Photo"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
</Style>
|
||||
|
||||
|
||||
-->
|
||||
|
||||
<Style x:Key="SettingsAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
|
||||
<Setter Property="AutomationProperties.AutomationId" Value="SettingsAppBarButton"/>
|
||||
<Setter Property="AutomationProperties.Name" Value="Settings"/>
|
||||
<Setter Property="Content" Value=""/>
|
||||
<Setter Property="Content" Value="" />
|
||||
</Style>
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
@ -1833,4 +1847,10 @@
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<SolidColorBrush x:Key="ListViewItemSelectedBackgroundThemeBrush" Color="#075369"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="ListViewItemPointerOverBackgroundThemeBrush" Color="#30ffffff"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="ListViewItemSelectedPointerOverBackgroundThemeBrush" Color="#ab188DAD"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="ListViewItemSelectedPointerOverBorderThemeBrush" Color="#ab188DAD"></SolidColorBrush>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
155
DrumKit/Common/TextButtonStyles.xaml
Normal file
155
DrumKit/Common/TextButtonStyles.xaml
Normal file
@ -0,0 +1,155 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<SolidColorBrush x:Key="TextBoxBackgroundThemeBrush" Color="#ffff" />
|
||||
<SolidColorBrush x:Key="TextBoxBorderThemeBrush" Color="#efff" />
|
||||
<SolidColorBrush x:Key="TextBoxDisabledBackgroundThemeBrush" Color="Transparent" />
|
||||
<SolidColorBrush x:Key="TextBoxDisabledBorderThemeBrush" Color="#66FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextBoxDisabledForegroundThemeBrush" Color="#FF666666" />
|
||||
<SolidColorBrush x:Key="TextBoxForegroundThemeBrush" Color="#f000" />
|
||||
|
||||
<x:Double x:Key="TextControlBackgroundThemeOpacity">0</x:Double>
|
||||
<x:Double x:Key="TextControlBorderThemeOpacity">0</x:Double>
|
||||
<x:Double x:Key="TextControlPointerOverBackgroundThemeOpacity">0.17</x:Double>
|
||||
<x:Double x:Key="TextControlPointerOverBorderThemeOpacity">0.17</x:Double>
|
||||
<x:Double x:Key="TextControlThemeMinHeight">32</x:Double>
|
||||
<x:Double x:Key="TextControlThemeMinWidth">64</x:Double>
|
||||
<Thickness x:Key="TextControlBorderThemeThickness">2</Thickness>
|
||||
<Thickness x:Key="TextControlThemePadding">10,3,10,5</Thickness>
|
||||
|
||||
<Style x:Key="MyTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="MinWidth" Value="{StaticResource TextControlThemeMinWidth}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource TextControlThemeMinHeight}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextBoxForegroundThemeBrush}" />
|
||||
<Setter Property="Background" Value="{StaticResource TextBoxBackgroundThemeBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderThemeBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{StaticResource TextControlBorderThemeThickness}" />
|
||||
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
|
||||
<Setter Property="Padding" Value="{StaticResource TextControlThemePadding}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TextBox">
|
||||
<Grid>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledBackgroundThemeBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledBorderThemeBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledForegroundThemeBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="EditIconElement"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="White" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Normal">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="BackgroundElement"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0"
|
||||
To="0" />
|
||||
<DoubleAnimation Storyboard.TargetName="BorderElement"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0"
|
||||
To="0" />
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="White" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="BackgroundElement"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0"
|
||||
To="0.1" />
|
||||
<DoubleAnimation Storyboard.TargetName="BorderElement"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0"
|
||||
To="0.1" />
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="White" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Focused">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="EditIconElement"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Gray" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="0" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border x:Name="BackgroundElement"
|
||||
Background="{TemplateBinding Background}"
|
||||
Margin="{TemplateBinding BorderThickness}"
|
||||
Grid.ColumnSpan="3"/>
|
||||
|
||||
<Border x:Name="BorderElement"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Grid.ColumnSpan="3"/>
|
||||
|
||||
<TextBlock x:Name="EditIconElement"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Margin="5,5,0,5"
|
||||
Foreground="#8fff"
|
||||
FontFamily="{StaticResource SymbolThemeFontFamily}"
|
||||
FontStyle="Normal" FontSize="14"
|
||||
Opacity=".6"
|
||||
Text="" />
|
||||
|
||||
<ScrollViewer x:Name="ContentElement"
|
||||
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
|
||||
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
|
||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
|
||||
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
|
||||
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
|
||||
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
|
||||
Margin="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
IsTabStop="False"
|
||||
ZoomMode="Disabled"
|
||||
Grid.Column="1"/>
|
||||
|
||||
<Button x:Name="DeleteButton"
|
||||
IsTabStop="False"
|
||||
Grid.Column="2"
|
||||
Visibility="Collapsed"
|
||||
Opacity="0"
|
||||
IsEnabled="False" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
20
DrumKit/Controller/ControllerException.cs
Normal file
20
DrumKit/Controller/ControllerException.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
class ControllerException : Exception
|
||||
{
|
||||
public ControllerException() :
|
||||
base() { }
|
||||
|
||||
public ControllerException(string message) :
|
||||
base(message) { }
|
||||
|
||||
public ControllerException(string message, Exception innerException) :
|
||||
base(message, innerException) { }
|
||||
}
|
||||
}
|
440
DrumKit/Controller/DataController.cs
Normal file
440
DrumKit/Controller/DataController.cs
Normal file
@ -0,0 +1,440 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public static class DataController
|
||||
{
|
||||
#region Fields: Repositories
|
||||
|
||||
private static Repository.DataRepository DataRepo { get; set; }
|
||||
private static Repository.DrumkitRepository DrumkitRepo { get; set; }
|
||||
private static Repository.SoundRepository SoundRepository { get; set; }
|
||||
|
||||
private static SoundPool SoundPool { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields: Timers
|
||||
private static DispatcherTimer saveConfigTimer { get; set; }
|
||||
private static DispatcherTimer saveLayoutTimer { get; set; }
|
||||
private static DispatcherTimer saveSettingsTimer { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Fields: Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets application's installation info
|
||||
/// </summary>
|
||||
public static AppInstallInfo InstallInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DataRepo == null) ? null : DataRepo.InstallInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets application's settings.
|
||||
/// </summary>
|
||||
public static AppSettings Settings
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DataRepo == null) ? null : DataRepo.Settings;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of available drumkits.
|
||||
/// </summary>
|
||||
public static Dictionary<string, Drumkit> AvailableDrumkits
|
||||
{
|
||||
get
|
||||
{
|
||||
return (DrumkitRepo == null) ? null : DrumkitRepo.AvailableDrumKits;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current drumkit.
|
||||
/// </summary>
|
||||
public static Drumkit CurrentDrumkit
|
||||
{
|
||||
get
|
||||
{
|
||||
return AvailableDrumkits[CurrentDrumkitName];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
CurrentDrumkitName = value.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current drumkit names.
|
||||
/// </summary>
|
||||
public static string CurrentDrumkitName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current drumkit layouts.
|
||||
/// </summary>
|
||||
public static DrumkitLayoutCollection CurrentLayouts { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current drums configuration.
|
||||
/// </summary>
|
||||
public static DrumkitConfig CurrentConfig { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master volume.
|
||||
/// </summary>
|
||||
public static float MasterVolume
|
||||
{
|
||||
get {
|
||||
return Settings.MasterVolume;
|
||||
}
|
||||
|
||||
set {
|
||||
Settings.MasterVolume = value;
|
||||
SoundPool.MasterVolume = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Triggered when the progress of the initialize method changed.
|
||||
/// </summary>
|
||||
public static event EventHandler<KeyValuePair<int, string>> ProgressChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Initializes everything.
|
||||
/// </summary>
|
||||
public static async Task Initialize()
|
||||
{
|
||||
// Initialize timers
|
||||
InitializeTimers();
|
||||
|
||||
// Prepare data
|
||||
ReportProgress(1 * 100 / 8, "Loading data...");
|
||||
await InitializeData();
|
||||
|
||||
// Open log file
|
||||
await Log.Initialize();
|
||||
|
||||
// Prepare drumkits
|
||||
ReportProgress(4 * 100 / 8, "Loading drums...");
|
||||
await InitializeDrumkits();
|
||||
|
||||
// Figure out current drumkit, throw ControllerException if nothing found.
|
||||
CurrentDrumkitName = GetCurrentDrumkit();
|
||||
|
||||
// Load drumkit layouts and config
|
||||
ReportProgress(5 * 100 / 8, "Loading drums...");
|
||||
CurrentLayouts = await DrumkitRepo.ReadLayouts(CurrentDrumkitName);
|
||||
CurrentConfig = await DrumkitRepo.ReadConfig(CurrentDrumkitName);
|
||||
|
||||
// Load drumkit sounds
|
||||
ReportProgress(6 * 100 / 8, "Loading sounds...");
|
||||
await InitializeSounds();
|
||||
|
||||
// Load user interface (images and stuff)
|
||||
ReportProgress(7 * 100 / 8, "Loading interface...");
|
||||
await InitializeUI();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the timers for IO operations
|
||||
/// The timers are used in order to avoid problems from too many IO requests in a short period of time.
|
||||
/// </summary>
|
||||
private static void InitializeTimers()
|
||||
{
|
||||
saveConfigTimer = new DispatcherTimer();
|
||||
saveConfigTimer.Interval = TimeSpan.FromSeconds(.5);
|
||||
saveConfigTimer.Tick += SaveConfigTick;
|
||||
|
||||
saveLayoutTimer = new DispatcherTimer();
|
||||
saveLayoutTimer.Interval = TimeSpan.FromSeconds(.5);
|
||||
saveLayoutTimer.Tick += SaveLayoutTick;
|
||||
|
||||
saveSettingsTimer = new DispatcherTimer();
|
||||
saveSettingsTimer.Interval = TimeSpan.FromSeconds(.5);
|
||||
saveSettingsTimer.Tick += SaveSettingsTick;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the data: loads settings, app install info, performs after install actions.
|
||||
/// </summary>
|
||||
private static async Task InitializeData()
|
||||
{
|
||||
DataRepo = new Repository.DataRepository();
|
||||
await DataRepo.Initialize(ApplicationData.Current);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the drumkit repository: loads information about every drumkit
|
||||
/// </summary>
|
||||
private static async Task InitializeDrumkits()
|
||||
{
|
||||
StorageFolder repo = await ApplicationData.Current.RoamingFolder.CreateFolderAsync("Drumkits", CreationCollisionOption.OpenIfExists);
|
||||
DrumkitRepo = new Repository.DrumkitRepository();
|
||||
await DrumkitRepo.Initialize(repo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the sound repository: loads all the drums associated with the current drumkit, creates soundpool.
|
||||
/// </summary>
|
||||
private static async Task InitializeSounds()
|
||||
{
|
||||
// Create repository
|
||||
StorageFolder repo = CurrentDrumkit.RootFolder;
|
||||
SoundRepository = new Repository.SoundRepository(repo);
|
||||
|
||||
// Load drums
|
||||
foreach (var i in CurrentDrumkit.DrumsList)
|
||||
if (CurrentConfig.Drums[i.Id].IsEnabled)
|
||||
await SoundRepository.LoadSounds(i);
|
||||
|
||||
// Create soundpool
|
||||
if (SoundRepository.LoadedSounds.Count > 0)
|
||||
SoundPool = new SoundPool(SoundRepository.LoadedSounds.First().Value.WaveFormat, Settings.Polyphony);
|
||||
|
||||
else
|
||||
SoundPool = new SoundPool(new SharpDX.Multimedia.WaveFormat(), Settings.Polyphony);
|
||||
|
||||
SoundPool.MasterVolume = Settings.MasterVolume;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the current drumkit
|
||||
/// </summary>
|
||||
private static string GetCurrentDrumkit()
|
||||
{
|
||||
// Try the application settings
|
||||
if (AvailableDrumkits.ContainsKey(Settings.CurrentKit))
|
||||
return Settings.CurrentKit;
|
||||
|
||||
// Nope, try default
|
||||
if (AvailableDrumkits.ContainsKey("Default"))
|
||||
return "Default";
|
||||
|
||||
// Nope, try anything
|
||||
if (AvailableDrumkits.Count > 0)
|
||||
return AvailableDrumkits.First().Key;
|
||||
|
||||
// Still nothing? Error
|
||||
throw new ControllerException("No drumkits available!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the drum images
|
||||
/// </summary>
|
||||
private static async Task InitializeUI()
|
||||
{
|
||||
// Load images
|
||||
foreach (var i in CurrentDrumkit.DrumsList)
|
||||
{
|
||||
i.LoadedImageSource = await IOHelper.GetImageAsync(CurrentDrumkit.RootFolder, i.ImageSource);
|
||||
i.LoadedImagePressedSource = await IOHelper.GetImageAsync(CurrentDrumkit.RootFolder, i.ImagePressedSource);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Resets to factory settings
|
||||
/// </summary>
|
||||
public static async Task FactoryReset()
|
||||
{
|
||||
await ApplicationData.Current.ClearAsync();
|
||||
}
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Reports current progress (calls event).
|
||||
/// </summary>
|
||||
/// <param name="percent">Percentage of task completed.</param>
|
||||
/// <param name="info">What is happening, like a message to the user.</param>
|
||||
private static void ReportProgress(int percent, string info)
|
||||
{
|
||||
if (ProgressChanged != null)
|
||||
ProgressChanged(null, new KeyValuePair<int, string>(percent, info));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Playback
|
||||
/// <summary>
|
||||
/// Plays a sound if loaded.
|
||||
/// </summary>
|
||||
/// <param name="drum_id">ID of the drum the sound belongs to.</param>
|
||||
/// <param name="intensity">Intensity of sound</param>
|
||||
public static void PlaySound(string drum_id, int intensity=0)
|
||||
{
|
||||
// Get sound
|
||||
Sound? sound = SoundRepository.GetLoadedSound(drum_id, intensity);
|
||||
|
||||
// If possible, play
|
||||
if (sound.HasValue)
|
||||
{
|
||||
float l = Convert.ToSingle(CurrentConfig.Drums[drum_id].VolumeL);
|
||||
float r = Convert.ToSingle(CurrentConfig.Drums[drum_id].VolumeR);
|
||||
|
||||
SoundPool.PlayBuffer(sound.Value, l, r);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Drumkit repository
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a drumkit from the system.
|
||||
/// </summary>
|
||||
/// <param name="name">Name (identifier) of drumkit</param>
|
||||
public static async Task RemoveDrumkit (string name)
|
||||
{
|
||||
// Make sure there is at least a drumkit remaining
|
||||
if (AvailableDrumkits.Count <= 1)
|
||||
throw new ControllerException("Cannot remove last drumkit.");
|
||||
|
||||
// Is it current drumkit?
|
||||
if (name == CurrentDrumkitName)
|
||||
throw new ArgumentException("Cannot remove currently loaded drumkit.");
|
||||
|
||||
// Remove
|
||||
await DrumkitRepo.Remove(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Installs a drumkit package.
|
||||
/// </summary>
|
||||
/// <param name="tarball">A .tar file</param>
|
||||
public static async Task InstallDrumkit(StorageFile tarball)
|
||||
{
|
||||
await DrumkitRepo.InstallTarball(tarball);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports a drumkit package.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_key">The key of the drumkit to export</param>
|
||||
/// <param name="tarball">The destination file</param>
|
||||
public static async Task ExportDrumkit(string drumkit_key, StorageFile tarball)
|
||||
{
|
||||
await DrumkitRepo.ExportTarball(drumkit_key, tarball);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new layout
|
||||
/// </summary>
|
||||
public static void CreateLayout()
|
||||
{
|
||||
// Create object
|
||||
var layout = new DrumkitLayout();
|
||||
|
||||
// Add layout for each of the existing drums
|
||||
foreach (var i in CurrentDrumkit.Drums.Keys)
|
||||
layout.Drums.Add(i, new DrumLayout() { TargetId = i });
|
||||
|
||||
// Add to layout list
|
||||
CurrentLayouts.Items.Add(layout);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Save methods
|
||||
/// <summary>
|
||||
/// Saves the drum configuration settings for current drumkit.
|
||||
/// </summary>
|
||||
public static void SaveConfig()
|
||||
{
|
||||
saveConfigTimer.Stop();
|
||||
saveConfigTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the drum layout settings for current drumkit.
|
||||
/// </summary>
|
||||
public static void SaveLayout()
|
||||
{
|
||||
saveLayoutTimer.Stop();
|
||||
saveLayoutTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the applications settings.
|
||||
/// </summary>
|
||||
public static void SaveSettings()
|
||||
{
|
||||
saveSettingsTimer.Stop();
|
||||
saveSettingsTimer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save settings timer.
|
||||
/// </summary>
|
||||
private static async void SaveSettingsTick(object sender, object e)
|
||||
{
|
||||
// Save settings
|
||||
await DataRepo.WriteSettings();
|
||||
Log.Write("Saved settings");
|
||||
|
||||
// Stop timer
|
||||
var timer = sender as DispatcherTimer;
|
||||
if (timer != null)
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save layouts timer
|
||||
/// </summary>
|
||||
private static async void SaveLayoutTick(object sender, object e)
|
||||
{
|
||||
// Save layouts
|
||||
await DrumkitRepo.WriteLayouts(CurrentDrumkitName, CurrentLayouts);
|
||||
Log.Write("Saved layout...");
|
||||
|
||||
// Stop timer
|
||||
var timer = sender as DispatcherTimer;
|
||||
if (timer != null)
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save drum configuration timer.
|
||||
/// </summary>
|
||||
private static async void SaveConfigTick(object sender, object e)
|
||||
{
|
||||
// Save drumkit configuration
|
||||
await DrumkitRepo.WriteConfig(CurrentDrumkitName, CurrentConfig);
|
||||
Log.Write("Saved configuration...");
|
||||
|
||||
// Stop timer
|
||||
var timer = sender as DispatcherTimer;
|
||||
if (timer != null)
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Saves settings and other stuff
|
||||
/// </summary>
|
||||
public static void Dispose()
|
||||
{
|
||||
DrumkitRepo.Dispose();
|
||||
SoundRepository.Dispose();
|
||||
SoundPool.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
27
DrumKit/Domain/AppInstallInfo.cs
Normal file
27
DrumKit/Domain/AppInstallInfo.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
[XmlType("DrumkitInstalled")]
|
||||
public class AppInstallInfo
|
||||
{
|
||||
[XmlElement("when")]
|
||||
public DateTime When { get; set; }
|
||||
|
||||
[XmlElement("version")]
|
||||
public int Version { get; set; }
|
||||
|
||||
public AppInstallInfo()
|
||||
{
|
||||
this.When = DateTime.Now;
|
||||
var ver = typeof(AppInstallInfo).GetTypeInfo().Assembly.GetName().Version;
|
||||
this.Version = ver.Major * 1000 + ver.Minor;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,11 +19,23 @@ namespace DrumKit
|
||||
[XmlElement("animations")]
|
||||
public bool Animations { get; set; }
|
||||
|
||||
[XmlElement("masterVolume")]
|
||||
public float MasterVolume { get; set; }
|
||||
|
||||
[XmlElement("debugMode")]
|
||||
public bool DebugMode { get; set; }
|
||||
|
||||
[XmlElement("polyphony")]
|
||||
public int Polyphony { get; set; }
|
||||
|
||||
public AppSettings()
|
||||
{
|
||||
this.CurrentKit = "Default";
|
||||
this.ShowKeyBindings = false;
|
||||
this.Animations = true;
|
||||
this.MasterVolume = 0.8f;
|
||||
this.DebugMode = false;
|
||||
this.Polyphony = 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,24 @@ namespace DrumKit
|
||||
[XmlElement("image")]
|
||||
public string ImageSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image loaded into memory.
|
||||
/// </summary>
|
||||
[XmlIgnore()]
|
||||
public Windows.UI.Xaml.Media.ImageSource LoadedImageSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image uri.
|
||||
/// </summary>
|
||||
[XmlElement("imagePressed")]
|
||||
public string ImagePressedSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pressed image loaded into memory.
|
||||
/// </summary>
|
||||
[XmlIgnore()]
|
||||
public Windows.UI.Xaml.Media.ImageSource LoadedImagePressedSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of sound sources.
|
||||
/// </summary>
|
||||
@ -45,6 +57,10 @@ namespace DrumKit
|
||||
this.Name = null;
|
||||
this.ImageSource = null;
|
||||
this.ImagePressedSource = null;
|
||||
|
||||
this.LoadedImageSource = null;
|
||||
this.LoadedImagePressedSource = null;
|
||||
|
||||
this.Sounds = new List<SoundSource>();
|
||||
}
|
||||
|
||||
|
@ -36,9 +36,30 @@ namespace DrumKit
|
||||
[XmlElement("volumeR")]
|
||||
public double VolumeR { get; set; }
|
||||
|
||||
[XmlElement("vkey")]
|
||||
[XmlIgnore()]
|
||||
public Windows.System.VirtualKey Key { get; set; }
|
||||
|
||||
[XmlElement("vkey")]
|
||||
public string KeyString
|
||||
{
|
||||
get {
|
||||
if (Enum.IsDefined(typeof(Windows.System.VirtualKey), this.Key))
|
||||
return Enum.GetName(typeof(Windows.System.VirtualKey), this.Key);
|
||||
|
||||
return Convert.ToString((int)this.Key);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Windows.System.VirtualKey key;
|
||||
|
||||
if (Enum.TryParse(value, out key))
|
||||
this.Key = key;
|
||||
|
||||
else this.Key = (Windows.System.VirtualKey) int.Parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
public DrumConfig()
|
||||
{
|
||||
this.TargetId = null;
|
||||
|
@ -22,8 +22,29 @@ namespace DrumKit
|
||||
[XmlElement("layoutfile")]
|
||||
public string LayoutFilePath { get; set; }
|
||||
|
||||
[XmlIgnore()]
|
||||
public Dictionary<string, Drum> Drums { get; private set; }
|
||||
|
||||
[XmlArray("drums")]
|
||||
public List<Drum> Drums { get; set; }
|
||||
public Drum[] DrumsList {
|
||||
get {
|
||||
List<Drum> drums = new List<Drum>();
|
||||
|
||||
foreach (var i in Drums)
|
||||
drums.Add(i.Value);
|
||||
|
||||
return drums.ToArray();
|
||||
}
|
||||
|
||||
set {
|
||||
foreach (var i in value)
|
||||
Drums.Add(i.Id, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[XmlIgnore()]
|
||||
public Windows.Storage.StorageFolder RootFolder { get; set; }
|
||||
|
||||
public Drumkit()
|
||||
{
|
||||
@ -31,7 +52,8 @@ namespace DrumKit
|
||||
this.Description = null;
|
||||
this.ConfigFilePath = null;
|
||||
this.LayoutFilePath = null;
|
||||
this.Drums = new List<Drum>();
|
||||
this.Drums = new Dictionary<string,Drum>();
|
||||
this.RootFolder = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,35 @@ namespace DrumKit
|
||||
[XmlType("drumkitConfig")]
|
||||
public class DrumkitConfig
|
||||
{
|
||||
[XmlIgnore()]
|
||||
public Dictionary<string, DrumConfig> Drums { get; private set; }
|
||||
|
||||
[XmlArray("drums")]
|
||||
public List<DrumConfig> Drums { get; set; }
|
||||
public DrumConfig[] DrumsList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<DrumConfig> configs = new List<DrumConfig>();
|
||||
|
||||
foreach (var i in Drums)
|
||||
configs.Add(i.Value);
|
||||
|
||||
return configs.ToArray();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
foreach (var i in value)
|
||||
Drums.Add(i.TargetId, i);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public DrumkitConfig()
|
||||
{
|
||||
this.Drums = new Dictionary<string, DrumConfig>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace DrumKit
|
||||
public DrumkitLayoutTargetView TargetView { get; set; }
|
||||
|
||||
[XmlElement("targetView")]
|
||||
private string TargetViewSerialize
|
||||
public string TargetViewSerialize
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -65,15 +65,36 @@ namespace DrumKit
|
||||
[XmlElement("isDefault")]
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
[XmlIgnore()]
|
||||
public Dictionary<string, DrumLayout> Drums { get; set; }
|
||||
|
||||
[XmlArray("drums")]
|
||||
public List<DrumLayout> Drums { get; set; }
|
||||
public DrumLayout[] DrumsList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<DrumLayout> layouts = new List<DrumLayout>();
|
||||
|
||||
foreach (var i in this.Drums)
|
||||
layouts.Add(i.Value);
|
||||
|
||||
return layouts.ToArray();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
foreach (var i in value)
|
||||
this.Drums.Add(i.TargetId, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DrumkitLayout()
|
||||
{
|
||||
this.Name = null;
|
||||
this.IsDefault = false;
|
||||
this.Drums = new List<DrumLayout>();
|
||||
this.Drums = new Dictionary<string, DrumLayout>();
|
||||
this.TargetView = DrumkitLayoutTargetView.All;
|
||||
}
|
||||
}
|
||||
|
17
DrumKit/Domain/Sound.cs
Normal file
17
DrumKit/Domain/Sound.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using SharpDX.Multimedia;
|
||||
using SharpDX.XAudio2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public struct Sound
|
||||
{
|
||||
public AudioBuffer Buffer { get; set; }
|
||||
public uint[] DecodedPacketsInfo { get; set; }
|
||||
public WaveFormat WaveFormat { get; set; }
|
||||
}
|
||||
}
|
@ -106,11 +106,49 @@
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Archiving\TarballReader.cs" />
|
||||
<Compile Include="Controller\DataController.cs" />
|
||||
<Compile Include="Controller\ControllerException.cs" />
|
||||
<Compile Include="Domain\AppInstallInfo.cs" />
|
||||
<Compile Include="Domain\AppSettings.cs" />
|
||||
<Compile Include="IOHelper.cs" />
|
||||
<Compile Include="Domain\Sound.cs" />
|
||||
<Compile Include="Recorder.cs" />
|
||||
<Compile Include="UI\DrumPlayUI.xaml.cs">
|
||||
<DependentUpon>DrumPlayUI.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\DrumEditUI.xaml.cs">
|
||||
<DependentUpon>DrumEditUI.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\EditorPage.xaml.cs">
|
||||
<DependentUpon>EditorPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Settings\LayoutsSettingsControl.xaml.cs">
|
||||
<DependentUpon>LayoutsSettingsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Utils\UIHelper.cs" />
|
||||
<Compile Include="UI\Settings\ExperimentsSettingsControl.xaml.cs">
|
||||
<DependentUpon>ExperimentsSettingsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\CommonControls\FileControl.xaml.cs">
|
||||
<DependentUpon>FileControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Settings\DrumsSettingsControl.xaml.cs">
|
||||
<DependentUpon>DrumsSettingsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Settings\DrumkitsSettingsControl.xaml.cs">
|
||||
<DependentUpon>DrumkitsSettingsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\Settings\GeneralSettingsControl.xaml.cs">
|
||||
<DependentUpon>GeneralSettingsControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Repository\LogRepository.cs" />
|
||||
<Compile Include="Repository\DataRepository.cs" />
|
||||
<Compile Include="Repository\SoundRepository.cs" />
|
||||
<Compile Include="UI\SettingsPage.xaml.cs">
|
||||
<DependentUpon>SettingsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Repository\RepositoryException.cs" />
|
||||
<Compile Include="Utils\IOHelper.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Managers\DataManager.cs" />
|
||||
<Compile Include="Domain\Drum.cs" />
|
||||
<Compile Include="Domain\DrumConfig.cs" />
|
||||
<Compile Include="Domain\Drumkit.cs" />
|
||||
@ -119,26 +157,26 @@
|
||||
<Compile Include="Domain\DrumkitLayoutCollection.cs" />
|
||||
<Compile Include="Domain\DrumkitLayoutTargetView.cs" />
|
||||
<Compile Include="Domain\DrumLayout.cs" />
|
||||
<Compile Include="Managers\DrumsManager.cs" />
|
||||
<Compile Include="Managers\UIManager.cs" />
|
||||
<Compile Include="UI\DrumUI.cs" />
|
||||
<Compile Include="Repository\DrumkitRepository.cs" />
|
||||
<Compile Include="UI\LoadingPage.xaml.cs">
|
||||
<DependentUpon>LoadingPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Recorder.cs" />
|
||||
<Compile Include="Managers\SoundManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SoundPool.cs" />
|
||||
<Compile Include="Domain\SoundSource.cs" />
|
||||
<Compile Include="UI\Settings\LogControl.xaml.cs">
|
||||
<DependentUpon>LogControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<Content Include="Assets\ApplicationData.tar" />
|
||||
<Content Include="Features.txt" />
|
||||
<None Include="Build\7z.exe" />
|
||||
<None Include="Build\ApplicationData\Drumkits\Default\config.xml" />
|
||||
<None Include="Build\ApplicationData\Drumkits\Default\drumkit.xml" />
|
||||
@ -185,6 +223,51 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Common\TextButtonStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
<Page Include="UI\DrumPlayUI.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\DrumEditUI.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\EditorPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\LayoutsSettingsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\ExperimentsSettingsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\CommonControls\FileControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\DrumsSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\DrumkitsSettingsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\GeneralSettingsControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\SettingsPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="UI\LoadingPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@ -193,6 +276,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="UI\Settings\LogControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="SharpDX, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a, processorArchitecture=MSIL">
|
||||
@ -204,7 +291,12 @@
|
||||
<HintPath>..\..\..\..\WebDownloads\SharpDX242\Bin\Signed-winrt\SharpDX.XAudio2.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tarball\Tarball.csproj">
|
||||
<Project>{5cb567d7-572e-4bae-802f-7e3f62cddf64}</Project>
|
||||
<Name>Tarball</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '11.0' ">
|
||||
<VisualStudioVersion>11.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
10
DrumKit/Features.txt
Normal file
10
DrumKit/Features.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Feature ideas:
|
||||
|
||||
* drum hit intensity
|
||||
* audio effects (echo & stuff)
|
||||
* additional drum sets
|
||||
* create/delete drums
|
||||
* create drum kits
|
||||
* z index in editor
|
||||
* recording
|
||||
* sequencer
|
@ -10,54 +10,42 @@ namespace DrumKit
|
||||
{
|
||||
static class Log
|
||||
{
|
||||
private static StreamWriter output = null;
|
||||
|
||||
public static async Task Initialize()
|
||||
{
|
||||
// Create "Logs" folder if not created
|
||||
var folder = await ApplicationData.Current.RoamingFolder.CreateFolderAsync("AppLogs", CreationCollisionOption.OpenIfExists);
|
||||
|
||||
// Create a log file
|
||||
var file = await folder.CreateFileAsync(DateTime.Now.Ticks.ToString() + ".csv", CreationCollisionOption.GenerateUniqueName);
|
||||
|
||||
// Open stream
|
||||
var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
|
||||
var iostream = stream.AsStream();
|
||||
output = new StreamWriter(iostream);
|
||||
output.AutoFlush = true;
|
||||
|
||||
// Write an initial message
|
||||
Write("Session started");
|
||||
// Initialize the log repository
|
||||
await Repository.LogRepository.Initialize(folder);
|
||||
}
|
||||
|
||||
public static void Write(string format, params object[] args)
|
||||
{
|
||||
if (output == null) return;
|
||||
// Prepare data
|
||||
string res = string.Format(format, args);
|
||||
string final = string.Format("{0} INFO: {1}", DateTime.Now, res);
|
||||
|
||||
// Write data
|
||||
output.WriteLine("{0},Information,{1}", DateTime.Now, res);
|
||||
// Write
|
||||
Repository.LogRepository.WriteLine(final);
|
||||
}
|
||||
|
||||
public static void Error(string format, params object[] args)
|
||||
{
|
||||
if (output == null) return;
|
||||
// Prepare data
|
||||
string res = string.Format(format, args);
|
||||
string final = string.Format("{0} ERROR: {1}", DateTime.Now, res);
|
||||
|
||||
// Write data
|
||||
output.WriteLine("{0},Error,{1}", DateTime.Now, res);
|
||||
// Write
|
||||
Repository.LogRepository.WriteLine(final);
|
||||
}
|
||||
|
||||
public static void Except(Exception ex)
|
||||
{
|
||||
if (output == null) return;
|
||||
// Prepare data
|
||||
string final = string.Format("{0} EXCEPTION: {1}", DateTime.Now, ex.ToString());
|
||||
|
||||
// Prepare
|
||||
string stack = ex.StackTrace.Replace("\n", ",,,,");
|
||||
|
||||
// Write data
|
||||
output.WriteLine("{0},Exception,{1},{2},{3}", DateTime.Now, ex.Message, ex.Source, stack);
|
||||
// Write
|
||||
Repository.LogRepository.WriteLine(final);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,179 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
static class DataManager
|
||||
{
|
||||
public static AppSettings Settings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this is the first time application was launched.
|
||||
/// </summary>
|
||||
public static async Task<bool> IsFirstLaunch()
|
||||
{
|
||||
// See if 'installed.xml' exists
|
||||
var folder = ApplicationData.Current.RoamingFolder;
|
||||
var files = await folder.GetFilesAsync();
|
||||
|
||||
return files.Count(x => x.Name == "installed.xml") == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the content of the source folder into the destination folder recursively.
|
||||
/// </summary>
|
||||
//private static async Task CopyFolder(StorageFolder source, StorageFolder dest)
|
||||
//{
|
||||
// // Copy folders recursively
|
||||
// var folders = await source.GetFoldersAsync();
|
||||
|
||||
// foreach (var i in folders)
|
||||
// {
|
||||
// var newfolder = await dest.CreateFolderAsync(i.Name, CreationCollisionOption.OpenIfExists);
|
||||
// await CopyFolder(i, newfolder);
|
||||
// }
|
||||
|
||||
// // Copy files
|
||||
// var files = await source.GetFilesAsync();
|
||||
|
||||
// foreach (var i in files)
|
||||
// await i.CopyAsync(dest);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Installs the assets at first launch.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task InstallAssets()
|
||||
{
|
||||
// Read content of 'ApplicationData'
|
||||
var reader = new DrumKit.Archiving.TarballReader();
|
||||
await reader.Unpack(new Uri("ms-appx:///Assets/ApplicationData.tar"), ApplicationData.Current.RoamingFolder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the 'installed.xml' file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static async Task MarkInstalled()
|
||||
{
|
||||
// Open stream
|
||||
StorageFile file = await ApplicationData.Current.RoamingFolder.CreateFileAsync("installed.xml");
|
||||
var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
|
||||
var iostream = stream.AsStream();
|
||||
|
||||
// Generate xml
|
||||
var writer = System.Xml.XmlWriter.Create(iostream, new System.Xml.XmlWriterSettings() { Async = true, CloseOutput = true });
|
||||
|
||||
writer.WriteStartDocument();
|
||||
writer.WriteStartElement("drumkit");
|
||||
writer.WriteString(DateTime.UtcNow.ToString());
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndDocument();
|
||||
|
||||
// Cleanup
|
||||
await writer.FlushAsync();
|
||||
writer.Dispose();
|
||||
iostream.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets everything to factory settings.
|
||||
/// The application must be reinitialized after (or closed).
|
||||
/// </summary>
|
||||
public static async Task FactoryReset()
|
||||
{
|
||||
await ApplicationData.Current.ClearAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings file.
|
||||
/// </summary>
|
||||
public static async Task LoadSettings()
|
||||
{
|
||||
// If all else fails, default settings
|
||||
Settings = new AppSettings();
|
||||
|
||||
// Get settings file
|
||||
var files = await ApplicationData.Current.RoamingFolder.GetFilesAsync();
|
||||
var sf = files.FirstOrDefault(x => x.Name == "settings.xml");
|
||||
|
||||
// File found
|
||||
if (sf != null)
|
||||
{
|
||||
// Open file
|
||||
var fstream = await sf.OpenReadAsync();
|
||||
var fstream_net = fstream.AsStream();
|
||||
|
||||
// Deserialize
|
||||
XmlSerializer s = new XmlSerializer(Settings.GetType());
|
||||
var settings = s.Deserialize(fstream_net) as AppSettings;
|
||||
|
||||
// All good
|
||||
if (settings != null)
|
||||
Settings = settings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings file.
|
||||
/// </summary>
|
||||
public static async Task SaveSettings()
|
||||
{
|
||||
// Get settings file
|
||||
var file = await ApplicationData.Current.RoamingFolder.CreateFileAsync("settings.xml", CreationCollisionOption.ReplaceExisting);
|
||||
|
||||
// Open file
|
||||
var fstream = await file.OpenAsync(FileAccessMode.ReadWrite);
|
||||
var fstream_net = fstream.AsStream();
|
||||
|
||||
// Serialize
|
||||
XmlSerializer s = new XmlSerializer(Settings.GetType());
|
||||
s.Serialize(fstream_net, Settings);
|
||||
|
||||
// Cleanup
|
||||
await fstream_net.FlushAsync();
|
||||
fstream_net.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the application (prepares the application at first launch, loads settings and drums).
|
||||
/// </summary>
|
||||
public static async Task Initialize()
|
||||
{
|
||||
// Is this the first time the user launches the application?
|
||||
if (await IsFirstLaunch())
|
||||
{
|
||||
// Clean up any junk
|
||||
await FactoryReset();
|
||||
|
||||
// Copy local assets to app data
|
||||
await InstallAssets();
|
||||
|
||||
// Generate 'installed.xml' file
|
||||
await MarkInstalled();
|
||||
}
|
||||
|
||||
// Load settings
|
||||
await LoadSettings();
|
||||
|
||||
// Load drum packages
|
||||
}
|
||||
|
||||
public static async Task Close()
|
||||
{
|
||||
// Save settings
|
||||
await SaveSettings();
|
||||
|
||||
// Save modified layout & stuff
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
static class DrumsManager
|
||||
{
|
||||
private static StorageFolder currentDrumkitKey = null;
|
||||
private static int currentDrumkitLayoutIndex = -1;
|
||||
|
||||
public static Dictionary<StorageFolder, Drumkit> AvailableDrumkits { get; private set; }
|
||||
public static DrumkitLayoutCollection CurrentDrumkitLayouts { get; private set; }
|
||||
public static DrumkitConfig CurrentDrumkitConfig { get; private set; }
|
||||
|
||||
public static Drumkit CurrentDrumkit
|
||||
{
|
||||
get {
|
||||
return (currentDrumkitKey == null) ? null : AvailableDrumkits[currentDrumkitKey];
|
||||
}
|
||||
}
|
||||
|
||||
public static StorageFolder CurrentDrumkitLocation
|
||||
{
|
||||
get {
|
||||
return currentDrumkitKey;
|
||||
}
|
||||
}
|
||||
|
||||
public static DrumkitLayout CurrentDrumkitLayout
|
||||
{
|
||||
get {
|
||||
return (currentDrumkitLayoutIndex == -1) ? null : CurrentDrumkitLayouts.Items[currentDrumkitLayoutIndex];
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<object> DeserializeFile(StorageFile file, Type type)
|
||||
{
|
||||
// Open manifest file
|
||||
var stream = await file.OpenReadAsync();
|
||||
var iostream = stream.AsStream();
|
||||
|
||||
// Deserialize
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
return serializer.Deserialize(iostream);
|
||||
}
|
||||
|
||||
private static async Task<Drumkit> LoadDrumkit(StorageFolder f)
|
||||
{
|
||||
// Open manifest file
|
||||
var manifest = await f.GetFileAsync("drumkit.xml");
|
||||
object dk = await DeserializeFile(manifest, typeof(Drumkit));
|
||||
return dk as Drumkit;
|
||||
}
|
||||
|
||||
private static async Task FindDrumkits()
|
||||
{
|
||||
// Reset list
|
||||
AvailableDrumkits = new Dictionary<StorageFolder, Drumkit>();
|
||||
|
||||
// Get 'drumkits' folder content
|
||||
var folder = await ApplicationData.Current.RoamingFolder.GetFolderAsync("Drumkits");
|
||||
var kits = await folder.GetFoldersAsync();
|
||||
|
||||
// Load each drumkit
|
||||
foreach (var i in kits)
|
||||
{
|
||||
Drumkit kit = await LoadDrumkit(i);
|
||||
if (kit != null)
|
||||
AvailableDrumkits.Add(i, kit);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task LoadCurrentDrumkit(string name)
|
||||
{
|
||||
// Get it from the list
|
||||
var current = AvailableDrumkits.FirstOrDefault(x => x.Value.Name == name);
|
||||
|
||||
// Doesn't exist? The default should at least exist.
|
||||
if (current.Equals(default(KeyValuePair<StorageFolder, Drumkit>)))
|
||||
current = AvailableDrumkits.FirstOrDefault(x => x.Value.Name == "Default");
|
||||
|
||||
// Not even default? Get any kit
|
||||
if (current.Equals(default(KeyValuePair<StorageFolder, Drumkit>)))
|
||||
current = AvailableDrumkits.FirstOrDefault();
|
||||
|
||||
// No drumkit? This is a serious problem
|
||||
if (current.Equals(default(KeyValuePair<StorageFolder, Drumkit>)))
|
||||
throw new Exception("No drumkits available.");
|
||||
|
||||
currentDrumkitKey = current.Key;
|
||||
|
||||
// Load layout and configuration
|
||||
StorageFile layout = await current.Key.GetFileAsync(current.Value.LayoutFilePath);
|
||||
CurrentDrumkitLayouts = await DeserializeFile(layout, typeof(DrumkitLayoutCollection)) as DrumkitLayoutCollection;
|
||||
|
||||
StorageFile config = await current.Key.GetFileAsync(current.Value.ConfigFilePath);
|
||||
CurrentDrumkitConfig = await DeserializeFile(config, typeof(DrumkitConfig)) as DrumkitConfig;
|
||||
}
|
||||
|
||||
public static async Task Initialize(AppSettings settings)
|
||||
{
|
||||
// Load drumkits
|
||||
await FindDrumkits();
|
||||
|
||||
// Load current drumkit
|
||||
await LoadCurrentDrumkit(settings.CurrentKit);
|
||||
}
|
||||
|
||||
public static void SetLayout()
|
||||
{
|
||||
currentDrumkitLayoutIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpDX;
|
||||
using SharpDX.XAudio2;
|
||||
using SharpDX.Multimedia;
|
||||
using System.IO;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
static class SoundManager
|
||||
{
|
||||
#region Data types
|
||||
private class MyWave
|
||||
{
|
||||
public AudioBuffer Buffer { get; set; }
|
||||
public uint[] DecodedPacketsInfo { get; set; }
|
||||
public WaveFormat WaveFormat { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private attributes
|
||||
private static XAudio2 xaudio = null;
|
||||
private static MasteringVoice mvoice = null;
|
||||
private static Dictionary<string, MyWave> sounds = null;
|
||||
private static SoundPool soundPool = null;
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Initializes the sound manager
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
xaudio = new XAudio2();
|
||||
xaudio.StartEngine();
|
||||
|
||||
mvoice = new MasteringVoice(xaudio);
|
||||
sounds = new Dictionary<string, MyWave>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Unload
|
||||
/// <summary>
|
||||
/// Unloads all the sounds
|
||||
/// </summary>
|
||||
public static void UnloadAll()
|
||||
{
|
||||
if (sounds == null)
|
||||
return;
|
||||
|
||||
sounds.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads the sounds related to a drum.
|
||||
/// </summary>
|
||||
/// <param name="drum">The drum which will be unloaded.</param>
|
||||
public static void UnloadDrum(Drum drum)
|
||||
{
|
||||
foreach (var i in drum.Sounds)
|
||||
sounds.Remove(drum.Id + i.Intensity.ToString());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Load
|
||||
/// <summary>
|
||||
/// Adds a sound to the dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">A key associated with the sound</param>
|
||||
/// <param name="file">The file which will be loaded</param>
|
||||
private static async Task AddSound(string key, StorageFile file)
|
||||
{
|
||||
MyWave wave = new MyWave();
|
||||
|
||||
// Load file
|
||||
var stream = await file.OpenReadAsync();
|
||||
var iostream = stream.AsStream();
|
||||
var soundStream = new SoundStream(iostream);
|
||||
var buffer = new AudioBuffer() {
|
||||
Stream = soundStream,
|
||||
AudioBytes = (int)soundStream.Length,
|
||||
Flags = BufferFlags.EndOfStream
|
||||
};
|
||||
iostream.Dispose();
|
||||
|
||||
// Set up information
|
||||
wave.Buffer = buffer;
|
||||
wave.DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
|
||||
wave.WaveFormat = soundStream.Format;
|
||||
|
||||
// Now we can initialize the soundpool
|
||||
if (soundPool == null)
|
||||
soundPool = new SoundPool(xaudio, wave.WaveFormat);
|
||||
|
||||
// Add to sound list
|
||||
sounds.Add(key, wave);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the sounds associated with a drum
|
||||
/// </summary>
|
||||
public static async Task LoadDrum(Drum drum, StorageFolder root)
|
||||
{
|
||||
// Load each sound
|
||||
foreach (var i in drum.Sounds)
|
||||
{
|
||||
var file = await IOHelper.GetFileRelativeAsync(root, i.Source);
|
||||
await AddSound(drum.Id + i.Intensity.ToString(), file);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads every drum in a drumkit.
|
||||
/// </summary>
|
||||
public static async Task LoadDrumkit(Drumkit kit, StorageFolder root)
|
||||
{
|
||||
// Load each sound
|
||||
foreach (var i in kit.Drums)
|
||||
await LoadDrum(i, root);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Play
|
||||
/// <summary>
|
||||
/// Plays a sound
|
||||
/// </summary>
|
||||
/// <param name="drum_id">The id of the drum</param>
|
||||
/// <param name="intensity">The intensity</param>
|
||||
public static void Play(string drum_id, int intensity)
|
||||
{
|
||||
// Get wave info
|
||||
MyWave info = null;
|
||||
|
||||
if (!sounds.TryGetValue(drum_id + intensity.ToString(), out info))
|
||||
return;
|
||||
|
||||
// Play
|
||||
soundPool.PlayBuffer(info.Buffer, info.DecodedPacketsInfo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
static class UIManager
|
||||
{
|
||||
private static Dictionary<string, DrumUI> drums;
|
||||
private static Dictionary<VirtualKey, string> keymap;
|
||||
|
||||
public static Canvas TheCanvas { get; private set; }
|
||||
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Initializes the ui manager
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
drums = new Dictionary<string, DrumUI>();
|
||||
keymap = new Dictionary<VirtualKey, string>();
|
||||
|
||||
TheCanvas = new Canvas();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the ui stuff for drumkit
|
||||
/// </summary>
|
||||
public static async Task ReloadDrumkit()
|
||||
{
|
||||
// Delete previous
|
||||
drums.Clear();
|
||||
keymap.Clear();
|
||||
|
||||
// Load drums
|
||||
foreach (var i in DrumsManager.CurrentDrumkit.Drums)
|
||||
{
|
||||
DrumUI drumui = new DrumUI();
|
||||
await drumui.InitializeDrum(i, DrumsManager.CurrentDrumkitLocation);
|
||||
drumui.PointerPressed += HandlerDrumPointerPressed;
|
||||
drumui.DragDelta += HandlerDrumMoved;
|
||||
|
||||
TheCanvas.Children.Add(drumui.Element);
|
||||
drums.Add(i.Id, drumui);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the layout.
|
||||
/// </summary>
|
||||
public static void ReloadLayout()
|
||||
{
|
||||
DrumUI drum;
|
||||
|
||||
foreach (var i in DrumsManager.CurrentDrumkitLayout.Drums)
|
||||
if (drums.TryGetValue(i.TargetId, out drum))
|
||||
drum.UpdateLayout(i, TheCanvas.ActualWidth, TheCanvas.ActualHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the configuration.
|
||||
/// </summary>
|
||||
public static async Task ReloadConfig()
|
||||
{
|
||||
foreach (var i in DrumsManager.CurrentDrumkitConfig.Drums)
|
||||
{
|
||||
// Enabled and not loaded
|
||||
if (i.IsEnabled && !drums.ContainsKey(i.TargetId))
|
||||
{
|
||||
Drum drum = DrumsManager.CurrentDrumkit.Drums.FirstOrDefault(x => x.Id == i.TargetId);
|
||||
if (drum != null)
|
||||
{
|
||||
DrumUI drumui = new DrumUI();
|
||||
await drumui.InitializeDrum(drum, DrumsManager.CurrentDrumkitLocation);
|
||||
drumui.PointerPressed += HandlerDrumPointerPressed;
|
||||
drumui.DragDelta += HandlerDrumMoved;
|
||||
|
||||
drums.Add(i.TargetId, drumui);
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled and loaded
|
||||
else if (!i.IsEnabled && drums.ContainsKey(i.TargetId))
|
||||
{
|
||||
TheCanvas.Children.Remove(drums[i.TargetId].Element);
|
||||
drums.Remove(i.TargetId);
|
||||
}
|
||||
|
||||
// Keyboard mapping
|
||||
if (!keymap.ContainsKey(i.Key))
|
||||
keymap.Add(i.Key, i.TargetId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
/// <summary>
|
||||
/// Handles drum hit using mouse/touchpad
|
||||
/// </summary>
|
||||
private static void HandlerDrumPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
|
||||
{
|
||||
var button = sender as FrameworkElement;
|
||||
var tag = button.Tag as string;
|
||||
|
||||
if (tag != null)
|
||||
HandlerDrumClickedCommon(tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drum hit using keyboard
|
||||
/// </summary>
|
||||
public static void HandlerKeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
|
||||
{
|
||||
string drum;
|
||||
|
||||
// Key repeat or something
|
||||
if (args.KeyStatus.WasKeyDown)
|
||||
return;
|
||||
|
||||
// If key in key map, perform "click"
|
||||
if (keymap.TryGetValue(args.VirtualKey, out drum))
|
||||
HandlerDrumClickedCommon(drum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drum hit.
|
||||
/// </summary>
|
||||
private static void HandlerDrumClickedCommon(string drum_id)
|
||||
{
|
||||
SoundManager.Play(drum_id, 0);
|
||||
|
||||
if (DataManager.Settings.Animations)
|
||||
drums[drum_id].Hit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drum movement.
|
||||
/// </summary>
|
||||
private static void HandlerDrumMoved(object sender, Windows.UI.Xaml.Controls.Primitives.DragDeltaEventArgs e)
|
||||
{
|
||||
var thumb = sender as Thumb;
|
||||
var tag = thumb.Tag as string;
|
||||
int drum_index = -1;
|
||||
|
||||
if (tag != null)
|
||||
drum_index = DrumsManager.CurrentDrumkitLayout.Drums.FindIndex(x => x.TargetId == tag);
|
||||
|
||||
if (drum_index >= 0)
|
||||
{
|
||||
double delta_x = e.HorizontalChange / TheCanvas.ActualWidth;
|
||||
double delta_y = e.VerticalChange / TheCanvas.ActualHeight;
|
||||
|
||||
if (double.IsInfinity(delta_x) || double.IsInfinity(delta_y) || double.IsNaN(delta_x) || double.IsNaN(delta_y))
|
||||
return;
|
||||
|
||||
DrumsManager.CurrentDrumkitLayout.Drums[drum_index].X += delta_x;
|
||||
DrumsManager.CurrentDrumkitLayout.Drums[drum_index].Y += delta_y;
|
||||
|
||||
drums[tag].UpdateLayout(DrumsManager.CurrentDrumkitLayout.Drums[drum_index], TheCanvas.ActualWidth, TheCanvas.ActualHeight);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static void EnterEdit()
|
||||
{
|
||||
foreach (var i in drums)
|
||||
i.Value.EnableEdit();
|
||||
}
|
||||
|
||||
public static void ExitEdit()
|
||||
{
|
||||
foreach (var i in drums)
|
||||
i.Value.DisableEdit();
|
||||
}
|
||||
}
|
||||
}
|
@ -240,7 +240,6 @@
|
||||
<Language Code="pt-br" InMinimumRequirementSet="true" />
|
||||
<Language Code="pt-pt" InMinimumRequirementSet="true" />
|
||||
<Language Code="quc-latn" InMinimumRequirementSet="false" />
|
||||
<Language Code="qut" InMinimumRequirementSet="false" />
|
||||
<Language Code="qut-gt" InMinimumRequirementSet="false" />
|
||||
<Language Code="qut-latn" InMinimumRequirementSet="false" />
|
||||
<Language Code="quz" InMinimumRequirementSet="false" />
|
||||
@ -292,9 +291,10 @@
|
||||
<Language Code="ti" InMinimumRequirementSet="false" />
|
||||
<Language Code="ti-et" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-cyrl" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-cyrl-tr" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-latn" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-latn-tr" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-tm" InMinimumRequirementSet="false" />
|
||||
<Language Code="tk-tr" InMinimumRequirementSet="false" />
|
||||
<Language Code="tn" InMinimumRequirementSet="false" />
|
||||
<Language Code="tn-bw" InMinimumRequirementSet="false" />
|
||||
<Language Code="tn-za" InMinimumRequirementSet="false" />
|
||||
@ -342,11 +342,13 @@
|
||||
<ReservedName>DrumKit</ReservedName>
|
||||
</ReservedNames>
|
||||
</ProductReservedInfo>
|
||||
<AccountPackageIdentityNames />
|
||||
<AccountPackageIdentityNames>
|
||||
<MainPackageIdentityName>35555TiberiuChibici.Harmonia</MainPackageIdentityName>
|
||||
</AccountPackageIdentityNames>
|
||||
<PackageInfoList LandingUrl="https://appdev.microsoft.com:443/StorePortals/Developer/Catalog/ReleaseAnchor/a07735fd-3955-4470-aa48-5356c8ae5c91">
|
||||
<PackageInfo>
|
||||
<PackageArchitecture>neutral</PackageArchitecture>
|
||||
<PackageMaxArchitectureVersion>1.0.0.6</PackageMaxArchitectureVersion>
|
||||
<PackageMaxArchitectureVersion>2.1.0.26</PackageMaxArchitectureVersion>
|
||||
</PackageInfo>
|
||||
</PackageInfoList>
|
||||
</StoreAssociation>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
|
||||
<Identity Name="35555TiberiuChibici.DrumKit" Publisher="CN=B6F45FE5-D749-4D29-874C-8323B266F3C8" Version="1.1.0.14" />
|
||||
<Identity Name="35555TiberiuChibici.DrumKit" Publisher="CN=B6F45FE5-D749-4D29-874C-8323B266F3C8" Version="2.2.0.27" />
|
||||
<Properties>
|
||||
<DisplayName>DrumKit</DisplayName>
|
||||
<PublisherDisplayName>Tiberiu Chibici</PublisherDisplayName>
|
||||
@ -19,7 +19,9 @@
|
||||
<DefaultTile ShowName="allLogos" WideLogo="Assets\Logos\WideLogo.png" />
|
||||
<SplashScreen Image="Assets\Logos\SplashScreen.png" />
|
||||
<InitialRotationPreference>
|
||||
<Rotation Preference="portrait" />
|
||||
<Rotation Preference="landscape" />
|
||||
<Rotation Preference="portraitFlipped" />
|
||||
<Rotation Preference="landscapeFlipped" />
|
||||
</InitialRotationPreference>
|
||||
</VisualElements>
|
||||
|
@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyTitle("DrumKit")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyCompany("Chibici Tiberiu")]
|
||||
[assembly: AssemblyProduct("DrumKit")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyCopyright("Copyright © Chibici Tiberiu 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("2.2.*")]
|
||||
//[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
183
DrumKit/Repository/DataRepository.cs
Normal file
183
DrumKit/Repository/DataRepository.cs
Normal file
@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit.Repository
|
||||
{
|
||||
class DataRepository
|
||||
{
|
||||
#region Properties
|
||||
public AppSettings Settings { get; private set; }
|
||||
public AppInstallInfo InstallInfo { get; private set; }
|
||||
public ApplicationData RepositoryLocation { get; private set; }
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Creates a new instance of drumkit.
|
||||
/// </summary>
|
||||
public DataRepository()
|
||||
{
|
||||
this.InstallInfo = null;
|
||||
this.Settings = null;
|
||||
this.RepositoryLocation = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialize
|
||||
/// <summary>
|
||||
/// And initializes the data using that information, and sets the location.
|
||||
/// Note that you cannot call this method multiple times on the same instance.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException if location was already set" />
|
||||
public async Task Initialize(ApplicationData where)
|
||||
{
|
||||
// Set up location
|
||||
if (this.RepositoryLocation != null)
|
||||
throw new InvalidOperationException("You cannot change data repository location once set.");
|
||||
|
||||
this.RepositoryLocation = where;
|
||||
Log.Write("[DataRepository] Location set: {0}", where.RoamingFolder.Path);
|
||||
|
||||
// Read installation information
|
||||
this.InstallInfo = await this.ReadInstallInfo();
|
||||
|
||||
// Version changed, or no info (new install)?
|
||||
if (this.IsFirstLaunch())
|
||||
{
|
||||
// Clean up any junk
|
||||
await this.FactoryReset();
|
||||
|
||||
// Copy local assets to app data
|
||||
await this.InstallAssets();
|
||||
|
||||
// Generate "installed.xml" file
|
||||
await this.WriteInstallInfo();
|
||||
}
|
||||
|
||||
// Load settings
|
||||
this.Settings = await this.ReadSettings();
|
||||
|
||||
// No settings? Use default.
|
||||
if (this.Settings == null)
|
||||
this.Settings = new AppSettings();
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads the install info.
|
||||
/// </summary>
|
||||
/// <returns>An AppInstallInfo structure, or null if file does not exist.</returns>
|
||||
private async Task<AppInstallInfo> ReadInstallInfo()
|
||||
{
|
||||
// See if 'installed.xml' exists
|
||||
var files = await this.RepositoryLocation.RoamingFolder.GetFilesAsync();
|
||||
StorageFile file = files.FirstOrDefault(x => x.Name == "installed.xml");
|
||||
|
||||
if (file == null)
|
||||
return null;
|
||||
|
||||
// Read info
|
||||
object info = await IOHelper.DeserializeFile(file, typeof(AppInstallInfo));
|
||||
return info as AppInstallInfo;
|
||||
}
|
||||
|
||||
private async Task<AppSettings> ReadSettings()
|
||||
{
|
||||
// See if 'settings.xml' exists
|
||||
var files = await this.RepositoryLocation.RoamingFolder.GetFilesAsync();
|
||||
StorageFile file = files.FirstOrDefault(x => x.Name == "settings.xml");
|
||||
|
||||
if (file == null)
|
||||
return null;
|
||||
|
||||
// Read info
|
||||
object settings = await IOHelper.DeserializeFile(file, typeof(AppSettings));
|
||||
return settings as AppSettings;
|
||||
}
|
||||
|
||||
private bool IsFirstLaunch()
|
||||
{
|
||||
// Get current assembly information
|
||||
Assembly current_asm = typeof(DataRepository).GetTypeInfo().Assembly;
|
||||
int version = current_asm.GetName().Version.Major * 1000 + current_asm.GetName().Version.Minor;
|
||||
|
||||
// If no install info, this is probably first launch
|
||||
if (this.InstallInfo == null)
|
||||
{
|
||||
Log.Write("[DataRepository] First launch!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Smaller version, upgrade necessary
|
||||
if (this.InstallInfo.Version != version)
|
||||
{
|
||||
Log.Write("[DataRepository] Version upgrade ({0} => {1}).", this.InstallInfo.Version, version);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Nothing new
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Installs the assets at first launch.
|
||||
/// </summary>
|
||||
private async Task InstallAssets()
|
||||
{
|
||||
// Read content of 'ApplicationData'
|
||||
var reader = new Tarball.TarballReader();
|
||||
await reader.Unpack(new Uri("ms-appx:///Assets/ApplicationData.tar"), this.RepositoryLocation.RoamingFolder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the 'installed.xml' file.
|
||||
/// </summary>
|
||||
private async Task WriteInstallInfo()
|
||||
{
|
||||
// Create file
|
||||
StorageFile file = await this.RepositoryLocation.RoamingFolder.CreateFileAsync("installed.xml");
|
||||
|
||||
// Create app info
|
||||
AppInstallInfo info = new AppInstallInfo();
|
||||
|
||||
// Serialize info
|
||||
await IOHelper.SerializeFile(file, info, typeof(AppInstallInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets to factory settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task FactoryReset()
|
||||
{
|
||||
await this.RepositoryLocation.ClearAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the current settings.
|
||||
/// </summary>
|
||||
public async Task WriteSettings()
|
||||
{
|
||||
// Get settings file
|
||||
var file = await ApplicationData.Current.RoamingFolder.CreateFileAsync("settings.xml", CreationCollisionOption.ReplaceExisting);
|
||||
|
||||
// Serialize settings
|
||||
await IOHelper.SerializeFile(file, this.Settings, typeof(AppSettings));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the current resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
322
DrumKit/Repository/DrumkitRepository.cs
Normal file
322
DrumKit/Repository/DrumkitRepository.cs
Normal file
@ -0,0 +1,322 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit.Repository
|
||||
{
|
||||
public class DrumkitRepository
|
||||
{
|
||||
#region Properties
|
||||
public Dictionary<string, Drumkit> AvailableDrumKits { get; private set; }
|
||||
public StorageFolder RepositoryLocation { get; private set; }
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Creates a new instance of drumkit.
|
||||
/// </summary>
|
||||
public DrumkitRepository()
|
||||
{
|
||||
this.AvailableDrumKits = new Dictionary<string, Drumkit>();
|
||||
this.RepositoryLocation = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region (private) AddDrumkit
|
||||
/// <summary>
|
||||
/// Adds a drumkit to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="kit">Drumkit to add</param>
|
||||
/// <returns>True if item added successfully, false otherwise.</returns>
|
||||
private bool AddDrumkit(Drumkit kit)
|
||||
{
|
||||
// If drumkit is null
|
||||
if (kit == null)
|
||||
return false;
|
||||
|
||||
// If name is unique
|
||||
if (this.AvailableDrumKits.ContainsKey(kit.Name))
|
||||
{
|
||||
Log.Error("[DrumkitRepository] Did not add kit, name not unique: name = {0}, location = {1} ", kit.Name, kit.RootFolder.Path);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to list
|
||||
this.AvailableDrumKits.Add(kit.Name, kit);
|
||||
Log.Write("[DrumkitRepository] Added kit: name = {0}, location = {1}", kit.Name, kit.RootFolder.Path);
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region (private) ReadDrumkit
|
||||
/// <summary>
|
||||
/// Reads information about a drumkit.
|
||||
/// </summary>
|
||||
/// <param name="where">Where drumkit located</param>
|
||||
/// <returns>Drumkit object, null if not a valid drumkit.</returns>
|
||||
private async Task<Drumkit> ReadDrumkit(StorageFolder where)
|
||||
{
|
||||
// Get manifest file
|
||||
var files = await where.GetFilesAsync();
|
||||
var manifest = files.FirstOrDefault(x => x.Name == "drumkit.xml");
|
||||
|
||||
// No manifest? Not drumkit
|
||||
if (manifest == null)
|
||||
return null;
|
||||
|
||||
// Read drumkit object
|
||||
object kitobj = await IOHelper.DeserializeFile(manifest, typeof(Drumkit));
|
||||
var kit = kitobj as Drumkit;
|
||||
|
||||
// Set root folder if possible
|
||||
if (kit != null)
|
||||
kit.RootFolder = where;
|
||||
|
||||
// Return
|
||||
return kit;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadLayouts
|
||||
/// <summary>
|
||||
/// Reads the layouts of the specified drumkit.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_name">Name of drumkit</param>
|
||||
public async Task<DrumkitLayoutCollection> ReadLayouts(string drumkit_name)
|
||||
{
|
||||
Drumkit kit = null;
|
||||
|
||||
// Get the drumkit
|
||||
if (!this.AvailableDrumKits.TryGetValue(drumkit_name, out kit))
|
||||
return null;
|
||||
|
||||
// Get layouts file
|
||||
StorageFile file = await IOHelper.GetFileRelativeAsync(kit.RootFolder, kit.LayoutFilePath);
|
||||
|
||||
// Read layouts
|
||||
object layouts = await IOHelper.DeserializeFile(file, typeof(DrumkitLayoutCollection));
|
||||
return layouts as DrumkitLayoutCollection;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteLayouts
|
||||
/// <summary>
|
||||
/// Rewrites the layouts for the specified drumkit.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_name">Name of drumkit.</param>
|
||||
/// <param name="layouts">Layout collection to be saved.</param>
|
||||
public async Task WriteLayouts(string drumkit_name, DrumkitLayoutCollection layouts)
|
||||
{
|
||||
Drumkit kit = null;
|
||||
|
||||
// Sanity check
|
||||
if (layouts == null)
|
||||
throw new RepositoryException("Cannot write null layout collection!");
|
||||
|
||||
// Get the drumkit
|
||||
if (!this.AvailableDrumKits.TryGetValue(drumkit_name, out kit))
|
||||
throw new RepositoryException("No such drumkit.");
|
||||
|
||||
// Delete old layouts file
|
||||
StorageFile old = await IOHelper.GetFileRelativeAsync(kit.RootFolder, kit.LayoutFilePath);
|
||||
await old.DeleteAsync();
|
||||
|
||||
// Create new file
|
||||
StorageFile file = await IOHelper.CreateFileRelativeAsync(kit.RootFolder, kit.LayoutFilePath);
|
||||
|
||||
// Write
|
||||
await IOHelper.SerializeFile(file, layouts, typeof(DrumkitLayoutCollection));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadConfig
|
||||
/// <summary>
|
||||
/// Reads the configuration file for the specified drumkit.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_name">Name of drumkit</param>
|
||||
public async Task<DrumkitConfig> ReadConfig(string drumkit_name)
|
||||
{
|
||||
Drumkit kit = null;
|
||||
|
||||
// Get the drumkit
|
||||
if (!this.AvailableDrumKits.TryGetValue(drumkit_name, out kit))
|
||||
return null;
|
||||
|
||||
// Get layouts file
|
||||
StorageFile file = await IOHelper.GetFileRelativeAsync(kit.RootFolder, kit.ConfigFilePath);
|
||||
|
||||
// Read layouts
|
||||
object config = await IOHelper.DeserializeFile(file, typeof(DrumkitConfig));
|
||||
return config as DrumkitConfig;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteConfig
|
||||
/// <summary>
|
||||
/// Rewrites the configuration file for the specified drumkit.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_name">Name of drumkit</param>
|
||||
/// <param name="config">Configuration</param>
|
||||
public async Task WriteConfig(string drumkit_name, DrumkitConfig config)
|
||||
{
|
||||
Drumkit kit = null;
|
||||
|
||||
// Sanity check
|
||||
if (config == null)
|
||||
throw new RepositoryException("Cannot write null configs!");
|
||||
|
||||
// Get the drumkit
|
||||
if (!this.AvailableDrumKits.TryGetValue(drumkit_name, out kit))
|
||||
throw new RepositoryException("No such drumkit.");
|
||||
|
||||
// Delete old layouts file
|
||||
StorageFile old = await IOHelper.GetFileRelativeAsync(kit.RootFolder, kit.ConfigFilePath);
|
||||
await old.DeleteAsync();
|
||||
|
||||
// Create new file
|
||||
StorageFile file = await IOHelper.CreateFileRelativeAsync(kit.RootFolder, kit.ConfigFilePath);
|
||||
|
||||
// Write
|
||||
await IOHelper.SerializeFile(file, config, typeof(DrumkitConfig));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Initialize
|
||||
/// <summary>
|
||||
/// Initializes the repository set to one location.
|
||||
/// Note that you cannot call this method multiple times for the same instance.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException if location was already set" />
|
||||
public async Task Initialize(StorageFolder where)
|
||||
{
|
||||
// Set up location
|
||||
if (this.RepositoryLocation != null)
|
||||
throw new InvalidOperationException("You cannot change drumkit repository location once set.");
|
||||
|
||||
this.RepositoryLocation = where;
|
||||
Log.Write("[DrumkitRepository] Location set: {0}", where.Path);
|
||||
|
||||
// Get possible drumkits
|
||||
var folders = await where.GetFoldersAsync();
|
||||
|
||||
// Load each drumkit
|
||||
foreach (var i in folders)
|
||||
{
|
||||
Drumkit kit = await this.ReadDrumkit(i);
|
||||
|
||||
// If it is a drumkit
|
||||
if (kit != null)
|
||||
this.AddDrumkit(kit);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InstallTarball
|
||||
/// <summary>
|
||||
/// Adds a new drumkit to the repository.
|
||||
/// The drumkit should be an uncompressed tarball file, which will be
|
||||
/// unpacked to the repository's location.
|
||||
/// </summary>
|
||||
/// <param name="tarball">The tarball file.</param>
|
||||
/// <exception cref="ArgumentException if file is not a valid drumkit." />
|
||||
/// <exception cref="RepositoryException if name of drumkit is not unique." />
|
||||
public async Task InstallTarball (StorageFile tarball)
|
||||
{
|
||||
Log.Write("[DrumkitRepository] Installing tarball: {0}", tarball.Path);
|
||||
|
||||
// Create destination folder
|
||||
string dest_name = System.IO.Path.GetFileNameWithoutExtension(tarball.Name);
|
||||
var dest = await this.RepositoryLocation.CreateFolderAsync(dest_name, CreationCollisionOption.GenerateUniqueName);
|
||||
|
||||
// Unpack tarball
|
||||
var reader = new Tarball.TarballReader();
|
||||
await reader.Unpack(tarball, dest);
|
||||
|
||||
// Read information
|
||||
Drumkit kit = await this.ReadDrumkit(dest);
|
||||
|
||||
// If there was a problem
|
||||
if (kit == null || !this.AddDrumkit(kit))
|
||||
{
|
||||
Log.Error("[DrumkitRepository] Failed to install tarball: {0}", tarball.Path);
|
||||
|
||||
// Cleanup
|
||||
await dest.DeleteAsync(StorageDeleteOption.PermanentDelete);
|
||||
|
||||
// Throw exception
|
||||
if (kit == null)
|
||||
throw new ArgumentException("Tarball not a drumkit.");
|
||||
|
||||
else
|
||||
throw new RepositoryException("Drumkit name not unique.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ExportTarball
|
||||
/// <summary>
|
||||
/// Exports a drumkit to a tarball file.
|
||||
/// </summary>
|
||||
/// <param name="drumkit_key">The key of the drumkit to export.</param>
|
||||
/// <param name="tarball">The destination tarball file.</param>
|
||||
/// <exception cref="ArgumentException">Raised if key is not valid.</exception>
|
||||
/// <exception cref="ArgumentNullException">Raised if destination tarball is null.</exception>
|
||||
public async Task ExportTarball(string drumkit_key, StorageFile tarball)
|
||||
{
|
||||
// Sanity checks
|
||||
if (!AvailableDrumKits.ContainsKey(drumkit_key))
|
||||
throw new ArgumentException("Invalid key!");
|
||||
|
||||
if (tarball == null)
|
||||
throw new ArgumentNullException("Tarball cannot be null.");
|
||||
|
||||
// Log
|
||||
Log.Write("[DrumkitRepository] Exporting drumkit \"{0}\" to tarball : {1}", drumkit_key, tarball.Path);
|
||||
|
||||
// Get drumkit's folder
|
||||
StorageFolder folder = AvailableDrumKits[drumkit_key].RootFolder;
|
||||
|
||||
// Create tarball writer
|
||||
Tarball.TarballWriter writer = new Tarball.TarballWriter();
|
||||
writer.AddItems(await folder.GetItemsAsync());
|
||||
await writer.Pack(tarball);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Remove
|
||||
/// <summary>
|
||||
/// Removes a drumkit from the repository (and system)
|
||||
/// </summary>
|
||||
/// <param name="name">Name of drumkit</param>
|
||||
/// <exception cref="ArgumentException if name does not exist." />
|
||||
public async Task Remove(string name)
|
||||
{
|
||||
// Make sure such name exists
|
||||
if (!this.AvailableDrumKits.ContainsKey(name))
|
||||
throw new ArgumentException("Invalid name");
|
||||
|
||||
// Remove folder
|
||||
if (this.AvailableDrumKits[name].RootFolder != null)
|
||||
{
|
||||
// Log
|
||||
Log.Write("[DrumkitRepository] Removing drumkit: name = {0}, location = {1}", name, this.AvailableDrumKits[name].RootFolder.Path);
|
||||
await this.AvailableDrumKits[name].RootFolder.DeleteAsync(StorageDeleteOption.PermanentDelete);
|
||||
}
|
||||
|
||||
// Remove entry
|
||||
this.AvailableDrumKits.Remove(name);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Cleans the used resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.AvailableDrumKits.Clear();
|
||||
}
|
||||
}
|
||||
}
|
140
DrumKit/Repository/LogRepository.cs
Normal file
140
DrumKit/Repository/LogRepository.cs
Normal file
@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace DrumKit.Repository
|
||||
{
|
||||
public static class LogRepository
|
||||
{
|
||||
private static StorageFile OutputFile = null;
|
||||
private static StorageFolder RootDirectory = null;
|
||||
private static List<string> Buffer = new List<string>();
|
||||
|
||||
public static DateTime CurrentLogDate { get; private set; }
|
||||
public static List<DateTime> Dates { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the log repository.
|
||||
/// </summary>
|
||||
public static async Task Initialize(StorageFolder location)
|
||||
{
|
||||
// Create/open log file
|
||||
CurrentLogDate = new DateTime(DateTime.Now.Ticks);
|
||||
OutputFile = await location.CreateFileAsync(CurrentLogDate.Ticks.ToString() + ".log", CreationCollisionOption.OpenIfExists);
|
||||
|
||||
// Set root directory
|
||||
RootDirectory = location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a line to the log file
|
||||
/// </summary>
|
||||
/// <param name="text">The text to write.</param>
|
||||
public static async void WriteLine(string text)
|
||||
{
|
||||
// Append text
|
||||
if (OutputFile != null)
|
||||
try {
|
||||
await FileIO.AppendTextAsync(OutputFile, text + "\n");
|
||||
}
|
||||
|
||||
catch { }
|
||||
|
||||
// No file? write to a temporary buffer
|
||||
else Buffer.Add(text);
|
||||
|
||||
// Also write to console
|
||||
System.Diagnostics.Debug.WriteLine(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the list of log files
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task ReadLogFiles()
|
||||
{
|
||||
// Make sure we have a root directory
|
||||
if (RootDirectory == null)
|
||||
throw new RepositoryException("No location set!");
|
||||
|
||||
// Get files in root directory
|
||||
var files = await RootDirectory.GetFilesAsync();
|
||||
|
||||
// Clear old dates
|
||||
Dates = new List<DateTime>();
|
||||
|
||||
// Get dates
|
||||
long ticks;
|
||||
foreach (var i in files)
|
||||
{
|
||||
string file_name = Path.GetFileNameWithoutExtension(i.Name);
|
||||
|
||||
if (long.TryParse(file_name, out ticks))
|
||||
Dates.Add(new DateTime(ticks));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all log files except the current one.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task Clear()
|
||||
{
|
||||
// Make sure we have a root directory
|
||||
if (RootDirectory == null)
|
||||
throw new RepositoryException("No location set!");
|
||||
|
||||
// Get files in root directory
|
||||
var files = await RootDirectory.GetFilesAsync();
|
||||
|
||||
// Calculate current date
|
||||
string current = CurrentLogDate.Ticks.ToString() + ".log";
|
||||
|
||||
// Delete everything except current
|
||||
foreach (var i in files)
|
||||
if (i.Name != current)
|
||||
await i.DeleteAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a log file.
|
||||
/// </summary>
|
||||
/// <param name="time">The date and time linked to this log file.</param>
|
||||
/// <returns>The list of lines for this file.</returns>
|
||||
public static async Task<IList<string>> ReadLog(DateTime time)
|
||||
{
|
||||
// Make sure we have a root directory
|
||||
if (RootDirectory == null)
|
||||
throw new RepositoryException("No location set!");
|
||||
|
||||
// Find the file
|
||||
var file = await RootDirectory.GetFileAsync(time.Ticks.ToString() + ".log");
|
||||
|
||||
// Return result
|
||||
return await FileIO.ReadLinesAsync(file);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a log file to another location.
|
||||
/// </summary>
|
||||
/// <param name="log">Date and time for the log entry.</param>
|
||||
/// <param name="dest">Destination folder</param>
|
||||
public static async Task SaveAs (DateTime log, StorageFolder dest)
|
||||
{
|
||||
// Make sure we have a root directory
|
||||
if (RootDirectory == null)
|
||||
throw new RepositoryException("No location set!");
|
||||
|
||||
// Find the file
|
||||
var file = await RootDirectory.GetFileAsync(log.Ticks.ToString() + ".log");
|
||||
|
||||
// Copy
|
||||
await file.CopyAsync(dest);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
20
DrumKit/Repository/RepositoryException.cs
Normal file
20
DrumKit/Repository/RepositoryException.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DrumKit.Repository
|
||||
{
|
||||
class RepositoryException : Exception
|
||||
{
|
||||
public RepositoryException() :
|
||||
base() { }
|
||||
|
||||
public RepositoryException(string message) :
|
||||
base(message) { }
|
||||
|
||||
public RepositoryException(string message, Exception innerException) :
|
||||
base(message, innerException) { }
|
||||
}
|
||||
}
|
131
DrumKit/Repository/SoundRepository.cs
Normal file
131
DrumKit/Repository/SoundRepository.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using SharpDX.XAudio2;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Windows.Storage;
|
||||
using SharpDX.Multimedia;
|
||||
|
||||
namespace DrumKit.Repository
|
||||
{
|
||||
class SoundRepository
|
||||
{
|
||||
#region Properties
|
||||
public StorageFolder RepositoryLocation { get; private set; }
|
||||
public Dictionary<string, Sound> LoadedSounds { get; private set; }
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Creates a new instance of sound repository.
|
||||
/// </summary>
|
||||
public SoundRepository(StorageFolder where)
|
||||
{
|
||||
this.RepositoryLocation = null;
|
||||
this.LoadedSounds = new Dictionary<string, Sound>();
|
||||
|
||||
this.Initialize(where);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Initialize
|
||||
/// <summary>
|
||||
/// Initializes the repository set to one location.
|
||||
/// </summary>
|
||||
private void Initialize(StorageFolder where)
|
||||
{
|
||||
// Set up location
|
||||
this.RepositoryLocation = where;
|
||||
Log.Write("[SoundRepository] Location set: {0}", where.Path);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Loads a sound into memory.
|
||||
/// </summary>
|
||||
/// <param name="drumid">The id of the drum which will hold the sound.</param>
|
||||
/// <param name="source">A sound source.</param>
|
||||
private async Task LoadSound(string drumid, SoundSource source)
|
||||
{
|
||||
// Get file
|
||||
StorageFile file = await IOHelper.GetFileRelativeAsync(RepositoryLocation, source.Source);
|
||||
|
||||
// Open file
|
||||
var stream = await file.OpenReadAsync();
|
||||
var iostream = stream.AsStream();
|
||||
var soundStream = new SoundStream(iostream);
|
||||
|
||||
// Read data
|
||||
var buffer = new AudioBuffer()
|
||||
{
|
||||
Stream = soundStream,
|
||||
AudioBytes = (int)soundStream.Length,
|
||||
Flags = BufferFlags.EndOfStream
|
||||
};
|
||||
iostream.Dispose();
|
||||
|
||||
// Create sound object
|
||||
Sound sound = new Sound();
|
||||
sound.Buffer = buffer;
|
||||
sound.DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
|
||||
sound.WaveFormat = soundStream.Format;
|
||||
|
||||
// Add sound to dictionary
|
||||
this.LoadedSounds.Add(String.Format("{0}#{1}", drumid, source.Intensity), sound);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all the sounds associated with a drum to memory.
|
||||
/// </summary>
|
||||
/// <param name="drum">The drum.</param>
|
||||
public async Task LoadSounds(Drum drum)
|
||||
{
|
||||
// Load each sound
|
||||
foreach (var i in drum.Sounds)
|
||||
await this.LoadSound(drum.Id, i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads all the sounds associated with a drum from memory.
|
||||
/// </summary>
|
||||
/// <param name="drum">The drum</param>
|
||||
public void UnloadSounds(Drum drum)
|
||||
{
|
||||
// Unload each sound
|
||||
foreach (var i in drum.Sounds)
|
||||
{
|
||||
string key = String.Format("{0}#{1}", drum.Id, i.Intensity);
|
||||
if (this.LoadedSounds.ContainsKey(key))
|
||||
this.LoadedSounds.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a loaded sound from the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="drumid">ID of the drum.</param>
|
||||
/// <param name="intensity">Sound intensity.</param>
|
||||
public Sound? GetLoadedSound(string drumid, int intensity)
|
||||
{
|
||||
Sound sound;
|
||||
string key = String.Format("{0}#{1}", drumid, intensity);
|
||||
|
||||
// Try to get sound
|
||||
if (!this.LoadedSounds.TryGetValue(key, out sound))
|
||||
return null;
|
||||
|
||||
// OK
|
||||
return sound;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans the currently used resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.LoadedSounds.Clear();
|
||||
}
|
||||
}
|
||||
}
|
@ -9,33 +9,74 @@ using SharpDX.Multimedia;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
class SoundPool
|
||||
public class SoundPool
|
||||
{
|
||||
List<SourceVoice> voices;
|
||||
private XAudio2 Device { get; set; }
|
||||
private MasteringVoice MasterVoice { get; set; }
|
||||
private Queue<SourceVoice> Channels { get; set; }
|
||||
|
||||
public SoundPool(XAudio2 device, WaveFormat format)
|
||||
/// <summary>
|
||||
/// Gets or sets the master volume
|
||||
/// </summary>
|
||||
public float MasterVolume
|
||||
{
|
||||
voices = new List<SourceVoice>();
|
||||
get {
|
||||
return this.MasterVoice.Volume;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
voices.Add(new SourceVoice(device, format, true));
|
||||
set {
|
||||
this.MasterVoice.SetVolume(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new sound pool.
|
||||
/// </summary>
|
||||
/// <param name="poly">How many sounds will be able to play simultaneously. Default is 64.</param>
|
||||
public SoundPool(WaveFormat format, int poly = 64)
|
||||
{
|
||||
// Create and initialize device
|
||||
this.Device = new XAudio2();
|
||||
this.Device.StartEngine();
|
||||
|
||||
// Create voices
|
||||
this.MasterVoice = new MasteringVoice(this.Device);
|
||||
this.Channels = new Queue<SourceVoice>();
|
||||
|
||||
for (int i = 0; i < poly; i++)
|
||||
{
|
||||
SourceVoice voice = new SourceVoice(this.Device, format, true);
|
||||
this.Channels.Enqueue(voice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void PlayBuffer(AudioBuffer buffer, uint[] packetinfo)
|
||||
/// <summary>
|
||||
/// Plays a sound buffer through one of the free channels.
|
||||
/// </summary>
|
||||
/// <param name="sound">The sound object</param>
|
||||
public void PlayBuffer(Sound sound, float volumeL = 1.0f, float volumeR = 1.0f)
|
||||
{
|
||||
int preferred = -1;
|
||||
float[] volumes = { volumeL, volumeR };
|
||||
|
||||
for (int i = 0; i < voices.Count; i++)
|
||||
if (voices[i].State.BuffersQueued == 0)
|
||||
preferred = i;
|
||||
SourceVoice top = this.Channels.Dequeue();
|
||||
top.Stop();
|
||||
top.FlushSourceBuffers();
|
||||
top.SubmitSourceBuffer(sound.Buffer, sound.DecodedPacketsInfo);
|
||||
top.SetChannelVolumes(2, volumes);
|
||||
top.Start();
|
||||
this.Channels.Enqueue(top);
|
||||
}
|
||||
|
||||
if (preferred != -1)
|
||||
{
|
||||
// voices[preferred].FlushSourceBuffers();
|
||||
voices[preferred].SubmitSourceBuffer(buffer, packetinfo);
|
||||
voices[preferred].Start();
|
||||
}
|
||||
/// <summary>
|
||||
/// Cleans up used resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Channels.Clear();
|
||||
this.MasterVoice.Dispose();
|
||||
Device.StopEngine();
|
||||
Device.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
DrumKit/UI/CommonControls/FileControl.xaml
Normal file
36
DrumKit/UI/CommonControls/FileControl.xaml
Normal file
@ -0,0 +1,36 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.FileControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="120"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Name="textName" Style="{StaticResource TitleTextStyle}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,8">Test</TextBlock>
|
||||
|
||||
<Image Grid.Row="1" Name="image"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Left" Width="120"/>
|
||||
|
||||
<Button Name="buttonBrowse" Style="{StaticResource TextButtonStyle}"
|
||||
Grid.Column="1" Margin="10,5,10,5">...</Button>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
26
DrumKit/UI/CommonControls/FileControl.xaml.cs
Normal file
26
DrumKit/UI/CommonControls/FileControl.xaml.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class FileControl : UserControl
|
||||
{
|
||||
public FileControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
211
DrumKit/UI/DrumEditUI.xaml
Normal file
211
DrumKit/UI/DrumEditUI.xaml
Normal file
@ -0,0 +1,211 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.DrumEditUI"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
SizeChanged="DrumEditUl_SizeChanged">
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
<!-- Translation thumb -->
|
||||
<SolidColorBrush x:Key="TranslationThumbBackgroundBrush" Color="Transparent" />
|
||||
|
||||
<LinearGradientBrush x:Key="TranslationThumbBackgroundFocusedBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#2fff" Offset="1" />
|
||||
<GradientStop Color="#5fff" Offset="0" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="TranslationThumbBackgroundPressedBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#1fff" Offset="1" />
|
||||
<GradientStop Color="#3fff" Offset="0" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="TranslationThumbBorderBrush" StartPoint="0,0" EndPoint="0,1" >
|
||||
<GradientStop Color="#2fff" Offset="1" />
|
||||
<GradientStop Color="#5fff" Offset="0" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<!-- Drum name background -->
|
||||
<LinearGradientBrush x:Key="DrumNameBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#0000" Offset="1" />
|
||||
<GradientStop Color="#2000" Offset="0.7" />
|
||||
<GradientStop Color="#a000" Offset="0" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<!-- Round thumb -->
|
||||
<SolidColorBrush x:Key="RoundThumbBackgroundBrush" Color="WhiteSmoke" />
|
||||
<SolidColorBrush x:Key="RoundThumbBorderBrush" Color="LightGray" />
|
||||
<SolidColorBrush x:Key="RoundThumbForegroundBrush" Color="Gray" />
|
||||
|
||||
<!-- Rotation thumb -->
|
||||
<SolidColorBrush x:Key="RotationTranslationThumbBackgroundBrush" Color="Coral" />
|
||||
<SolidColorBrush x:Key="RotationTranslationThumbBorderBrush" Color="LightCoral" />
|
||||
<SolidColorBrush x:Key="RotationDrumForegroundBrush" Color="Brown" />
|
||||
|
||||
<!-- Translation thumb style -->
|
||||
<Style x:Name="TranslationThumbStyle" TargetType="Thumb">
|
||||
<Setter Property="Background" Value="{StaticResource TranslationThumbBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource TranslationThumbBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
|
||||
<Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" >
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="normalRectangle"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0" To="1" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="focusedRectangle"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0" To="1" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="pressedRectangle"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0" To="1" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Rectangle Name="normalRectangle"
|
||||
Fill="{TemplateBinding Background}"
|
||||
Stroke="{TemplateBinding BorderBrush}"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}"
|
||||
Opacity="0" />
|
||||
|
||||
<Rectangle Name="focusedRectangle"
|
||||
Fill="{StaticResource TranslationThumbBackgroundFocusedBrush}"
|
||||
Stroke="{TemplateBinding BorderBrush}"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}"
|
||||
Opacity="0" />
|
||||
|
||||
<Rectangle Name="pressedRectangle"
|
||||
Fill="{StaticResource TranslationThumbBackgroundPressedBrush}"
|
||||
Stroke="{TemplateBinding BorderBrush}"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}"
|
||||
Opacity="0" />
|
||||
</Grid>
|
||||
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Round thumb style -->
|
||||
<Style x:Key="RoundThumbStyle" TargetType="Thumb">
|
||||
<Setter Property="Background" Value="{StaticResource RoundThumbBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource RoundThumbBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="Foreground" Value="{StaticResource RoundThumbForegroundBrush}" />
|
||||
<Setter Property="Height" Value="16" />
|
||||
<Setter Property="Width" Value="16" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Grid>
|
||||
<Ellipse
|
||||
Fill="{TemplateBinding Background}"
|
||||
Stroke="{TemplateBinding BorderBrush}"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}" />
|
||||
|
||||
<TextBlock
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Text="{TemplateBinding Tag}"/>
|
||||
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Rotation thumb style -->
|
||||
<Style x:Key="RotationThumbStyle" TargetType="Thumb" BasedOn="{StaticResource RoundThumbStyle}" >
|
||||
<Setter Property="Background" Value="{StaticResource RotationTranslationThumbBackgroundBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource RotationTranslationThumbBorderBrush}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource RotationDrumForegroundBrush}" />
|
||||
<Setter Property="FontFamily" Value="{StaticResource SymbolThemeFontFamily}" />
|
||||
<Setter Property="FontSize" Value="10" />
|
||||
<Setter Property="FontStyle" Value="Normal" />
|
||||
<Setter Property="Tag" Value="" />
|
||||
</Style>
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
|
||||
<Grid Name="rotateGrid" IsHitTestVisible="False">
|
||||
|
||||
<Image Name="image" IsHitTestVisible="False"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Border HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
IsHitTestVisible="False"
|
||||
Background="{StaticResource DrumNameBackgroundBrush}">
|
||||
|
||||
<TextBlock
|
||||
IsHitTestVisible="False"
|
||||
Name="nameText" HorizontalAlignment="Center"
|
||||
Style="{StaticResource TitleTextStyle}"
|
||||
Margin="0,2,0,16"/>
|
||||
|
||||
</Border>
|
||||
|
||||
<Border BorderBrush="Black" BorderThickness="1">
|
||||
|
||||
<Thumb
|
||||
Name="translationThumb"
|
||||
Style="{StaticResource TranslationThumbStyle}"
|
||||
DragDelta="translationThumb_DragDelta" />
|
||||
|
||||
</Border>
|
||||
|
||||
<Thumb
|
||||
Name="rotationThumb"
|
||||
Style="{StaticResource RotationThumbStyle}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
DragStarted="rotationThumb_DragStarted"
|
||||
DragDelta="rotationThumb_DragDelta" >
|
||||
|
||||
</Thumb>
|
||||
|
||||
<Thumb
|
||||
Name="scaleThumb" Grid.Row="1"
|
||||
Style="{StaticResource RoundThumbStyle}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
DragDelta="scaleThumb_DragDelta" >
|
||||
|
||||
<Thumb.RenderTransform>
|
||||
<TranslateTransform X="8" Y="8" />
|
||||
</Thumb.RenderTransform>
|
||||
|
||||
</Thumb>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
180
DrumKit/UI/DrumEditUI.xaml.cs
Normal file
180
DrumKit/UI/DrumEditUI.xaml.cs
Normal file
@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class DrumEditUI : UserControl
|
||||
{
|
||||
#region Constants
|
||||
const double RotationHandleOffset = 8;
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <summary>
|
||||
/// Triggered when the item was dragged.
|
||||
/// </summary>
|
||||
public event DragDeltaEventHandler DragDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the angle changes
|
||||
/// </summary>
|
||||
public event EventHandler AngleChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drum rotation
|
||||
/// </summary>
|
||||
public double Angle
|
||||
{
|
||||
get
|
||||
{
|
||||
// Get rotated grid
|
||||
var transform = rotateGrid.RenderTransform as RotateTransform;
|
||||
|
||||
// Get angle
|
||||
if (transform != null)
|
||||
return transform.Angle;
|
||||
|
||||
// No rotation
|
||||
return 0;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
// Set rotation transformation
|
||||
RotateTransform rot = new RotateTransform();
|
||||
rot.CenterX = this.Width / 2;
|
||||
rot.CenterY = this.Height / 2;
|
||||
rot.Angle = value;
|
||||
|
||||
rotateGrid.RenderTransform = rot;
|
||||
|
||||
// Set thumb position
|
||||
TranslateTransform tr = new TranslateTransform();
|
||||
double radius = this.Height / 2 + RotationHandleOffset;
|
||||
double rads = Math.PI * (value - 90) / 180;
|
||||
|
||||
tr.X = radius * Math.Cos(rads);
|
||||
tr.Y = radius * Math.Sin(rads);
|
||||
|
||||
rotationThumb.RenderTransform = tr;
|
||||
|
||||
// Call event
|
||||
if (AngleChanged != null)
|
||||
AngleChanged(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the drum id.
|
||||
/// </summary>
|
||||
public string DrumID { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private fields
|
||||
|
||||
private double rotationDragX = 0, rotationDragY = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of DrumEditUI
|
||||
/// </summary>
|
||||
public DrumEditUI(Drum drum)
|
||||
{
|
||||
// Initialize
|
||||
this.InitializeComponent();
|
||||
|
||||
// Set drum properties
|
||||
this.DrumID = drum.Id;
|
||||
this.nameText.Text = drum.Name;
|
||||
|
||||
// Set image
|
||||
this.image.Source = drum.LoadedImageSource;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handles the "rotation handle drag started" event.
|
||||
/// </summary>
|
||||
private void rotationThumb_DragStarted(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
var transl = this.rotationThumb.RenderTransform as TranslateTransform;
|
||||
|
||||
double x = (transl == null) ? 0 : transl.X;
|
||||
double y = (transl == null) ? 0 : transl.Y;
|
||||
|
||||
rotationDragX = x;
|
||||
rotationDragY = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the "rotation handle dragged" event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void rotationThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
rotationDragX += e.HorizontalChange;
|
||||
rotationDragY += e.VerticalChange;
|
||||
|
||||
double angle = Math.Atan2(rotationDragY, rotationDragX) * 180.0 / Math.PI + 90;
|
||||
this.Angle = angle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the "scale handle dragged" event.
|
||||
/// </summary>
|
||||
private void scaleThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
double new_w = this.Width + e.HorizontalChange;
|
||||
// double new_h = this.Height + e.VerticalChange;
|
||||
|
||||
this.Width = Math.Max(0, new_w);
|
||||
this.Height = Math.Max(0, new_w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the translation drag delta event.
|
||||
/// </summary>
|
||||
private void translationThumb_DragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
if (this.DragDelta != null)
|
||||
this.DragDelta(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the size changed event.
|
||||
/// </summary>
|
||||
private void DrumEditUl_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
this.Angle = Angle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
65
DrumKit/UI/DrumPlayUI.xaml
Normal file
65
DrumKit/UI/DrumPlayUI.xaml
Normal file
@ -0,0 +1,65 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.DrumPlayUI"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<Grid Name="grid" Background="Transparent"
|
||||
PointerPressed="Grid_PointerPressed">
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
|
||||
<VisualStateGroup x:Name="DrumGroups">
|
||||
|
||||
<VisualState x:Name="DrumNormal">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="imagePressed"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
BeginTime="0:0:0.1" Duration="0:0:0.7" To="0" >
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<SineEase EasingMode="EaseInOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<DoubleAnimation Storyboard.TargetName="image"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0:0:0.3" To="1" >
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<SineEase EasingMode="EaseIn" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="DrumHit">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="imagePressed"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0" To="1" />
|
||||
<DoubleAnimation Storyboard.TargetName="image"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
Duration="0" To=".3" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Image Name="image" IsHitTestVisible="False"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" />
|
||||
|
||||
<Image Name="imagePressed" IsHitTestVisible="False"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Opacity="0" />
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
122
DrumKit/UI/DrumPlayUI.xaml.cs
Normal file
122
DrumKit/UI/DrumPlayUI.xaml.cs
Normal file
@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class DrumPlayUI : UserControl
|
||||
{
|
||||
#region Public events
|
||||
public event PointerEventHandler Hit;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Gets or sets the rotation of the drum
|
||||
/// </summary>
|
||||
public double Angle
|
||||
{
|
||||
get
|
||||
{
|
||||
// Get rotated grid
|
||||
var transform = grid.RenderTransform as RotateTransform;
|
||||
|
||||
// Get angle
|
||||
if (transform != null)
|
||||
return transform.Angle;
|
||||
|
||||
// No rotation
|
||||
return 0;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
// Set rotation transformation
|
||||
RotateTransform rot = new RotateTransform();
|
||||
rot.CenterX = this.Width / 2;
|
||||
rot.CenterY = this.Height / 2;
|
||||
rot.Angle = value;
|
||||
|
||||
grid.RenderTransform = rot;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the drum id.
|
||||
/// </summary>
|
||||
public string DrumID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the hit animation.
|
||||
/// </summary>
|
||||
private bool IsAnimationEnabled {
|
||||
get {
|
||||
return DataController.Settings.Animations;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of DrumPlayUI
|
||||
/// </summary>
|
||||
/// <param name="drum"></param>
|
||||
public DrumPlayUI(Drum drum)
|
||||
{
|
||||
// Initialize
|
||||
this.InitializeComponent();
|
||||
|
||||
// Set drum properties
|
||||
this.DrumID = drum.Id;
|
||||
// TODO: key
|
||||
this.image.Source = drum.LoadedImageSource;
|
||||
this.imagePressed.Source = drum.LoadedImagePressedSource;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI handlers
|
||||
/// <summary>
|
||||
/// Handles the drum pressed event.
|
||||
/// </summary>
|
||||
private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
// Call hit event immediately
|
||||
if (this.Hit != null)
|
||||
this.Hit(this, e);
|
||||
|
||||
// Play animation
|
||||
this.PerformHit();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
public void PerformHit()
|
||||
{
|
||||
// Play animation
|
||||
if (this.IsAnimationEnabled)
|
||||
{
|
||||
VisualStateManager.GoToState(this, "DrumHit", true);
|
||||
VisualStateManager.GoToState(this, "DrumNormal", true);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,178 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
class DrumUI
|
||||
{
|
||||
#region Private attributes
|
||||
private Thumb thumb;
|
||||
private Image image, imagePressed;
|
||||
private Grid grid;
|
||||
private Storyboard hitAnimation;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <summary>
|
||||
/// Gets the ui element which will be put in a canvas.
|
||||
/// </summary>
|
||||
public FrameworkElement Element { get { return grid; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the drum id.
|
||||
/// </summary>
|
||||
public string DrumID { get; private set; }
|
||||
|
||||
public event Windows.UI.Xaml.Input.PointerEventHandler PointerPressed
|
||||
{
|
||||
add {
|
||||
grid.PointerPressed += value;
|
||||
}
|
||||
|
||||
remove {
|
||||
grid.PointerPressed -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public event DragDeltaEventHandler DragDelta
|
||||
{
|
||||
add {
|
||||
thumb.DragDelta += value;
|
||||
}
|
||||
|
||||
remove {
|
||||
thumb.DragDelta -= value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
private void GridAddChild(FrameworkElement element)
|
||||
{
|
||||
grid.Children.Add(element);
|
||||
element.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
element.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
}
|
||||
|
||||
private void InitializeCreateObjects()
|
||||
{
|
||||
// Create thumb
|
||||
this.thumb = new Thumb()
|
||||
{
|
||||
Background = new SolidColorBrush(Colors.Green),
|
||||
Opacity = .3,
|
||||
Visibility = Visibility.Collapsed
|
||||
};
|
||||
|
||||
// Create image
|
||||
this.image = new Image();
|
||||
|
||||
// Create pressed image
|
||||
this.imagePressed = new Image()
|
||||
{
|
||||
Opacity = 0
|
||||
};
|
||||
|
||||
// Create grid
|
||||
this.grid = new Grid();
|
||||
|
||||
// Create animation
|
||||
DoubleAnimation fade = new DoubleAnimation();
|
||||
fade.Duration = TimeSpan.FromSeconds(.6);
|
||||
fade.From = 1;
|
||||
fade.To = 0;
|
||||
|
||||
Storyboard.SetTarget(fade, this.imagePressed);
|
||||
Storyboard.SetTargetProperty(fade, "Opacity");
|
||||
|
||||
this.hitAnimation = new Storyboard();
|
||||
this.hitAnimation.Children.Add(fade);
|
||||
|
||||
// grid.Resources.Add("hitanimation", this.hitAnimation);
|
||||
}
|
||||
|
||||
private void InitializeParenting()
|
||||
{
|
||||
this.GridAddChild(this.image);
|
||||
this.GridAddChild(this.imagePressed);
|
||||
this.GridAddChild(this.thumb);
|
||||
}
|
||||
|
||||
public async Task InitializeDrum(Drum drum, StorageFolder root)
|
||||
{
|
||||
// Set path
|
||||
Uri rootpath = new Uri(root.Path);
|
||||
|
||||
// Set drum id
|
||||
this.DrumID = drum.Id;
|
||||
|
||||
// Set images
|
||||
this.image.Source = await IOHelper.GetImageAsync(root, drum.ImageSource);
|
||||
this.imagePressed.Source = await IOHelper.GetImageAsync(root, drum.ImagePressedSource);
|
||||
|
||||
// Set tags
|
||||
this.thumb.Tag = drum.Id;
|
||||
this.grid.Tag = drum.Id;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public DrumUI()
|
||||
{
|
||||
// Create objects
|
||||
this.InitializeCreateObjects();
|
||||
this.InitializeParenting();
|
||||
}
|
||||
|
||||
public void UpdateLayout(DrumLayout layout, double canvasWidth, double canvasHeight)
|
||||
{
|
||||
// Set up size
|
||||
this.grid.Width = layout.Size * canvasWidth;
|
||||
this.grid.Height = layout.Size * canvasWidth;
|
||||
|
||||
// Set up position
|
||||
Canvas.SetLeft(this.grid, layout.X * canvasWidth);
|
||||
Canvas.SetTop(this.grid, layout.Y * canvasHeight);
|
||||
Canvas.SetZIndex(this.grid, layout.ZIndex);
|
||||
|
||||
// Rotation
|
||||
RotateTransform transform = new RotateTransform();
|
||||
transform.Angle = layout.Angle;
|
||||
transform.CenterX = this.grid.Width / 2;
|
||||
transform.CenterY = this.grid.Height / 2;
|
||||
this.image.RenderTransform = transform;
|
||||
this.imagePressed.RenderTransform = transform;
|
||||
}
|
||||
|
||||
public void Hit()
|
||||
{
|
||||
// Perform a drum hit
|
||||
this.hitAnimation.Begin();
|
||||
}
|
||||
|
||||
public void EnableEdit()
|
||||
{
|
||||
// Thumb becomes visible
|
||||
this.thumb.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public void DisableEdit()
|
||||
{
|
||||
// Thumb becomes invisible
|
||||
this.thumb.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
34
DrumKit/UI/EditorPage.xaml
Normal file
34
DrumKit/UI/EditorPage.xaml
Normal file
@ -0,0 +1,34 @@
|
||||
<Page
|
||||
x:Class="DrumKit.EditorPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ImageBrush x:Key="EditorBackgroundBrush" ImageSource="ms-appx:///Assets/bg.png" Stretch="UniformToFill" />
|
||||
|
||||
</Page.Resources>
|
||||
|
||||
<Canvas
|
||||
Name="container"
|
||||
Background="{StaticResource EditorBackgroundBrush}">
|
||||
|
||||
<Button Name="buttonBack" Canvas.Left="10" Canvas.Top="10" Canvas.ZIndex="1"
|
||||
Style="{StaticResource BackButtonStyle}"
|
||||
Click="buttonBack_Click" />
|
||||
|
||||
</Canvas>
|
||||
|
||||
<!--<Page.BottomAppBar>
|
||||
<AppBar>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button>Change order</Button>
|
||||
<Button>Bring all drums into view</Button>
|
||||
</StackPanel>
|
||||
</AppBar>
|
||||
</Page.BottomAppBar>-->
|
||||
|
||||
</Page>
|
244
DrumKit/UI/EditorPage.xaml.cs
Normal file
244
DrumKit/UI/EditorPage.xaml.cs
Normal file
@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class EditorPage : Page
|
||||
{
|
||||
#region Private properties
|
||||
private int LayoutIndex { get; set; }
|
||||
|
||||
private DrumkitLayout Layout {
|
||||
get {
|
||||
if (this.LayoutIndex == -1)
|
||||
return null;
|
||||
|
||||
return DataController.CurrentLayouts.Items[LayoutIndex];
|
||||
}
|
||||
|
||||
set {
|
||||
this.LayoutIndex = DataController.CurrentLayouts.Items.IndexOf(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, DrumEditUI> DrumUIs { get; set; }
|
||||
|
||||
private bool IgnoreEvent = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor, initialization
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of EditorPage.
|
||||
/// </summary>
|
||||
public EditorPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
this.DrumUIs = new Dictionary<string, DrumEditUI>();
|
||||
this.LayoutIndex = -1;
|
||||
|
||||
this.SizeChanged += EditorPage_SizeChanged;
|
||||
this.Loaded += EditorPage_Loaded;
|
||||
|
||||
this.InitializeDrums();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the page loaded event.
|
||||
/// </summary>
|
||||
void EditorPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReloadLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the drums.
|
||||
/// </summary>
|
||||
void InitializeDrums()
|
||||
{
|
||||
foreach (var i in DataController.CurrentDrumkit.Drums)
|
||||
{
|
||||
// Create drum edit UI
|
||||
var ui = new DrumEditUI(i.Value);
|
||||
|
||||
// Set up events
|
||||
ui.DragDelta += Drum_Dragged;
|
||||
ui.SizeChanged += Drum_SizeChanged;
|
||||
ui.AngleChanged += Drum_AngleChanged;
|
||||
|
||||
// Add to canvas and dictionary
|
||||
this.container.Children.Add(ui);
|
||||
this.DrumUIs.Add(i.Key, ui);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reload layout
|
||||
/// <summary>
|
||||
/// Updates the layout of the drums
|
||||
/// </summary>
|
||||
void ReloadLayout()
|
||||
{
|
||||
// Get current size
|
||||
double w = container.ActualWidth;
|
||||
double h = container.ActualHeight;
|
||||
|
||||
if (double.IsNaN(w) || double.IsNaN(h) || double.IsInfinity(w) || double.IsInfinity(h))
|
||||
return;
|
||||
|
||||
// Flag that tells event handlers to ignore event
|
||||
this.IgnoreEvent = true;
|
||||
|
||||
// Set layouts
|
||||
foreach (var i in Layout.Drums)
|
||||
{
|
||||
// Set angle
|
||||
DrumUIs[i.Key].Angle = i.Value.Angle;
|
||||
|
||||
// Set scale
|
||||
DrumUIs[i.Key].Width = i.Value.Size * w;
|
||||
DrumUIs[i.Key].Height = i.Value.Size * w;
|
||||
|
||||
// Set position
|
||||
Canvas.SetLeft(DrumUIs[i.Key], w * i.Value.X);
|
||||
Canvas.SetTop(DrumUIs[i.Key], h * i.Value.Y);
|
||||
}
|
||||
|
||||
// Ignore no more
|
||||
this.IgnoreEvent = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Page events
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property is typically used to configure the page.</param>
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
Log.Write("Navigated to editor page.");
|
||||
|
||||
// When we arrive here, we should have a layout
|
||||
var layout = e.Parameter as DrumkitLayout;
|
||||
|
||||
if (layout == null)
|
||||
Frame.GoBack();
|
||||
|
||||
// Set layout
|
||||
this.Layout = layout;
|
||||
this.ReloadLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the page resize event.
|
||||
/// </summary>
|
||||
private void EditorPage_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
ReloadLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Buttons events
|
||||
|
||||
/// <summary>
|
||||
/// Handles the "Back" button click event.
|
||||
/// </summary>
|
||||
private void buttonBack_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.GoBack();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Drum events
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the angle is changed.
|
||||
/// </summary>
|
||||
void Drum_AngleChanged(object sender, EventArgs e)
|
||||
{
|
||||
var drumui = sender as DrumEditUI;
|
||||
|
||||
if (sender != null && !IgnoreEvent)
|
||||
{
|
||||
this.Layout.Drums[drumui.DrumID].Angle = drumui.Angle;
|
||||
|
||||
DataController.SaveLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the size of a drum is changed.
|
||||
/// </summary>
|
||||
void Drum_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
var drumui = sender as DrumEditUI;
|
||||
|
||||
if (drumui != null && !IgnoreEvent)
|
||||
{
|
||||
this.Layout.Drums[drumui.DrumID].Size = drumui.ActualWidth / container.ActualWidth;
|
||||
DataController.SaveLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the drum is dragged.
|
||||
/// We have to perform the move ourselves.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
void Drum_Dragged(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
var drumui = sender as DrumEditUI;
|
||||
|
||||
if (drumui != null && !IgnoreEvent)
|
||||
{
|
||||
// Get old position
|
||||
double old_x = Canvas.GetLeft(drumui);
|
||||
double old_y = Canvas.GetTop(drumui);
|
||||
|
||||
// Calculate new position
|
||||
double new_x = old_x + e.HorizontalChange;
|
||||
double new_y = old_y + e.VerticalChange;
|
||||
|
||||
// Save layout
|
||||
Layout.Drums[drumui.DrumID].X = new_x / container.ActualWidth;
|
||||
Layout.Drums[drumui.DrumID].Y = new_y / container.ActualHeight;
|
||||
|
||||
// Move object
|
||||
Canvas.SetLeft(drumui, new_x);
|
||||
Canvas.SetTop(drumui, new_y);
|
||||
|
||||
// Save modification
|
||||
DataController.SaveLayout();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -7,13 +7,20 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="#164646">
|
||||
<Grid Background="{StaticResource ApplicationBackgroundColor}">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<Image Source="ms-appx:///Assets/Logos/SplashScreen.png"
|
||||
Stretch="None"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
<StackPanel
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
@ -21,10 +28,15 @@
|
||||
Margin="20">
|
||||
<ProgressRing Width="40" Height="40" IsActive="True" Foreground="White" />
|
||||
<TextBlock
|
||||
Name="TextLoading"
|
||||
Name="textLoading"
|
||||
Style="{StaticResource SubheaderTextStyle}" Margin="10,0,0,0">
|
||||
Loading resources...</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<ProgressBar
|
||||
Name="progressBar" Grid.Row="1"
|
||||
Foreground="#53AB6D" Background="#20FFFFFF"
|
||||
Minimum="0" Maximum="100"/>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
@ -24,10 +25,8 @@ namespace DrumKit
|
||||
public LoadingPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Loaded += LoadingPage_Loaded;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// </summary>
|
||||
@ -35,38 +34,70 @@ namespace DrumKit
|
||||
/// property is typically used to configure the page.</param>
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
LoadStuff(e.Parameter);
|
||||
}
|
||||
|
||||
|
||||
private async void LoadingPage_Loaded(object sender, RoutedEventArgs e)
|
||||
private async Task DoFactoryReset()
|
||||
{
|
||||
DataController.Dispose();
|
||||
await DataController.FactoryReset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the loading of the application stuff.
|
||||
/// </summary>
|
||||
/// <param name="arg"></param>
|
||||
private async void LoadStuff(object arg)
|
||||
{
|
||||
bool error = false;
|
||||
DataController.ProgressChanged += DataController_ProgressChanged;
|
||||
|
||||
// Application restart?
|
||||
if (arg is string && (string) arg == "restart")
|
||||
DataController.Dispose();
|
||||
|
||||
// Factory reset?
|
||||
if (arg is string && (string) arg == "reset")
|
||||
await DoFactoryReset();
|
||||
|
||||
// Perform initializations
|
||||
try
|
||||
{
|
||||
TextLoading.Text = "Loading data...";
|
||||
await DataManager.Initialize();
|
||||
await Log.Initialize();
|
||||
await DrumsManager.Initialize(DataManager.Settings);
|
||||
|
||||
TextLoading.Text = "Loading sounds...";
|
||||
SoundManager.Initialize();
|
||||
await SoundManager.LoadDrumkit(DrumsManager.CurrentDrumkit, DrumsManager.CurrentDrumkitLocation);
|
||||
|
||||
TextLoading.Text = "Loading interface...";
|
||||
UIManager.Initialize();
|
||||
await UIManager.ReloadDrumkit();
|
||||
await UIManager.ReloadConfig();
|
||||
|
||||
try {
|
||||
await DataController.Initialize();
|
||||
Frame.Navigate(typeof(MainPage));
|
||||
}
|
||||
|
||||
// Error handling
|
||||
catch (Exception ex)
|
||||
{
|
||||
TextLoading.Text = "Failure: " + ex.Message;
|
||||
catch (Exception ex) {
|
||||
error = true;
|
||||
Log.Error("Failure during loading!");
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
var dialog = new Windows.UI.Popups.MessageDialog("A problem occurred, and the application could not be loaded.", "An error occurred!");
|
||||
dialog.Commands.Add(new Windows.UI.Popups.UICommand("Close", new Windows.UI.Popups.UICommandInvokedHandler(UICommandCloseHandler)));
|
||||
dialog.CancelCommandIndex = dialog.DefaultCommandIndex = 0;
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Application failed to load
|
||||
/// </summary>
|
||||
private async void UICommandCloseHandler(Windows.UI.Popups.IUICommand cmd)
|
||||
{
|
||||
await System.Threading.Tasks.Task.Delay(1000);
|
||||
Windows.ApplicationModel.Core.CoreApplication.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Progress event
|
||||
/// </summary>
|
||||
void DataController_ProgressChanged(object sender, KeyValuePair<int, string> e)
|
||||
{
|
||||
progressBar.Value = e.Key;
|
||||
textLoading.Text = e.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,21 +6,19 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Page.Transitions>
|
||||
<TransitionCollection>
|
||||
<EntranceThemeTransition />
|
||||
</TransitionCollection>
|
||||
</Page.Transitions>
|
||||
|
||||
<Grid
|
||||
Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Image Source="ms-appx:///Assets/bg.png"
|
||||
Stretch="UniformToFill"/>
|
||||
|
||||
<Grid Name="canvasContainer" />
|
||||
|
||||
<Grid Visibility="Collapsed">
|
||||
<Page.Resources>
|
||||
|
||||
<ImageBrush x:Key="MainpageBackgroundBrush" ImageSource="ms-appx:///Assets/bg.png" Stretch="UniformToFill" />
|
||||
|
||||
</Page.Resources>
|
||||
|
||||
<Grid
|
||||
Background="{StaticResource MainpageBackgroundBrush}">
|
||||
|
||||
<Canvas Name="canvas" />
|
||||
|
||||
<!--<Grid Visibility="Collapsed">
|
||||
<Border Margin="7"
|
||||
CornerRadius="10"
|
||||
BorderBrush="Red"
|
||||
@ -51,34 +49,49 @@
|
||||
</EventTrigger>
|
||||
</Canvas.Triggers>
|
||||
</Canvas>
|
||||
<!--<StackPanel Orientation="Horizontal"
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top">
|
||||
<Button>Record</Button>
|
||||
<Button>Stop</Button>
|
||||
</StackPanel>-->
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>-->
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<AppBar>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
||||
<ToggleButton
|
||||
Name="buttonAnimations"
|
||||
Click="buttonAnimations_Click"
|
||||
AutomationProperties.Name="Animations"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource VideoAppBarButtonStyle}" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ToggleButton
|
||||
Name="buttonEditMode"
|
||||
Click="buttonEditMode_Click"
|
||||
Style="{StaticResource EditAppBarButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal">
|
||||
|
||||
<ToggleButton
|
||||
Name="buttonAnimations"
|
||||
Click="buttonAnimations_Click"
|
||||
AutomationProperties.Name="Animations"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource VideoAppBarButtonStyle}" />
|
||||
|
||||
<Button
|
||||
Name="buttonEditMode"
|
||||
Click="ButtonEditMode_Click"
|
||||
Style="{StaticResource EditAppBarButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" >
|
||||
<Button
|
||||
Name="buttonSettings"
|
||||
Click="ButtonSettings_Click"
|
||||
AutomationProperties.Name="Settings"
|
||||
Style="{StaticResource SettingsAppBarButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</AppBar>
|
||||
</Page.BottomAppBar>
|
||||
</Page>
|
||||
|
@ -2,9 +2,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.Storage;
|
||||
using Windows.System;
|
||||
using Windows.UI.ApplicationSettings;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
@ -22,31 +26,263 @@ namespace DrumKit
|
||||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
#region Fields: Private members
|
||||
private Dictionary<string, DrumPlayUI> DrumUIs { get; set; }
|
||||
private Dictionary<VirtualKey, string> Keymap { get; set; }
|
||||
private int CurrentLayout { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Creates a new instance of MainPage.
|
||||
/// </summary>
|
||||
public MainPage()
|
||||
{
|
||||
// Create private members
|
||||
this.DrumUIs = new Dictionary<string, DrumPlayUI>();
|
||||
this.Keymap = new Dictionary<VirtualKey, string>();
|
||||
CurrentLayout = 0;
|
||||
|
||||
// Initialize page
|
||||
this.InitializeComponent();
|
||||
this.SizeChanged += MainPage_SizeChanged;
|
||||
this.Loaded += MainPage_Loaded;
|
||||
|
||||
this.canvasContainer.Children.Add(UIManager.TheCanvas);
|
||||
SettingsPane.GetForCurrentView().CommandsRequested += MainPage_CommandsRequested;
|
||||
|
||||
// Initialize drums
|
||||
this.InitializeDrums();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a single drum
|
||||
/// </summary>
|
||||
/// <param name="drum">The drum.</param>
|
||||
private void InitializeDrum(Drum drum)
|
||||
{
|
||||
// Create object
|
||||
DrumPlayUI d = new DrumPlayUI(drum);
|
||||
|
||||
// Set up callbacks
|
||||
d.Hit += HandlerDrumPointerPressed;
|
||||
|
||||
// Add to lists
|
||||
canvas.Children.Add(d);
|
||||
this.DrumUIs.Add(drum.Id, d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the drums.
|
||||
/// </summary>
|
||||
private void InitializeDrums()
|
||||
{
|
||||
// Clear previous stuff if any
|
||||
this.DrumUIs.Clear();
|
||||
this.Keymap.Clear();
|
||||
|
||||
// Load drums
|
||||
foreach (var i in DataController.CurrentDrumkit.DrumsList)
|
||||
InitializeDrum(i);
|
||||
|
||||
// Load drum configurations
|
||||
foreach (var i in DataController.CurrentConfig.DrumsList)
|
||||
{
|
||||
// Unload if disabled
|
||||
if (!i.IsEnabled)
|
||||
{
|
||||
canvas.Children.Remove(this.DrumUIs[i.TargetId]);
|
||||
this.DrumUIs.Remove(i.TargetId);
|
||||
}
|
||||
|
||||
// Keyboard mapping
|
||||
if (!Keymap.ContainsKey(i.Key))
|
||||
Keymap.Add(i.Key, i.TargetId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Settings charm
|
||||
/// <summary>
|
||||
/// Triggered when the settings pane requests commands/
|
||||
/// </summary>
|
||||
void MainPage_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
|
||||
{
|
||||
args.Request.ApplicationCommands.Clear();
|
||||
SettingsCommand general = new SettingsCommand("general", "General", new Windows.UI.Popups.UICommandInvokedHandler(MainPage_SettingsCommand));
|
||||
SettingsCommand drumkits = new SettingsCommand("drumkits", "Manage drumkits", new Windows.UI.Popups.UICommandInvokedHandler(MainPage_SettingsCommand));
|
||||
SettingsCommand drums = new SettingsCommand("drums", "Manage drums", new Windows.UI.Popups.UICommandInvokedHandler(MainPage_SettingsCommand));
|
||||
SettingsCommand layouts = new SettingsCommand("layouts", "Layouts", new Windows.UI.Popups.UICommandInvokedHandler(MainPage_SettingsCommand));
|
||||
|
||||
args.Request.ApplicationCommands.Add(general);
|
||||
args.Request.ApplicationCommands.Add(drumkits);
|
||||
args.Request.ApplicationCommands.Add(drums);
|
||||
args.Request.ApplicationCommands.Add(layouts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the settings charms
|
||||
/// </summary>
|
||||
void MainPage_SettingsCommand(Windows.UI.Popups.IUICommand command)
|
||||
{
|
||||
Frame.Navigate(typeof(SettingsPage), command.Id);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Layouts
|
||||
|
||||
/// <summary>
|
||||
/// Figures out which is the best layout available, and uses it.
|
||||
/// </summary>
|
||||
private int PickBestLayout()
|
||||
{
|
||||
// Smaller index is better
|
||||
int[] picks = {-1, -1, -1, -1, -1, -1};
|
||||
|
||||
// Get current layout
|
||||
var view = UIHelper.ToDrumkitLayoutView(Windows.UI.ViewManagement.ApplicationView.Value);
|
||||
|
||||
// Find best option
|
||||
for (int index = 0; index < DataController.CurrentLayouts.Items.Count; index++ )
|
||||
{
|
||||
var i = DataController.CurrentLayouts.Items[index];
|
||||
|
||||
bool isSame = (i.TargetView == view);
|
||||
bool contains = (i.TargetView & view) > 0;
|
||||
bool all = i.TargetView == DrumkitLayoutTargetView.All;
|
||||
|
||||
if (i.IsDefault)
|
||||
{
|
||||
if (isSame) picks[0] = index;
|
||||
if (contains) picks[1] = index;
|
||||
if (all) picks[2] = index;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (isSame) picks[3] = index;
|
||||
if (contains) picks[4] = index;
|
||||
if (all) picks[5] = index;
|
||||
}
|
||||
}
|
||||
|
||||
// Return first value different than -1, or 0
|
||||
foreach (var i in picks)
|
||||
if (i != -1) return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the layout
|
||||
/// </summary>
|
||||
private void ReloadLayout()
|
||||
{
|
||||
// Get current size
|
||||
double w = canvas.ActualWidth;
|
||||
double h = canvas.ActualHeight;
|
||||
|
||||
if (double.IsNaN(w) || double.IsNaN(h) || double.IsInfinity(w) || double.IsInfinity(h))
|
||||
return;
|
||||
|
||||
// Pick a layout
|
||||
this.CurrentLayout = PickBestLayout();
|
||||
|
||||
Log.Write("Layout change: picked_layout={0}, w={1}, h={2}", this.CurrentLayout, w, h);
|
||||
|
||||
// Apply layout
|
||||
foreach (var i in DataController.CurrentLayouts.Items[CurrentLayout].Drums)
|
||||
{
|
||||
if (!DrumUIs.ContainsKey(i.Key))
|
||||
continue;
|
||||
|
||||
// Set angle
|
||||
DrumUIs[i.Key].Angle = i.Value.Angle;
|
||||
|
||||
// Set scale
|
||||
DrumUIs[i.Key].Width = i.Value.Size * w;
|
||||
DrumUIs[i.Key].Height = i.Value.Size * w;
|
||||
|
||||
// Set position
|
||||
Canvas.SetLeft(DrumUIs[i.Key], w * i.Value.X);
|
||||
Canvas.SetTop(DrumUIs[i.Key], h * i.Value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Drums
|
||||
/// <summary>
|
||||
/// Handles drum hit using mouse/finger
|
||||
/// </summary>
|
||||
void HandlerDrumPointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
var button = sender as DrumPlayUI;
|
||||
|
||||
if (button != null)
|
||||
this.HandlerDrumClickedCommon(button.DrumID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drum hit using keyboard
|
||||
/// </summary>
|
||||
public void HandlerKeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
|
||||
{
|
||||
string drum;
|
||||
|
||||
// Key repeat or something
|
||||
if (args.KeyStatus.WasKeyDown)
|
||||
return;
|
||||
|
||||
// If key in key map, perform "click"
|
||||
if (this.Keymap.TryGetValue(args.VirtualKey, out drum))
|
||||
HandlerDrumClickedCommon(drum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drum hit.
|
||||
/// </summary>
|
||||
private void HandlerDrumClickedCommon(string drum_id)
|
||||
{
|
||||
try
|
||||
{
|
||||
DataController.PlaySound(drum_id, 0);
|
||||
|
||||
if (DataController.Settings.Animations)
|
||||
this.DrumUIs[drum_id].PerformHit();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error at playback!!! Drum id: {0}", drum_id);
|
||||
Log.Except(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI: Page events
|
||||
/// <summary>
|
||||
/// Handles page size change event.
|
||||
/// </summary>
|
||||
void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
// TODO: Find best layout, and change it
|
||||
DrumsManager.SetLayout();
|
||||
UIManager.ReloadLayout();
|
||||
this.ReloadLayout();
|
||||
this.ReloadLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles page load event.
|
||||
/// </summary>
|
||||
void MainPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Set layout
|
||||
DrumsManager.SetLayout();
|
||||
UIManager.ReloadLayout();
|
||||
this.ReloadLayout();
|
||||
|
||||
// Set toggles
|
||||
buttonAnimations.IsChecked = DataManager.Settings.Animations;
|
||||
buttonAnimations.IsChecked = DataController.Settings.Animations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -56,29 +292,33 @@ namespace DrumKit
|
||||
/// property is typically used to configure the page.</param>
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
Window.Current.CoreWindow.KeyDown += UIManager.HandlerKeyDown;
|
||||
Log.Write("Navigated to main page.");
|
||||
|
||||
Window.Current.CoreWindow.KeyDown += this.HandlerKeyDown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the page is about to be destroyed.
|
||||
/// </summary>
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
Window.Current.CoreWindow.KeyDown -= UIManager.HandlerKeyDown;
|
||||
Window.Current.CoreWindow.KeyDown -= this.HandlerKeyDown;
|
||||
}
|
||||
|
||||
private void buttonEditMode_Click(object sender, RoutedEventArgs e)
|
||||
#endregion
|
||||
|
||||
#region UI: Buttons
|
||||
/// <summary>
|
||||
/// Handles the edit button, going into the editor.
|
||||
/// </summary>
|
||||
private void ButtonEditMode_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as ToggleButton;
|
||||
if (button == null) return;
|
||||
|
||||
bool isChecked = (button.IsChecked.HasValue && button.IsChecked.Value);
|
||||
|
||||
// Fix togglebuton style bug
|
||||
VisualStateManager.GoToState(button, isChecked ? "Checked" : "Unchecked", false);
|
||||
|
||||
// Change visibility of thumbs
|
||||
if (isChecked) UIManager.EnterEdit();
|
||||
else UIManager.ExitEdit();
|
||||
Frame.Navigate(typeof(EditorPage), DataController.CurrentLayouts.Items[CurrentLayout]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the animations enabled toggle button.
|
||||
/// </summary>
|
||||
private void buttonAnimations_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as ToggleButton;
|
||||
@ -90,8 +330,21 @@ namespace DrumKit
|
||||
VisualStateManager.GoToState(button, isChecked ? "Checked" : "Unchecked", false);
|
||||
|
||||
// Change animation setting
|
||||
DataManager.Settings.Animations = isChecked;
|
||||
DataController.Settings.Animations = isChecked;
|
||||
|
||||
// Save modified setting
|
||||
DataController.SaveSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Goes to application settings.
|
||||
/// </summary>
|
||||
private void ButtonSettings_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(SettingsPage), this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
108
DrumKit/UI/Settings/DrumkitsSettingsControl.xaml
Normal file
108
DrumKit/UI/Settings/DrumkitsSettingsControl.xaml
Normal file
@ -0,0 +1,108 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.DrumkitsSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="321.429"
|
||||
d:DesignWidth="696.617">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Common/TextButtonStyles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
|
||||
<DataTemplate x:Key="DrumkitListDataTemplate">
|
||||
<Grid Name="theGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Left thing -->
|
||||
<Border Name="orangeBorder"
|
||||
Grid.Column="0" Grid.RowSpan="3"
|
||||
Background="OrangeRed" Width="10" />
|
||||
|
||||
<!--<Image MinWidth="10"
|
||||
Source="{Binding Thumbnail}" />-->
|
||||
|
||||
<!-- Name -->
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="15,2,15,0"
|
||||
FontSize="15.3"
|
||||
Style="{StaticResource MyTextBoxStyle}"
|
||||
IsReadOnly="True"
|
||||
Text="{Binding Name}"
|
||||
TextChanged="NameTextChanged"/>
|
||||
|
||||
<!-- Description -->
|
||||
<TextBox Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" Margin="15,0,15,2"
|
||||
Style="{StaticResource MyTextBoxStyle}"
|
||||
Text="{Binding Description}"
|
||||
TextChanged="DescriptionTextChanged"
|
||||
FontSize="13"
|
||||
FontStyle="Italic"
|
||||
IsReadOnly="True"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="Wrap"
|
||||
Height="80" />
|
||||
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="ListViewStretchItemStyle" TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Drumkit list -->
|
||||
<ListView Name="listDrumkits"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
ItemTemplate="{StaticResource DrumkitListDataTemplate}"
|
||||
ItemContainerStyle="{StaticResource ListViewStretchItemStyle}"
|
||||
SelectionMode="Single" >
|
||||
|
||||
</ListView>
|
||||
|
||||
<ProgressRing
|
||||
Name="progressRing"
|
||||
Foreground="White"
|
||||
Width="50" Height="50" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal">
|
||||
<!--<Button Style="{StaticResource MyButtonStyle}" Click="ButtonCreate_Click">Create</Button>-->
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonImport_Click">Import</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonExport_Click">Export</Button>
|
||||
<Border Width="20" />
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonDelete_Click">Delete</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonSetCurrent_Clicked">Set current</Button>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
319
DrumKit/UI/Settings/DrumkitsSettingsControl.xaml.cs
Normal file
319
DrumKit/UI/Settings/DrumkitsSettingsControl.xaml.cs
Normal file
@ -0,0 +1,319 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Notifications;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class DrumkitsSettingsControl : UserControl
|
||||
{
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Creates a new instance of DrumkitsSettingsControl
|
||||
/// </summary>
|
||||
public DrumkitsSettingsControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Loaded += DrumkitsSettingsControl_Loaded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads drumkit list at startup
|
||||
/// </summary>
|
||||
void DrumkitsSettingsControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReloadDrumkits();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reload drumkit list
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the list of drumkits from the data controller
|
||||
/// </summary>
|
||||
async void ReloadDrumkits()
|
||||
{
|
||||
// Remove previous stuff
|
||||
this.listDrumkits.Items.Clear();
|
||||
|
||||
// Add new stuff
|
||||
foreach (var i in DataController.AvailableDrumkits)
|
||||
this.listDrumkits.Items.Add(i.Value);
|
||||
|
||||
// Wait containers to be generated
|
||||
await System.Threading.Tasks.Task.Delay(50);
|
||||
|
||||
// Update visual stuff
|
||||
foreach (var i in this.listDrumkits.Items)
|
||||
{
|
||||
var it = i as Drumkit;
|
||||
|
||||
// Is current?
|
||||
if (DataController.Settings.CurrentKit == it.Name)
|
||||
{
|
||||
// Get border and grid
|
||||
var container = listDrumkits.ItemContainerGenerator.ContainerFromItem(it) as FrameworkElement;
|
||||
Border b = UIHelper.FindChildByName(container, "orangeBorder") as Border;
|
||||
Grid g = UIHelper.FindChildByName(container, "theGrid") as Grid;
|
||||
|
||||
// Change look
|
||||
if (b != null) b.Background = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0x78, 0x33));
|
||||
if (g != null) g.Background = new SolidColorBrush(Color.FromArgb(0x1f, 0xff, 0xef, 0xdf));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Handlers: Text boxes
|
||||
/// <summary>
|
||||
/// Handles drumkit name change
|
||||
/// </summary>
|
||||
private void NameTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
var drumkit = (sender as FrameworkElement).DataContext as Drumkit;
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles drumkit description change
|
||||
/// </summary>
|
||||
private void DescriptionTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
var drumkit = (sender as FrameworkElement).DataContext as Drumkit;
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Handlers: Buttons
|
||||
/// <summary>
|
||||
/// Handles the Create button
|
||||
/// </summary>
|
||||
private void ButtonCreate_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Import button
|
||||
/// </summary>
|
||||
private async void ButtonImport_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Error handling
|
||||
string error = null;
|
||||
|
||||
// Create file picker
|
||||
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
|
||||
picker.CommitButtonText = "Select drum package";
|
||||
picker.FileTypeFilter.Add(".tar");
|
||||
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Downloads;
|
||||
|
||||
// Pick a tarball
|
||||
var tarball = await picker.PickSingleFileAsync();
|
||||
|
||||
if (tarball == null)
|
||||
return;
|
||||
|
||||
// Enable progress ring
|
||||
progressRing.IsActive = true;
|
||||
|
||||
// See if it works
|
||||
try
|
||||
{
|
||||
await DataController.InstallDrumkit(tarball);
|
||||
ReloadDrumkits();
|
||||
}
|
||||
|
||||
catch (Repository.RepositoryException ex)
|
||||
{
|
||||
error = "A drumkit package with the same name already exists!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
error = "The selected file is not a valid drumkit package!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (IOException ex)
|
||||
{
|
||||
error = "The selected file is not a valid drumkit package!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "An unexpected error occured while importing the drumkit package!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
// Disable progress ring
|
||||
progressRing.IsActive = false;
|
||||
|
||||
// Show error if any occured
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
MessageDialog err = new MessageDialog(error, "An error occured!");
|
||||
await err.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Delete button
|
||||
/// </summary>
|
||||
private async void ButtonDelete_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Get the selected drumkit
|
||||
Drumkit selected = listDrumkits.SelectedItem as Drumkit;
|
||||
string error = null;
|
||||
|
||||
// Try to delete
|
||||
if (selected != null)
|
||||
try
|
||||
{
|
||||
await DataController.RemoveDrumkit(selected.Name);
|
||||
ReloadDrumkits();
|
||||
}
|
||||
|
||||
catch (ControllerException ex)
|
||||
{
|
||||
error = "There has to be at least one drumkit remaining!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
error = "Cannot delete the currently loaded drumkit!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "An unexpected error occured while deleting the drumkit!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
// Show error if any occured
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
MessageDialog err = new MessageDialog(error, "An error occured!");
|
||||
await err.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Export button
|
||||
/// </summary>
|
||||
private async void ButtonExport_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Variables
|
||||
Drumkit selected = listDrumkits.SelectedItem as Drumkit;
|
||||
string error = null;
|
||||
|
||||
// Make sure there is something selected
|
||||
if (selected == null) return;
|
||||
|
||||
// Pick a file
|
||||
Windows.Storage.Pickers.FileSavePicker picker = new Windows.Storage.Pickers.FileSavePicker();
|
||||
picker.CommitButtonText = "Export drum package";
|
||||
picker.FileTypeChoices.Add("Tarball", new string[] { ".tar" } );
|
||||
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
|
||||
var file = await picker.PickSaveFileAsync();
|
||||
|
||||
if (file == null) return;
|
||||
|
||||
// Enable progress ring
|
||||
progressRing.IsActive = true;
|
||||
|
||||
// See if it works
|
||||
try {
|
||||
await DataController.ExportDrumkit(selected.Name, file);
|
||||
}
|
||||
|
||||
catch (IOException ex)
|
||||
{
|
||||
error = "An unexpected error occured while exporting the drumkit package!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = "An unexpected error occured while exporting the drumkit package!";
|
||||
Log.Except(ex);
|
||||
}
|
||||
|
||||
// Disable progress ring
|
||||
progressRing.IsActive = false;
|
||||
|
||||
// Show error if any occured
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
MessageDialog err = new MessageDialog(error, "An error occured!");
|
||||
await err.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the SetCurrent button
|
||||
/// </summary>
|
||||
private async void ButtonSetCurrent_Clicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var drumkit = listDrumkits.SelectedItem as Drumkit;
|
||||
|
||||
if (drumkit != null && drumkit.Name != DataController.Settings.CurrentKit)
|
||||
{
|
||||
// Change drumkit
|
||||
DataController.Settings.CurrentKit = drumkit.Name;
|
||||
DataController.SaveSettings();
|
||||
|
||||
// Reload list
|
||||
ReloadDrumkits();
|
||||
|
||||
// Notify that the application needs to be restarted
|
||||
MessageDialog dialog = new MessageDialog("The application needs to be restarted in " +
|
||||
"order to change the current drumkit. If not restarted now, the selected drumkit " +
|
||||
"will be loaded the next time the application is started. ", "Application restart required");
|
||||
|
||||
dialog.Commands.Add(new UICommand("Restart application", new UICommandInvokedHandler(UICommandRestartHandler)));
|
||||
dialog.Commands.Add(new UICommand("Close"));
|
||||
dialog.DefaultCommandIndex = 1;
|
||||
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI Command that restarts the application, when current drumkit changes
|
||||
/// </summary>
|
||||
private void UICommandRestartHandler(Windows.UI.Popups.IUICommand cmd)
|
||||
{
|
||||
if (Window.Current.Content is Frame)
|
||||
{
|
||||
Frame frame = (Frame)Window.Current.Content;
|
||||
frame.Navigate(typeof(LoadingPage), "drumkitchange");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
164
DrumKit/UI/Settings/DrumsSettingsControl.xaml
Normal file
164
DrumKit/UI/Settings/DrumsSettingsControl.xaml
Normal file
@ -0,0 +1,164 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.DrumsSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="400"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Common/TextButtonStyles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
|
||||
<DataTemplate x:Key="DrumsListDataTemplate">
|
||||
<Grid Name="theGrid"
|
||||
MinWidth="380">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Left thing -->
|
||||
<Border Name="yellowBorder"
|
||||
Grid.Column="0" Grid.RowSpan="3"
|
||||
Background="Yellow" Width="10" />
|
||||
|
||||
<!-- Thumbnail -->
|
||||
<Image Grid.Row="0" Grid.RowSpan="2"
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Width="60" Height="60"
|
||||
Source="{Binding LoadedImageSource}"
|
||||
Stretch="Uniform" />
|
||||
|
||||
<!-- Name -->
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="15,2,15,0"
|
||||
FontSize="15.3"
|
||||
Style="{StaticResource MyTextBoxStyle}"
|
||||
Text="{Binding Name}"
|
||||
IsReadOnly="True" />
|
||||
|
||||
<!-- Configuration -->
|
||||
<Grid
|
||||
Grid.Column="1" Grid.Row="1" Margin="15,0,15,2">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ToggleButton
|
||||
Name="toggleEnabled" Grid.Column="0"
|
||||
Margin="0,-4,20,0" Padding="5,1"
|
||||
Content="Enabled"
|
||||
Click="ToggleEnabled_Click" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource TitleTextStyle}"
|
||||
Text="Key:" />
|
||||
|
||||
<TextBox
|
||||
Grid.Column="2"
|
||||
Name="textKey"
|
||||
Style="{StaticResource MyTextBoxStyle}"
|
||||
KeyUp="TextKey_KeyUp" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Column="1" Grid.Row="2" Margin="15,2,15,0">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Style="{StaticResource TitleTextStyle}"
|
||||
Text="Volume left:" />
|
||||
|
||||
<Slider Name="sliderVolumeL"
|
||||
Grid.Column="1"
|
||||
Margin="5,-8,5,0"
|
||||
Height="34"
|
||||
Minimum="0" Maximum="1"
|
||||
StepFrequency=".01"
|
||||
ValueChanged="sliderVolumeL_ValueChanged"/>
|
||||
|
||||
<TextBlock
|
||||
Margin="10,0,0,0"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource TitleTextStyle}"
|
||||
Text="Right:" />
|
||||
|
||||
<Slider Name="sliderVolumeR"
|
||||
Grid.Column="3"
|
||||
Margin="5,-8,5,0"
|
||||
Height="34"
|
||||
Minimum="0" Maximum="1"
|
||||
StepFrequency=".01"
|
||||
ValueChanged="sliderVolumeR_ValueChanged" />
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="GridViewStretchItemStyle" TargetType="GridViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Drums list -->
|
||||
<GridView Name="listDrums"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
ItemTemplate="{StaticResource DrumsListDataTemplate}"
|
||||
ItemContainerStyle="{StaticResource GridViewStretchItemStyle}"
|
||||
SelectionMode="Single" >
|
||||
<local:Drum ImageSource="/Assets/bg.png" Id="adda" Name="Hello world!" />
|
||||
</GridView>
|
||||
|
||||
<!-- Buttons -->
|
||||
<!--<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal">
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonCreate_Click">Create</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonDelete_Click">Delete</Button>
|
||||
</StackPanel>-->
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
236
DrumKit/UI/Settings/DrumsSettingsControl.xaml.cs
Normal file
236
DrumKit/UI/Settings/DrumsSettingsControl.xaml.cs
Normal file
@ -0,0 +1,236 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class DrumsSettingsControl : UserControl
|
||||
{
|
||||
#region Initialization
|
||||
/// <summary>
|
||||
/// Creates a new instance of DrumsSettingsControl
|
||||
/// </summary>
|
||||
public DrumsSettingsControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Loaded += DrumsSettingsControl_Loaded;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Loads drum list at startup
|
||||
/// </summary>
|
||||
void DrumsSettingsControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReloadDrums();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reloads the list of drums
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the list of drums
|
||||
/// </summary>
|
||||
async void ReloadDrums()
|
||||
{
|
||||
// Clear previous stuff
|
||||
listDrums.Items.Clear();
|
||||
|
||||
// Add new stuff
|
||||
foreach (var i in DataController.CurrentDrumkit.Drums)
|
||||
this.listDrums.Items.Add(i.Value);
|
||||
|
||||
// Wait for containers to be generated
|
||||
await System.Threading.Tasks.Task.Delay(50);
|
||||
|
||||
// Update visual stuff
|
||||
DrumConfig config = null;
|
||||
foreach (var i in this.listDrums.Items)
|
||||
{
|
||||
// Get drum and configuration
|
||||
var drum = i as Drum;
|
||||
if (drum != null)
|
||||
DataController.CurrentConfig.Drums.TryGetValue(drum.Id, out config);
|
||||
|
||||
// No drum, no configuration?
|
||||
if (drum == null || config == null)
|
||||
continue;
|
||||
|
||||
// Set up other properties
|
||||
var container = listDrums.ItemContainerGenerator.ContainerFromItem(i) as FrameworkElement;
|
||||
|
||||
ToggleButton enabled = UIHelper.FindChildByName(container, "toggleEnabled") as ToggleButton;
|
||||
if (enabled != null) enabled.IsChecked = config.IsEnabled;
|
||||
|
||||
Slider volumeL = UIHelper.FindChildByName(container, "sliderVolumeL") as Slider;
|
||||
if (volumeL != null) volumeL.Value = config.VolumeL;
|
||||
|
||||
Slider volumeR = UIHelper.FindChildByName(container, "sliderVolumeR") as Slider;
|
||||
if (volumeR != null) volumeR.Value = config.VolumeR;
|
||||
}
|
||||
|
||||
ReloadKeys();
|
||||
}
|
||||
|
||||
void ReloadKeys()
|
||||
{
|
||||
DrumConfig config = null;
|
||||
foreach (var i in this.listDrums.Items)
|
||||
{
|
||||
// Get drum and configuration
|
||||
var drum = i as Drum;
|
||||
if (drum != null)
|
||||
DataController.CurrentConfig.Drums.TryGetValue(drum.Id, out config);
|
||||
|
||||
// No drum, no configuration?
|
||||
if (drum == null || config == null)
|
||||
continue;
|
||||
|
||||
// Set up key
|
||||
var container = listDrums.ItemContainerGenerator.ContainerFromItem(i) as FrameworkElement;
|
||||
TextBox key = UIHelper.FindChildByName(container, "textKey") as TextBox;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
if (Enum.IsDefined(typeof(VirtualKey), config.Key))
|
||||
{
|
||||
// Get name
|
||||
string text = Enum.GetName(typeof(VirtualKey), config.Key);
|
||||
|
||||
// Prettify the name
|
||||
if (text.StartsWith("Number"))
|
||||
text = text.Substring("Number".Length);
|
||||
|
||||
text = System.Text.RegularExpressions.Regex.Replace(text, "([a-z])([A-Z])", "${1} ${2}");
|
||||
|
||||
// Set the text
|
||||
key.Text = text;
|
||||
}
|
||||
|
||||
else key.Text = string.Format("Unnamed ({0})", (int)config.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Handlers: Items
|
||||
|
||||
/// <summary>
|
||||
/// Handles "Landscape" toggle button.
|
||||
/// </summary>
|
||||
private void ToggleEnabled_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Get drum object
|
||||
var button = sender as ToggleButton;
|
||||
var drum = (sender as FrameworkElement).DataContext as Drum;
|
||||
|
||||
// Change enabled property
|
||||
if (drum != null && DataController.CurrentConfig.Drums.ContainsKey(drum.Id))
|
||||
{
|
||||
DataController.CurrentConfig.Drums[drum.Id].IsEnabled = button.IsChecked.HasValue && button.IsChecked.Value;
|
||||
|
||||
DataController.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the "key press" event in the textbox
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void TextKey_KeyUp(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
// Get drum object
|
||||
var text = sender as TextBox;
|
||||
var drum = (sender as FrameworkElement).DataContext as Drum;
|
||||
|
||||
// Set key
|
||||
if (text != null && drum != null && DataController.CurrentConfig.Drums.ContainsKey(drum.Id))
|
||||
{
|
||||
// Remove duplicates
|
||||
RemoveKeys(e.Key, drum.Id);
|
||||
|
||||
// Set key
|
||||
DataController.CurrentConfig.Drums[drum.Id].Key = e.Key;
|
||||
|
||||
// Display
|
||||
ReloadKeys();
|
||||
|
||||
// Save
|
||||
DataController.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void sliderVolumeL_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
// Get drum object
|
||||
var slider = sender as Slider;
|
||||
var drum = (sender as FrameworkElement).DataContext as Drum;
|
||||
|
||||
// Set value
|
||||
if (slider != null && drum != null && DataController.CurrentConfig.Drums.ContainsKey(drum.Id))
|
||||
{
|
||||
DataController.CurrentConfig.Drums[drum.Id].VolumeL = e.NewValue;
|
||||
DataController.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void sliderVolumeR_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
// Get drum object
|
||||
var slider = sender as Slider;
|
||||
var drum = (sender as FrameworkElement).DataContext as Drum;
|
||||
|
||||
// Set value
|
||||
if (slider != null && drum != null && DataController.CurrentConfig.Drums.ContainsKey(drum.Id))
|
||||
{
|
||||
DataController.CurrentConfig.Drums[drum.Id].VolumeR = e.NewValue;
|
||||
DataController.SaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
/// <summary>
|
||||
/// Sets the keyboart shortcut to None for all the drums that have this key.
|
||||
/// </summary>
|
||||
/// <param name="key">The keyboard shortcut</param>
|
||||
private void RemoveKeys(VirtualKey key, string exception_id=null)
|
||||
{
|
||||
// See if any other drum has the same key
|
||||
foreach (var i in DataController.CurrentConfig.Drums)
|
||||
if (i.Value.Key == key && i.Key != exception_id)
|
||||
{
|
||||
// Set to none
|
||||
i.Value.Key = VirtualKey.None;
|
||||
|
||||
// Get drum
|
||||
var drum = DataController.CurrentDrumkit.Drums[i.Key];
|
||||
|
||||
// Get key text box
|
||||
var container = listDrums.ItemContainerGenerator.ContainerFromItem(drum) as FrameworkElement;
|
||||
TextBox keytxt = UIHelper.FindChildByName(container, "textKey") as TextBox;
|
||||
keytxt.Text = Enum.GetName(typeof(VirtualKey), i.Value.Key);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
26
DrumKit/UI/Settings/ExperimentsSettingsControl.xaml
Normal file
26
DrumKit/UI/Settings/ExperimentsSettingsControl.xaml
Normal file
@ -0,0 +1,26 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.ExperimentsSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Common/TextButtonStyles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Canvas Name="canvas">
|
||||
<StackPanel>
|
||||
<TextBox Style="{StaticResource MyTextBoxStyle}" Width="200" Text="Hello world!"/>
|
||||
</StackPanel>
|
||||
|
||||
</Canvas>
|
||||
</UserControl>
|
31
DrumKit/UI/Settings/ExperimentsSettingsControl.xaml.cs
Normal file
31
DrumKit/UI/Settings/ExperimentsSettingsControl.xaml.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class ExperimentsSettingsControl : UserControl
|
||||
{
|
||||
public ExperimentsSettingsControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
DrumPlayUI ui = new DrumPlayUI(DataController.CurrentDrumkit.Drums.First().Value);
|
||||
canvas.Children.Add(ui);
|
||||
Canvas.SetTop(ui, 100);
|
||||
Canvas.SetLeft(ui, 300);
|
||||
}
|
||||
}
|
||||
}
|
174
DrumKit/UI/Settings/GeneralSettingsControl.xaml
Normal file
174
DrumKit/UI/Settings/GeneralSettingsControl.xaml
Normal file
@ -0,0 +1,174 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.GeneralSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="635.463"
|
||||
d:DesignWidth="1075.987">
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.Resources>
|
||||
|
||||
<Style x:Key="MyTitleTextStyle" TargetType="TextBlock" BasedOn="{StaticResource TitleTextStyle}">
|
||||
<Setter Property="Margin" Value="20,24,2,2" />
|
||||
<Setter Property="Foreground" Value="#59FFFF" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyItemTextStyle" TargetType="TextBlock" BasedOn="{StaticResource ItemTextStyle}">
|
||||
<Setter Property="Margin" Value="2,12,2,2" />
|
||||
</Style>
|
||||
|
||||
</Grid.Resources>
|
||||
|
||||
<!-- About section -->
|
||||
<TextBlock Style="{StaticResource MyTitleTextStyle}"
|
||||
Grid.Row="0" Margin="20,4,2,2">
|
||||
About</TextBlock>
|
||||
|
||||
<!-- About section: Website -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="1" Margin="2,12,2,2">
|
||||
Drumkit website</TextBlock>
|
||||
|
||||
<Button Name="buttonWebsite"
|
||||
Style="{StaticResource TextButtonStyle}"
|
||||
Grid.Row="1" Grid.Column="1" VerticalAlignment="Bottom">
|
||||
drumkit8.blogspot.com</Button>
|
||||
|
||||
<!-- About section: Support -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="2" Margin="2,12,2,2">
|
||||
Support</TextBlock>
|
||||
|
||||
<Button Name="buttonSupport"
|
||||
Style="{StaticResource TextButtonStyle}"
|
||||
Grid.Row="2" Grid.Column="1" VerticalAlignment="Bottom">
|
||||
chibicitiberiu@outlook.com</Button>
|
||||
|
||||
|
||||
<!-- About section: Version -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="3" Margin="2,12,2,2">
|
||||
Version</TextBlock>
|
||||
|
||||
<TextBlock Name="textVersion"
|
||||
Grid.Row="3" Grid.Column="1" VerticalAlignment="Bottom"
|
||||
Margin="0,2,2,2"
|
||||
Style="{StaticResource BodyTextStyle}" >
|
||||
1.0
|
||||
</TextBlock>
|
||||
|
||||
|
||||
<!-- Sound section -->
|
||||
<TextBlock Style="{StaticResource MyTitleTextStyle}"
|
||||
Grid.Row="6">
|
||||
Sound</TextBlock>
|
||||
|
||||
<!-- Sound section: Master volume -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="7" Margin="2,7,2,2">
|
||||
Master volume</TextBlock>
|
||||
|
||||
<Slider Name="masterVolumeSlider"
|
||||
Grid.Row="7" Grid.Column="1"
|
||||
Minimum="0" Maximum="100"
|
||||
StepFrequency="1"
|
||||
SmallChange=".05" LargeChange=".2"
|
||||
Width="100" Height="48"
|
||||
HorizontalAlignment="Left"/>
|
||||
|
||||
<!-- Sound section: Polyphony -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="8" Margin="2,7,2,2">
|
||||
Polyphony*</TextBlock>
|
||||
|
||||
<Slider Name="polyphonySlider"
|
||||
Grid.Row="8" Grid.Column="1"
|
||||
Minimum="1" Maximum="256"
|
||||
StepFrequency="1"
|
||||
SmallChange="1" LargeChange="5"
|
||||
Width="100" Height="48"
|
||||
HorizontalAlignment="Left"/>
|
||||
|
||||
<!-- Interface section -->
|
||||
<TextBlock Style="{StaticResource MyTitleTextStyle}"
|
||||
Grid.Row="9">
|
||||
Interface</TextBlock>
|
||||
|
||||
<!-- Interface section: Animations -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="10" Margin="2,12,2,2">
|
||||
Animations</TextBlock>
|
||||
|
||||
<ToggleSwitch Name="animationsToggle"
|
||||
Grid.Row="10" Grid.Column="1"/>
|
||||
|
||||
<!-- Interface section: Key bindings -->
|
||||
<!--<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="11" Margin="2,12,2,2">
|
||||
Display key bindings</TextBlock>
|
||||
|
||||
<ToggleSwitch Name="keyBindingsToggle"
|
||||
Grid.Row="11" Grid.Column="1"/>-->
|
||||
|
||||
<!-- Miscellaneous section -->
|
||||
<TextBlock Style="{StaticResource MyTitleTextStyle}"
|
||||
Grid.Row="12">
|
||||
Miscellaneous</TextBlock>
|
||||
|
||||
<!-- Miscellaneous section: Debugging mode -->
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="13" Margin="2,12,2,2">
|
||||
Debugging mode</TextBlock>
|
||||
|
||||
<ToggleSwitch Name="debuggingModeToggle"
|
||||
Grid.Row="13" Grid.Column="1"/>
|
||||
|
||||
<TextBlock Style="{StaticResource ItemTextStyle}"
|
||||
Grid.Row="14" Margin="2,12,2,2">
|
||||
Factory reset*</TextBlock>
|
||||
|
||||
<Button Name="buttonReset"
|
||||
Style="{StaticResource TextButtonStyle}"
|
||||
Grid.Row="14" Grid.Column="1" VerticalAlignment="Bottom">
|
||||
Reset</Button>
|
||||
|
||||
<!-- Notes section -->
|
||||
|
||||
<TextBlock Grid.Row="100" Style="{StaticResource MyItemTextStyle}"
|
||||
FontSize="11"
|
||||
Foreground="Silver">
|
||||
* Will be applied after the application is restarted.
|
||||
</TextBlock>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
120
DrumKit/UI/Settings/GeneralSettingsControl.xaml.cs
Normal file
120
DrumKit/UI/Settings/GeneralSettingsControl.xaml.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using System.Reflection;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace DrumKit
|
||||
{
|
||||
public sealed partial class GeneralSettingsControl : UserControl
|
||||
{
|
||||
public GeneralSettingsControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.LoadSettings();
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
// Version
|
||||
var version = typeof(GeneralSettingsControl).GetTypeInfo().Assembly.GetName().Version;
|
||||
this.textVersion.Text = String.Format("{0}.{1}", version.Major, version.Minor);
|
||||
|
||||
// Other
|
||||
this.masterVolumeSlider.Value = DataController.MasterVolume * 100;
|
||||
this.polyphonySlider.Value = DataController.Settings.Polyphony;
|
||||
this.animationsToggle.IsOn = DataController.Settings.Animations;
|
||||
//this.keyBindingsToggle.IsOn = DataController.Settings.ShowKeyBindings;
|
||||
this.debuggingModeToggle.IsOn = DataController.Settings.DebugMode;
|
||||
|
||||
// Set up events
|
||||
masterVolumeSlider.ValueChanged += masterVolumeSlider_ValueChanged;
|
||||
polyphonySlider.ValueChanged += polyphonySlider_ValueChanged;
|
||||
animationsToggle.Toggled += animationsToggle_Toggled;
|
||||
//keyBindingsToggle.Toggled += keyBindingsToggle_Toggled;
|
||||
buttonWebsite.Click += buttonWebsite_Click;
|
||||
buttonSupport.Click += buttonSupport_Click;
|
||||
buttonReset.Click += buttonReset_Click;
|
||||
debuggingModeToggle.Toggled += debuggingModeToggle_Toggled;
|
||||
}
|
||||
|
||||
private void masterVolumeSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
DataController.MasterVolume = Convert.ToSingle(masterVolumeSlider.Value) / 100.0f;
|
||||
DataController.SaveSettings();
|
||||
}
|
||||
|
||||
void polyphonySlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
DataController.Settings.Polyphony = Convert.ToInt32(polyphonySlider.Value);
|
||||
DataController.SaveSettings();
|
||||
}
|
||||
|
||||
private void animationsToggle_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataController.Settings.Animations = this.animationsToggle.IsOn;
|
||||
DataController.SaveSettings();
|
||||
}
|
||||
|
||||
//private void keyBindingsToggle_Toggled(object sender, RoutedEventArgs e)
|
||||
//{
|
||||
// DataController.Settings.ShowKeyBindings = this.keyBindingsToggle.IsOn;
|
||||
// DataController.SaveSettings();
|
||||
//}
|
||||
|
||||
private async void buttonWebsite_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Windows.System.Launcher.LaunchUriAsync(new Uri("http://drumkit8.blogspot.com/"));
|
||||
}
|
||||
|
||||
private async void buttonSupport_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await Windows.System.Launcher.LaunchUriAsync(new Uri("mailto:chibicitiberiu@outlook.com"));
|
||||
}
|
||||
|
||||
private async void buttonReset_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Notify that the application needs to be restarted
|
||||
MessageDialog dialog = new MessageDialog("The application needs to be restarted in " +
|
||||
"order to reset to factory settings. Note that every customisation will be deleted.",
|
||||
"Application restart required");
|
||||
|
||||
dialog.Commands.Add(new UICommand("Continue", new UICommandInvokedHandler(UICommandFactoryResetHandler)));
|
||||
dialog.Commands.Add(new UICommand("Cancel"));
|
||||
dialog.DefaultCommandIndex = 1;
|
||||
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI Command that restarts the application, when current drumkit changes
|
||||
/// </summary>
|
||||
private void UICommandFactoryResetHandler(Windows.UI.Popups.IUICommand cmd)
|
||||
{
|
||||
if (Window.Current.Content is Frame)
|
||||
{
|
||||
Frame frame = (Frame) Window.Current.Content;
|
||||
frame.Navigate(typeof(LoadingPage), "reset");
|
||||
}
|
||||
}
|
||||
|
||||
private void debuggingModeToggle_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DataController.Settings.DebugMode = this.debuggingModeToggle.IsOn;
|
||||
DataController.SaveSettings();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
92
DrumKit/UI/Settings/LayoutsSettingsControl.xaml
Normal file
92
DrumKit/UI/Settings/LayoutsSettingsControl.xaml
Normal file
@ -0,0 +1,92 @@
|
||||
<UserControl
|
||||
x:Class="DrumKit.LayoutsSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:DrumKit"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<DataTemplate x:Key="DrumkitListDataTemplate">
|
||||
<Grid Name="theGrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Left thing -->
|
||||
<Border Name="greenBorder"
|
||||
Grid.Column="0" Grid.RowSpan="3"
|
||||
Background="GreenYellow" Width="10" />
|
||||
|
||||
<!-- Name -->
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="15,2,15,0"
|
||||
FontSize="15.3"
|
||||
Style="{StaticResource MyTextBoxStyle}"
|
||||
Text="{Binding Name}"
|
||||
TextChanged="NameTextChanged" />
|
||||
|
||||
<!-- Description -->
|
||||
<StackPanel Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" Margin="15,0,15,2"
|
||||
Orientation="Horizontal">
|
||||
<ToggleButton Name="toggleLandscape" Click="ToggleLandscape_Click">Landscape</ToggleButton>
|
||||
<ToggleButton Name="togglePortrait" Click="TogglePortrait_Click">Portrait</ToggleButton>
|
||||
<ToggleButton Name="toggleFilled" Click="ToggleFilled_Click">Filled</ToggleButton>
|
||||
<ToggleButton Name="toggleSnapped" Click="ToggleSnapped_Click">Snapped</ToggleButton>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="ListViewStretchItemStyle" TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Drumkit list -->
|
||||
<ListView Name="listLayouts"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
ItemTemplate="{StaticResource DrumkitListDataTemplate}"
|
||||
ItemContainerStyle="{StaticResource ListViewStretchItemStyle}"
|
||||
SelectionMode="Single" >
|
||||
|
||||
<local:DrumkitLayout IsDefault="True" Name="Hello world" TargetViewSerialize="All" />
|
||||
|
||||
<TextBlock>Hello world!</TextBlock>
|
||||
|
||||
</ListView>
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal">
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonCreate_Click">Create</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonEdit_Click">Edit</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonDelete_Click">Delete</Button>
|
||||
<Button Style="{StaticResource MyButtonStyle}" Click="ButtonToggleActive_Click">Toggle active</Button>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user