mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Added changelog display
Implemented audio visualization layer sensitivity and fade speed
This commit is contained in:
parent
2abe4ec93b
commit
3739ffad03
@ -13,14 +13,6 @@ namespace Artemis
|
||||
{
|
||||
public App()
|
||||
{
|
||||
//using (var mgr = UpdateManager.GitHubUpdateManager("https://github.com/SpoinkyNL/Artemis"))
|
||||
//using (var mgr = new UpdateManager("C:\\Users\\Robert\\Desktop\\Artemis builds\\squirrel_test"))
|
||||
//{
|
||||
// SquirrelAwareApp.HandleEvents(
|
||||
// onInitialInstall: v => mgr.CreateShortcutForThisExe(),
|
||||
// onAppUpdate: v => Updater.AppUpdate(mgr),
|
||||
// onAppUninstall: v => Updater.AppUninstall(mgr));
|
||||
//}
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@ -525,7 +525,6 @@
|
||||
<Compile Include="Utilities\Memory\Win32.cs" />
|
||||
<Compile Include="Utilities\ParentChild\ChildItemCollection.cs" />
|
||||
<Compile Include="Utilities\ParentChild\IChildItem.cs" />
|
||||
<Compile Include="Utilities\ShellLink.cs" />
|
||||
<Compile Include="Utilities\StickyValue.cs" />
|
||||
<Compile Include="Utilities\Updater.cs" />
|
||||
<Compile Include="ViewModels\Abstract\BaseViewModel.cs" />
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
@ -13,7 +12,6 @@ using Artemis.ViewModels;
|
||||
using Caliburn.Micro;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
using LogManager = NLog.LogManager;
|
||||
|
||||
namespace Artemis
|
||||
{
|
||||
@ -39,14 +37,14 @@ namespace Artemis
|
||||
var e = ctx.EventArgs as MouseEventArgs;
|
||||
|
||||
// If there is an image control, get the scaled position
|
||||
if (img != null && e != null)
|
||||
if ((img != null) && (e != null))
|
||||
{
|
||||
var position = e.GetPosition(img);
|
||||
return (int) (img.Source.Width*(position.X/img.ActualWidth));
|
||||
}
|
||||
|
||||
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
|
||||
if (e != null && input != null)
|
||||
if ((e != null) && (input != null))
|
||||
return e.GetPosition(input).X;
|
||||
|
||||
// Return 0 if no processing could be done
|
||||
@ -59,14 +57,14 @@ namespace Artemis
|
||||
var e = ctx.EventArgs as MouseEventArgs;
|
||||
|
||||
// If there is an image control, get the scaled position
|
||||
if (img != null && e != null)
|
||||
if ((img != null) && (e != null))
|
||||
{
|
||||
var position = e.GetPosition(img);
|
||||
return (int) (img.Source.Width*(position.Y/img.ActualWidth));
|
||||
}
|
||||
|
||||
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
|
||||
if (e != null && input != null)
|
||||
if ((e != null) && (input != null))
|
||||
return e.GetPosition(input).Y;
|
||||
|
||||
// Return 0 if no processing could be done
|
||||
|
||||
@ -22,21 +22,21 @@
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- Scale -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Margin="10,13,10,10" FontSize="13.333" Text="Scale:"
|
||||
<!-- Volume sensitivity -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Margin="10,13,10,10" FontSize="13.333" Text="Volume sensitivity:"
|
||||
Height="18" VerticalAlignment="Top" />
|
||||
<Slider x:Name="Scale" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top"
|
||||
TickPlacement="None" TickFrequency="2"
|
||||
Value="{Binding Path=LayerModel.Properties.Scale, Mode=TwoWay}" Minimum="2" Maximum="24"
|
||||
SmallChange="2" IsSnapToTickEnabled="True" Margin="10,12,10,2" Height="24" LargeChange="2" />
|
||||
Value="{Binding Path=LayerModel.Properties.Sensitivity, Mode=TwoWay}" Margin="10,12,10,2" Height="24"
|
||||
TickPlacement="BottomRight" TickFrequency="1" Minimum="1" Maximum="10" SmallChange="1"
|
||||
IsSnapToTickEnabled="True" />
|
||||
|
||||
<!-- Animation Speed -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" Margin="10,13,10,10" FontSize="13.333" Text="Animation speed:"
|
||||
<!-- Fade-out speed -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" Margin="10,13,10,10" FontSize="13.333" Text="Fade-out speed:"
|
||||
VerticalAlignment="Top" Height="18" />
|
||||
<Slider x:Name="RotationSpeed" Grid.Row="0" Grid.Column="3" VerticalAlignment="Top"
|
||||
TickPlacement="None" TickFrequency="0.05"
|
||||
Value="{Binding Path=LayerModel.Properties.AnimationSpeed, Mode=TwoWay}" Minimum="0.05" Maximum="3"
|
||||
SmallChange="0" IsSnapToTickEnabled="True" Margin="10,12,10,2" Height="24" />
|
||||
Value="{Binding Path=LayerModel.Properties.FadeSpeed, Mode=TwoWay}" Margin="10,12,10,2"
|
||||
Height="24" TickPlacement="BottomRight" TickFrequency="1" Minimum="1" Maximum="3" SmallChange="1"
|
||||
IsSnapToTickEnabled="True" />
|
||||
|
||||
<!-- Colors -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" x:Name="ShowBrush">
|
||||
@ -50,7 +50,7 @@
|
||||
</StackPanel>
|
||||
|
||||
<!-- Random color -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Margin="10,13,10,10" FontSize="13.333" Text="Random color:"
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Margin="10,13,10,10" FontSize="13.333" Text="Bar direction:"
|
||||
VerticalAlignment="Top" Height="18" />
|
||||
<controls:ToggleSwitch Grid.Row="1" Grid.Column="3" OnLabel="Yes" OffLabel="No"
|
||||
IsChecked="{Binding Path=LayerModel.Properties.RandomColor, Mode=TwoWay}"
|
||||
|
||||
@ -52,7 +52,9 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
var thumbnailRect = new Rect(0, 0, 18, 18);
|
||||
var visual = new DrawingVisual();
|
||||
using (var c = visual.RenderOpen())
|
||||
{
|
||||
c.DrawImage(ImageUtilities.BitmapToBitmapImage(Resources.gif), thumbnailRect);
|
||||
}
|
||||
|
||||
var image = new DrawingImage(visual.Drawing);
|
||||
return image;
|
||||
@ -63,14 +65,31 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
lock (SpectrumData)
|
||||
{
|
||||
foreach (var audioLayer in _audioLayers)
|
||||
{
|
||||
// This is cheating but it ensures that the brush is drawn across the entire main-layer
|
||||
var oldWidth = audioLayer.Properties.Width;
|
||||
var oldHeight = audioLayer.Properties.Height;
|
||||
var oldX = audioLayer.Properties.X;
|
||||
var oldY = audioLayer.Properties.Y;
|
||||
|
||||
audioLayer.Properties.Width = layer.Properties.Width;
|
||||
audioLayer.Properties.Height = layer.Properties.Height;
|
||||
audioLayer.Properties.X = layer.Properties.X;
|
||||
audioLayer.Properties.Y = layer.Properties.Y;
|
||||
audioLayer.LayerType.Draw(audioLayer, c);
|
||||
|
||||
audioLayer.Properties.Width = oldWidth;
|
||||
audioLayer.Properties.Height = oldHeight;
|
||||
audioLayer.Properties.X = oldX;
|
||||
audioLayer.Properties.Y = oldY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
|
||||
{
|
||||
_lines = (int) layerModel.Properties.Width;
|
||||
if (_device == null || isPreview)
|
||||
if ((_device == null) || isPreview)
|
||||
return;
|
||||
|
||||
lock (SpectrumData)
|
||||
@ -90,6 +109,9 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
else
|
||||
height = 0;
|
||||
|
||||
// Apply Sensitivity setting
|
||||
height = height*settings.Sensitivity;
|
||||
|
||||
var newHeight = settings.Height/100.0*height;
|
||||
if (newHeight >= audioLayer.Properties.Height)
|
||||
audioLayer.Properties.Height = newHeight;
|
||||
@ -98,6 +120,9 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
if (audioLayer.Properties.Height < 0)
|
||||
audioLayer.Properties.Height = 0;
|
||||
|
||||
audioLayer.Properties.Brush = layerModel.Properties.Brush;
|
||||
audioLayer.Properties.Contain = false;
|
||||
|
||||
audioLayer.Update(null, false, true);
|
||||
index++;
|
||||
}
|
||||
@ -167,10 +192,8 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
||||
if (b1 <= b0)
|
||||
b1 = b0 + 1;
|
||||
for (; b0 < b1; b0++)
|
||||
{
|
||||
if (peak < e.Result[1 + b0].X)
|
||||
peak = e.Result[1 + b0].X;
|
||||
}
|
||||
var y = (int) (Math.Sqrt(peak)*3*255 - 4);
|
||||
if (y > 255)
|
||||
y = 255;
|
||||
|
||||
@ -52,6 +52,5 @@ using System.Windows;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.3.0.2")]
|
||||
[assembly: AssemblyFileVersion("1.3.0.2")]
|
||||
//[assembly: AssemblyMetadata("SquirrelAwareVersion", "1")]
|
||||
[assembly: AssemblyVersion("1.3.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.0.0")]
|
||||
@ -1,14 +1,12 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Windows;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
using MahApps.Metro;
|
||||
using Newtonsoft.Json;
|
||||
using Squirrel;
|
||||
|
||||
namespace Artemis.Settings
|
||||
{
|
||||
@ -17,6 +15,7 @@ namespace Artemis.Settings
|
||||
public GeneralSettings()
|
||||
{
|
||||
ThemeManager.AddAccent("CorsairYellow", new Uri("pack://application:,,,/Styles/Accents/CorsairYellow.xaml"));
|
||||
ApplyAutorun();
|
||||
}
|
||||
|
||||
[DefaultValue("WindowsProfile")]
|
||||
@ -59,6 +58,8 @@ namespace Artemis.Settings
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public string LogLevel { get; set; }
|
||||
|
||||
public Version LastRanVersion { get; set; }
|
||||
|
||||
public void Save()
|
||||
{
|
||||
SettingsProvider.Save(this);
|
||||
@ -86,17 +87,13 @@ namespace Artemis.Settings
|
||||
|
||||
public void ApplyAutorun()
|
||||
{
|
||||
var startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
|
||||
if (Autorun)
|
||||
using (var mgr = new UpdateManager(""))
|
||||
{
|
||||
var link = (IShellLink) new ShellLink();
|
||||
link.SetPath(Assembly.GetExecutingAssembly().Location);
|
||||
var file = (IPersistFile) link;
|
||||
|
||||
file.Save(startupFolder + @"\Artemis.lnk", false);
|
||||
if (Autorun)
|
||||
mgr.CreateShortcutsForExecutable("Artemis.exe", ShortcutLocation.Startup, false);
|
||||
else
|
||||
mgr.RemoveShortcutsForExecutable("Artemis.exe", ShortcutLocation.Startup);
|
||||
}
|
||||
else if (File.Exists(startupFolder + @"\Artemis.lnk"))
|
||||
File.Delete(startupFolder + @"\Artemis.lnk");
|
||||
}
|
||||
|
||||
public void ApplyTheme()
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Artemis.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a shortcut (.lnk) file.
|
||||
/// Source: http://stackoverflow.com/a/14632782/5015269
|
||||
/// </summary>
|
||||
[ComImport]
|
||||
[Guid("00021401-0000-0000-C000-000000000046")]
|
||||
internal class ShellLink
|
||||
{
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("000214F9-0000-0000-C000-000000000046")]
|
||||
internal interface IShellLink
|
||||
{
|
||||
void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd,
|
||||
int fFlags);
|
||||
|
||||
void GetIDList(out IntPtr ppidl);
|
||||
void SetIDList(IntPtr pidl);
|
||||
void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
|
||||
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
|
||||
void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
|
||||
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
|
||||
void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
|
||||
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
|
||||
void GetHotkey(out short pwHotkey);
|
||||
void SetHotkey(short wHotkey);
|
||||
void GetShowCmd(out int piShowCmd);
|
||||
void SetShowCmd(int iShowCmd);
|
||||
|
||||
void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath,
|
||||
out int piIcon);
|
||||
|
||||
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
|
||||
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
|
||||
void Resolve(IntPtr hwnd, int fFlags);
|
||||
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
||||
}
|
||||
}
|
||||
@ -2,10 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.DAL;
|
||||
using Artemis.Services;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities.Memory;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using Squirrel;
|
||||
|
||||
@ -13,45 +17,108 @@ namespace Artemis.Utilities
|
||||
{
|
||||
public static class Updater
|
||||
{
|
||||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Uses Squirrel to update the application through GitHub
|
||||
/// </summary>
|
||||
public static async void UpdateApp()
|
||||
{
|
||||
// Only update if the user allows it
|
||||
if (!SettingsProvider.Load<GeneralSettings>().AutoUpdate)
|
||||
if (SettingsProvider.Load<GeneralSettings>().AutoUpdate)
|
||||
return;
|
||||
|
||||
_logger.Info("Checking for updates...");
|
||||
// TODO: Remove prerelease before releasing
|
||||
//using (var mgr = UpdateManager.GitHubUpdateManager("https://github.com/SpoinkyNL/Artemis", null, null, null, true))
|
||||
//{
|
||||
// await mgr.Result.UpdateApp();
|
||||
//}
|
||||
|
||||
using (var mgr = new UpdateManager("C:\\Users\\Robert\\Desktop\\Artemis builds\\squirrel_test"))
|
||||
Logger.Info("Checking for updates...");
|
||||
// Pre-release
|
||||
using (var mgr = UpdateManager.GitHubUpdateManager("https://github.com/SpoinkyNL/Artemis", null, null, null, true))
|
||||
// Release
|
||||
// using (var mgr = UpdateManager.GitHubUpdateManager("https://github.com/SpoinkyNL/Artemis"))
|
||||
{
|
||||
await mgr.UpdateApp();
|
||||
try
|
||||
{
|
||||
await mgr.Result.UpdateApp();
|
||||
mgr.Result.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Update check failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AppUpdate(IUpdateManager mgr)
|
||||
/// <summary>
|
||||
/// Checks to see if the program has updated and shows a dialog if so.
|
||||
/// </summary>
|
||||
/// <param name="dialogService">The dialog service to use for progress and result dialogs</param>
|
||||
/// <returns></returns>
|
||||
public static async Task CheckChangelog(MetroDialogService dialogService)
|
||||
{
|
||||
_logger.Info("Running AppUpdate");
|
||||
var settings = new GeneralSettings();
|
||||
settings.ApplyAutorun();
|
||||
mgr.CreateShortcutForThisExe();
|
||||
var settings = SettingsProvider.Load<GeneralSettings>();
|
||||
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
if ((settings.LastRanVersion != null) && (currentVersion > settings.LastRanVersion))
|
||||
{
|
||||
Logger.Info("Updated from {0} to {1}, showing changelog.", settings.LastRanVersion, currentVersion);
|
||||
|
||||
// Ask the user whether he/she wants to see what's new
|
||||
var showChanges = await dialogService.
|
||||
ShowQuestionMessageBox("New version installed",
|
||||
$"Artemis has recently updated from version {settings.LastRanVersion} to {currentVersion}. \n" +
|
||||
"Would you like to see what's new?");
|
||||
|
||||
// If user wants to see changelog, show it to them
|
||||
if ((showChanges != null) && showChanges.Value)
|
||||
await ShowChanges(dialogService, currentVersion);
|
||||
}
|
||||
|
||||
settings.LastRanVersion = currentVersion;
|
||||
settings.Save();
|
||||
}
|
||||
|
||||
public static void AppUninstall(IUpdateManager mgr)
|
||||
/// <summary>
|
||||
/// Fetches all releases from GitHub, looks up the current release and shows the changelog
|
||||
/// </summary>
|
||||
/// <param name="dialogService">The dialog service to use for progress and result dialogs</param>
|
||||
/// <param name="version">The version to fetch the changelog for</param>
|
||||
/// <returns></returns>
|
||||
private static async Task ShowChanges(MetroDialogService dialogService, Version version)
|
||||
{
|
||||
_logger.Info("Running AppUninstall");
|
||||
// Use GeneralSettings to get rid of the autorun shortcut
|
||||
var fakeSettings = new GeneralSettings {Autorun = false};
|
||||
fakeSettings.ApplyAutorun();
|
||||
var progressDialog = await dialogService.ShowProgressDialog("Changelog", "Fetching release data from GitHub..");
|
||||
progressDialog.SetIndeterminate();
|
||||
|
||||
mgr.RemoveShortcutForThisExe();
|
||||
var jsonClient = new WebClient();
|
||||
|
||||
// GitHub trips if we don't add a user agent
|
||||
jsonClient.Headers.Add("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
|
||||
|
||||
// Random number to get around cache issues
|
||||
var rand = new Random(DateTime.Now.Millisecond);
|
||||
var json = await jsonClient.DownloadStringTaskAsync(
|
||||
"https://api.github.com/repos/SpoinkyNL/Artemis/releases?random=" + rand.Next());
|
||||
|
||||
// Get a list of releases
|
||||
var releases = JsonConvert.DeserializeObject<JArray>(json);
|
||||
var release = releases.FirstOrDefault(r => r["tag_name"].Value<string>() == version.ToString());
|
||||
try
|
||||
{
|
||||
await progressDialog.CloseAsync();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// Occurs when main window is closed before finished
|
||||
}
|
||||
|
||||
if (release != null)
|
||||
dialogService.ShowMessageBox(release["name"].Value<string>(), release["body"].Value<string>());
|
||||
else
|
||||
dialogService.ShowMessageBox("Couldn't fetch release",
|
||||
"Sorry, Artemis was unable to fetch the release data off of GitHub.\n" +
|
||||
"If you'd like, you can always find out the latest changes on the GitHub page accessible from the options menu");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries GitHub for the latest pointers file
|
||||
/// </summary>
|
||||
public static void GetPointers()
|
||||
{
|
||||
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate)
|
||||
|
||||
@ -7,6 +7,7 @@ using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Services;
|
||||
using Artemis.Settings;
|
||||
using Artemis.Utilities;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.ViewModels
|
||||
@ -114,10 +115,13 @@ namespace Artemis.ViewModels
|
||||
|
||||
NotifyOfPropertyChange(() => CanShowWindow);
|
||||
NotifyOfPropertyChange(() => CanHideWindow);
|
||||
|
||||
ShowKeyboardDialog();
|
||||
|
||||
SettingsProvider.Load<GeneralSettings>().ApplyTheme();
|
||||
|
||||
// Show certain dialogs if needed
|
||||
CheckKeyboardState();
|
||||
CheckDuplicateInstances();
|
||||
Updater.CheckChangelog(DialogService);
|
||||
}
|
||||
|
||||
private void CheckDuplicateInstances()
|
||||
@ -137,7 +141,7 @@ namespace Artemis.ViewModels
|
||||
"If so, please make sure Artemis isn't already running");
|
||||
}
|
||||
|
||||
private async void ShowKeyboardDialog()
|
||||
private async void CheckKeyboardState()
|
||||
{
|
||||
while (!_shellViewModel.IsActive)
|
||||
await Task.Delay(200);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user