mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Partial refactor of applying profile display UI
This commit is contained in:
parent
227caa2230
commit
17cc302d17
@ -576,7 +576,7 @@ namespace HeliosPlus.Shared
|
|||||||
// Now lets start by changing the display topology
|
// Now lets start by changing the display topology
|
||||||
Task applyProfileTopologyTask = Task.Run(() =>
|
Task applyProfileTopologyTask = Task.Run(() =>
|
||||||
{
|
{
|
||||||
Console.WriteLine("ShortcutRepository/SaveShortcutIconToCache : Applying Profile Topology " + profile.Name);
|
Console.WriteLine("ProfileRepository/SaveShortcutIconToCache : Applying Profile Topology " + profile.Name);
|
||||||
ApplyTopology(profile);
|
ApplyTopology(profile);
|
||||||
});
|
});
|
||||||
applyProfileTopologyTask.Wait();
|
applyProfileTopologyTask.Wait();
|
||||||
@ -584,7 +584,7 @@ namespace HeliosPlus.Shared
|
|||||||
// And then change the path information
|
// And then change the path information
|
||||||
Task applyProfilePathInfoTask = Task.Run(() =>
|
Task applyProfilePathInfoTask = Task.Run(() =>
|
||||||
{
|
{
|
||||||
Console.WriteLine("ShortcutRepository/SaveShortcutIconToCache : Applying Profile Path " + profile.Name);
|
Console.WriteLine("ProfileRepository/SaveShortcutIconToCache : Applying Profile Path " + profile.Name);
|
||||||
ApplyPathInfo(profile);
|
ApplyPathInfo(profile);
|
||||||
});
|
});
|
||||||
applyProfilePathInfoTask.Wait();
|
applyProfilePathInfoTask.Wait();
|
||||||
@ -593,16 +593,17 @@ namespace HeliosPlus.Shared
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
Console.WriteLine($"ProfileRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyTopology(ProfileItem profile)
|
public static bool ApplyTopology(ProfileItem profile)
|
||||||
{
|
{
|
||||||
Debug.Print("ShortcutRepository.ApplyTopology()");
|
Debug.Print("ProfileRepository.ApplyTopology()");
|
||||||
if (profile == null)
|
|
||||||
return;
|
if (!(profile is ProfileItem))
|
||||||
|
return false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -615,6 +616,7 @@ namespace HeliosPlus.Shared
|
|||||||
|
|
||||||
if (surroundTopologies.Length == 0)
|
if (surroundTopologies.Length == 0)
|
||||||
{
|
{
|
||||||
|
// This profile does not use NVIDIA Surround
|
||||||
var currentTopologies = GridTopology.GetGridTopologies();
|
var currentTopologies = GridTopology.GetGridTopologies();
|
||||||
|
|
||||||
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
||||||
@ -625,34 +627,39 @@ namespace HeliosPlus.Shared
|
|||||||
.Select(displays => new GridTopology(1, 1, new[] { displays }))
|
.Select(displays => new GridTopology(1, 1, new[] { displays }))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
} else if (surroundTopologies.Length > 0)
|
||||||
|
|
||||||
if (surroundTopologies.Length > 0)
|
|
||||||
{
|
{
|
||||||
|
// This profile is an NVIDIA Surround profile
|
||||||
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
Console.WriteLine($"ProfileRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
// ignored
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyPathInfo(ProfileItem profile)
|
public static bool ApplyPathInfo(ProfileItem profile)
|
||||||
{
|
{
|
||||||
Debug.Print("ShortcutRepository.ApplyPathInfo()");
|
Debug.Print("ProfileRepository.ApplyPathInfo()");
|
||||||
if (profile == null)
|
if (!(profile is ProfileItem))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (!profile.IsPossible)
|
try
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
|
||||||
$"ShortcutRepository/ApplyPathInfo exception: Problem applying the '{profile.Name}' Display Profile! The display configuration changed since this profile is created. Please re-create this profile.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var pathInfos = profile.Viewports.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
|
var pathInfos = profile.Viewports.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
|
||||||
WindowsDisplayAPI.DisplayConfig.PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
WindowsDisplayAPI.DisplayConfig.PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"ProfileRepository/ApplyPathInfo exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidFilename(string testName)
|
public static bool IsValidFilename(string testName)
|
||||||
|
@ -80,8 +80,15 @@
|
|||||||
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
|
<Compile Include="GameLibraries\SteamAppInfoParser\App.cs" />
|
||||||
<Compile Include="GameLibraries\SteamLibrary.cs" />
|
<Compile Include="GameLibraries\SteamLibrary.cs" />
|
||||||
<Compile Include="IconUtils.cs" />
|
<Compile Include="IconUtils.cs" />
|
||||||
|
<Compile Include="ProgressReporter.cs" />
|
||||||
<Compile Include="ShortcutItem.cs" />
|
<Compile Include="ShortcutItem.cs" />
|
||||||
<Compile Include="ShortcutRepository.cs" />
|
<Compile Include="ShortcutRepository.cs" />
|
||||||
|
<Compile Include="UIForms\ApplyingProfileForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="UIForms\ApplyingProfileForm.Designer.cs">
|
||||||
|
<DependentUpon>ApplyingProfileForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UIForms\ShortcutAdaptor.cs" />
|
<Compile Include="UIForms\ShortcutAdaptor.cs" />
|
||||||
<Compile Include="UIForms\ProfileAdaptor.cs" />
|
<Compile Include="UIForms\ProfileAdaptor.cs" />
|
||||||
<Compile Include="UIForms\MainForm.cs">
|
<Compile Include="UIForms\MainForm.cs">
|
||||||
@ -139,6 +146,9 @@
|
|||||||
<LastGenOutput>Language.Designer.cs</LastGenOutput>
|
<LastGenOutput>Language.Designer.cs</LastGenOutput>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="UIForms\ApplyingProfileForm.resx">
|
||||||
|
<DependentUpon>ApplyingProfileForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="UIForms\MainForm.resx">
|
<EmbeddedResource Include="UIForms\MainForm.resx">
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
@ -19,6 +19,7 @@ using HeliosPlus.UIForms;
|
|||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Diagnostics.Contracts;
|
||||||
|
|
||||||
namespace HeliosPlus {
|
namespace HeliosPlus {
|
||||||
public enum SupportedProgramMode
|
public enum SupportedProgramMode
|
||||||
@ -329,7 +330,7 @@ namespace HeliosPlus {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public static string GetValidFilename(string uncheckedFilename)
|
/* public static string GetValidFilename(string uncheckedFilename)
|
||||||
{
|
{
|
||||||
string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
|
string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
|
||||||
foreach (char c in invalid)
|
foreach (char c in invalid)
|
||||||
@ -338,5 +339,65 @@ namespace HeliosPlus {
|
|||||||
}
|
}
|
||||||
return uncheckedFilename;
|
return uncheckedFilename;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
// ApplyProfile lives here so that the UI works.
|
||||||
|
public static bool ApplyProfile(ProfileItem profile)
|
||||||
|
{
|
||||||
|
// If we're already on the wanted profile then no need to change!
|
||||||
|
if (ProfileRepository.IsActiveProfile(profile))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// We need to check if the profile is valid
|
||||||
|
if (!profile.IsPossible)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Set up the UI forms to show
|
||||||
|
ApplyingProfileForm timeoutForm = new ApplyingProfileForm(3, 0, $"Applying Profile '{profile.Name}'", $"Press ESC to timeout");
|
||||||
|
ApplyingProfileForm topologyForm = new ApplyingProfileForm(0, 30, $"Applying Profile '{profile.Name}' Topology");
|
||||||
|
ApplyingProfileForm pathInfoForm = new ApplyingProfileForm(0, 30, $"Applying Profile '{profile.Name}' Path");
|
||||||
|
|
||||||
|
topologyForm.ShowDialog();
|
||||||
|
// Now lets start by changing the display topology
|
||||||
|
Task applyTopologyTask = Task.Run(() =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("ProfileRepository/SaveShortcutIconToCache : Applying Profile Topology " + profile.Name);
|
||||||
|
ProfileRepository.ApplyTopology(profile);
|
||||||
|
});
|
||||||
|
applyTopologyTask.Wait();
|
||||||
|
topologyForm.Close();
|
||||||
|
|
||||||
|
if (applyTopologyTask.IsCompleted)
|
||||||
|
{
|
||||||
|
pathInfoForm.ShowDialog();
|
||||||
|
Task applyPathInfoTask = Task.Run(() => {
|
||||||
|
Console.WriteLine("ProfileRepository/SaveShortcutIconToCache : Applying Profile Path " + profile.Name);
|
||||||
|
ProfileRepository.ApplyPathInfo(profile);
|
||||||
|
});
|
||||||
|
|
||||||
|
applyPathInfoTask.Wait();
|
||||||
|
pathInfoForm.Close();
|
||||||
|
// And then change the path information
|
||||||
|
if (applyPathInfoTask.IsCompleted)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"ProfileRepository/ApplyTopology exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
160
HeliosPlus/ProgressReporter.cs
Normal file
160
HeliosPlus/ProgressReporter.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HeliosPlus
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class used by Tasks to report progress or completion updates back to the UI.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ProgressReporter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The underlying scheduler for the UI's synchronization context.
|
||||||
|
/// </summary>
|
||||||
|
private readonly TaskScheduler scheduler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ProgressReporter"/> class.
|
||||||
|
/// This should be run on a UI thread.
|
||||||
|
/// </summary>
|
||||||
|
public ProgressReporter()
|
||||||
|
{
|
||||||
|
this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the task scheduler which executes tasks on the UI thread.
|
||||||
|
/// </summary>
|
||||||
|
public TaskScheduler Scheduler
|
||||||
|
{
|
||||||
|
get { return this.scheduler; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the progress to the UI thread. This method should be called from the task.
|
||||||
|
/// Note that the progress update is asynchronous with respect to the reporting Task.
|
||||||
|
/// For a synchronous progress update, wait on the returned <see cref="Task"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">The action to perform in the context of the UI thread.
|
||||||
|
/// Note that this action is run asynchronously on the UI thread.</param>
|
||||||
|
/// <returns>The task queued to the UI thread.</returns>
|
||||||
|
public Task ReportProgressAsync(Action action)
|
||||||
|
{
|
||||||
|
return Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, this.scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the progress to the UI thread, and waits for the UI thread to process
|
||||||
|
/// the update before returning. This method should be called from the task.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">The action to perform in the context of the UI thread.</param>
|
||||||
|
public void ReportProgress(Action action)
|
||||||
|
{
|
||||||
|
this.ReportProgressAsync(action).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task finishes execution,
|
||||||
|
/// whether it finishes with success, failiure, or cancellation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">The task to monitor for completion.</param>
|
||||||
|
/// <param name="action">The action to take when the task has completed, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle completion. This is normally ignored.</returns>
|
||||||
|
public Task RegisterContinuation(Task task, Action action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task finishes execution,
|
||||||
|
/// whether it finishes with success, failiure, or cancellation.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
||||||
|
/// <param name="task">The task to monitor for completion.</param>
|
||||||
|
/// <param name="action">The action to take when the task has completed, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle completion. This is normally ignored.</returns>
|
||||||
|
public Task RegisterContinuation<TResult>(Task<TResult> task, Action action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task successfully finishes execution.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">The task to monitor for successful completion.</param>
|
||||||
|
/// <param name="action">The action to take when the task has successfully completed, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle successful completion. This is normally ignored.</returns>
|
||||||
|
public Task RegisterSucceededHandler(Task task, Action action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task successfully finishes execution
|
||||||
|
/// and returns a result.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
||||||
|
/// <param name="task">The task to monitor for successful completion.</param>
|
||||||
|
/// <param name="action">The action to take when the task has successfully completed, in the context of the UI thread.
|
||||||
|
/// The argument to the action is the return value of the task.</param>
|
||||||
|
/// <returns>The continuation created to handle successful completion. This is normally ignored.</returns>
|
||||||
|
public Task RegisterSucceededHandler<TResult>(Task<TResult> task, Action<TResult> action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(t => action(t.Result), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.Scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task becomes faulted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">The task to monitor for faulting.</param>
|
||||||
|
/// <param name="action">The action to take when the task has faulted, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle faulting. This is normally ignored.</returns>
|
||||||
|
public Task RegisterFaultedHandler(Task task, Action<Exception> action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task becomes faulted.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
||||||
|
/// <param name="task">The task to monitor for faulting.</param>
|
||||||
|
/// <param name="action">The action to take when the task has faulted, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle faulting. This is normally ignored.</returns>
|
||||||
|
public Task RegisterFaultedHandler<TResult>(Task<TResult> task, Action<Exception> action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task is cancelled.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="task">The task to monitor for cancellation.</param>
|
||||||
|
/// <param name="action">The action to take when the task is cancelled, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle cancellation. This is normally ignored.</returns>
|
||||||
|
public Task RegisterCancelledHandler(Task task, Action action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a UI thread handler for when the specified task is cancelled.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
||||||
|
/// <param name="task">The task to monitor for cancellation.</param>
|
||||||
|
/// <param name="action">The action to take when the task is cancelled, in the context of the UI thread.</param>
|
||||||
|
/// <returns>The continuation created to handle cancellation. This is normally ignored.</returns>
|
||||||
|
public Task RegisterCancelledHandler<TResult>(Task<TResult> task, Action action)
|
||||||
|
{
|
||||||
|
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -484,7 +484,8 @@ namespace HeliosPlus
|
|||||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||||
|
|
||||||
// Apply the Profile!
|
// Apply the Profile!
|
||||||
if (!ProfileRepository.ApplyProfile(shortcutToUse.ProfileToUse))
|
//if (!ProfileRepository.ApplyProfile(shortcutToUse.ProfileToUse))
|
||||||
|
if (!Program.ApplyProfile(shortcutToUse.ProfileToUse))
|
||||||
{
|
{
|
||||||
throw new Exception(Language.Cannot_change_active_profile);
|
throw new Exception(Language.Cannot_change_active_profile);
|
||||||
}
|
}
|
||||||
@ -694,7 +695,8 @@ namespace HeliosPlus
|
|||||||
// Change back to the original profile if it is different
|
// Change back to the original profile if it is different
|
||||||
if (!ProfileRepository.IsActiveProfile(rollbackProfile))
|
if (!ProfileRepository.IsActiveProfile(rollbackProfile))
|
||||||
{
|
{
|
||||||
if (!ProfileRepository.ApplyProfile(rollbackProfile))
|
//if (!ProfileRepository.ApplyProfile(rollbackProfile))
|
||||||
|
if (!Program.ApplyProfile(rollbackProfile))
|
||||||
{
|
{
|
||||||
throw new Exception(Language.Cannot_change_active_profile);
|
throw new Exception(Language.Cannot_change_active_profile);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace HeliosPlus.UIForms
|
|||||||
this.lbl_sub_message = new System.Windows.Forms.Label();
|
this.lbl_sub_message = new System.Windows.Forms.Label();
|
||||||
this.lbl_message = new System.Windows.Forms.Label();
|
this.lbl_message = new System.Windows.Forms.Label();
|
||||||
this.progressBar = new CircularProgressBar.CircularProgressBar();
|
this.progressBar = new CircularProgressBar.CircularProgressBar();
|
||||||
this.t_start = new System.Windows.Forms.Timer(this.components);
|
this.t_cancellation = new System.Windows.Forms.Timer(this.components);
|
||||||
this.t_countdown = new System.Windows.Forms.Timer(this.components);
|
this.t_countdown = new System.Windows.Forms.Timer(this.components);
|
||||||
this.progressPanel.SuspendLayout();
|
this.progressPanel.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
@ -106,8 +106,8 @@ namespace HeliosPlus.UIForms
|
|||||||
//
|
//
|
||||||
// t_start
|
// t_start
|
||||||
//
|
//
|
||||||
this.t_start.Interval = 1000;
|
this.t_cancellation.Interval = 1000;
|
||||||
this.t_start.Tick += new System.EventHandler(this.t_start_Tick);
|
this.t_cancellation.Tick += new System.EventHandler(this.t_cancellation_Tick);
|
||||||
//
|
//
|
||||||
// t_countdown
|
// t_countdown
|
||||||
//
|
//
|
||||||
@ -150,7 +150,7 @@ namespace HeliosPlus.UIForms
|
|||||||
private Panel progressPanel;
|
private Panel progressPanel;
|
||||||
private CircularProgressBar.CircularProgressBar progressBar;
|
private CircularProgressBar.CircularProgressBar progressBar;
|
||||||
private System.Windows.Forms.Label lbl_message;
|
private System.Windows.Forms.Label lbl_message;
|
||||||
private System.Windows.Forms.Timer t_start;
|
private System.Windows.Forms.Timer t_cancellation;
|
||||||
private System.Windows.Forms.Timer t_countdown;
|
private System.Windows.Forms.Timer t_countdown;
|
||||||
private Label lbl_sub_message;
|
private Label lbl_sub_message;
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,9 @@ namespace HeliosPlus.UIForms
|
|||||||
return base.ProcessCmdKey(ref msg, keyData);
|
return base.ProcessCmdKey(ref msg, keyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t_start.Enabled)
|
if (t_cancellation.Enabled)
|
||||||
{
|
{
|
||||||
t_start.Stop();
|
t_cancellation.Stop();
|
||||||
t_countdown.Stop();
|
t_countdown.Stop();
|
||||||
DialogResult = DialogResult.Cancel;
|
DialogResult = DialogResult.Cancel;
|
||||||
Close();
|
Close();
|
||||||
@ -133,14 +133,14 @@ namespace HeliosPlus.UIForms
|
|||||||
|
|
||||||
private void DoTimeout()
|
private void DoTimeout()
|
||||||
{
|
{
|
||||||
lbl_message.Text = CancellationMessage;
|
|
||||||
lbl_sub_message.Text = CancellationSubMessage;
|
|
||||||
progressBar.ProgressColor = Color.DodgerBlue;
|
|
||||||
|
|
||||||
if (_startCounter > 0)
|
if (_startCounter > 0)
|
||||||
{
|
{
|
||||||
|
lbl_message.Text = CancellationMessage;
|
||||||
|
lbl_sub_message.Text = CancellationSubMessage;
|
||||||
|
progressBar.ProgressColor = Color.DodgerBlue;
|
||||||
progressBar.Text = (progressBar.Value = progressBar.Maximum = _startCounter).ToString();
|
progressBar.Text = (progressBar.Value = progressBar.Maximum = _startCounter).ToString();
|
||||||
t_start.Start();
|
t_cancellation.Start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -241,11 +241,11 @@ namespace HeliosPlus.UIForms
|
|||||||
Reposition();
|
Reposition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void t_start_Tick(object sender, EventArgs e)
|
private void t_cancellation_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (_startCounter < 0)
|
if (_startCounter < 0)
|
||||||
{
|
{
|
||||||
t_start.Stop();
|
t_cancellation.Stop();
|
||||||
DoJob();
|
DoJob();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
149
HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs
generated
Normal file
149
HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs
generated
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
namespace HeliosPlus.UIForms
|
||||||
|
{
|
||||||
|
partial class ApplyingProfileForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
this.progressPanel = new System.Windows.Forms.Panel();
|
||||||
|
this.lbl_sub_message = new System.Windows.Forms.Label();
|
||||||
|
this.progressBar = new CircularProgressBar.CircularProgressBar();
|
||||||
|
this.lbl_message = new System.Windows.Forms.Label();
|
||||||
|
this.t_countdown = new System.Windows.Forms.Timer(this.components);
|
||||||
|
this.t_cancellation = new System.Windows.Forms.Timer(this.components);
|
||||||
|
this.progressPanel.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// progressPanel
|
||||||
|
//
|
||||||
|
this.progressPanel.Anchor = System.Windows.Forms.AnchorStyles.None;
|
||||||
|
this.progressPanel.Controls.Add(this.lbl_sub_message);
|
||||||
|
this.progressPanel.Controls.Add(this.progressBar);
|
||||||
|
this.progressPanel.Controls.Add(this.lbl_message);
|
||||||
|
this.progressPanel.Location = new System.Drawing.Point(77, 154);
|
||||||
|
this.progressPanel.Name = "progressPanel";
|
||||||
|
this.progressPanel.Size = new System.Drawing.Size(621, 270);
|
||||||
|
this.progressPanel.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// lbl_sub_message
|
||||||
|
//
|
||||||
|
this.lbl_sub_message.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.lbl_sub_message.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.lbl_sub_message.Location = new System.Drawing.Point(159, 87);
|
||||||
|
this.lbl_sub_message.Name = "lbl_sub_message";
|
||||||
|
this.lbl_sub_message.Size = new System.Drawing.Size(300, 16);
|
||||||
|
this.lbl_sub_message.TabIndex = 2;
|
||||||
|
this.lbl_sub_message.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// progressBar
|
||||||
|
//
|
||||||
|
this.progressBar.AnimationFunction = WinFormAnimation.KnownAnimationFunctions.Liner;
|
||||||
|
this.progressBar.AnimationSpeed = 1000;
|
||||||
|
this.progressBar.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||||
|
this.progressBar.Font = new System.Drawing.Font("Microsoft Sans Serif", 39.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.progressBar.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
|
||||||
|
this.progressBar.InnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
|
||||||
|
this.progressBar.InnerMargin = 0;
|
||||||
|
this.progressBar.InnerWidth = 0;
|
||||||
|
this.progressBar.Location = new System.Drawing.Point(243, 125);
|
||||||
|
this.progressBar.MarqueeAnimationSpeed = 2000;
|
||||||
|
this.progressBar.Name = "progressBar";
|
||||||
|
this.progressBar.OuterColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||||
|
this.progressBar.OuterMargin = -8;
|
||||||
|
this.progressBar.OuterWidth = 6;
|
||||||
|
this.progressBar.ProgressColor = System.Drawing.Color.DodgerBlue;
|
||||||
|
this.progressBar.ProgressWidth = 10;
|
||||||
|
this.progressBar.SecondaryFont = new System.Drawing.Font("Microsoft Sans Serif", 26.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
|
this.progressBar.Size = new System.Drawing.Size(135, 135);
|
||||||
|
this.progressBar.StartAngle = 270;
|
||||||
|
this.progressBar.SubscriptColor = System.Drawing.Color.FromArgb(((int)(((byte)(166)))), ((int)(((byte)(166)))), ((int)(((byte)(166)))));
|
||||||
|
this.progressBar.SubscriptMargin = new System.Windows.Forms.Padding(10, -35, 0, 0);
|
||||||
|
this.progressBar.SubscriptText = "";
|
||||||
|
this.progressBar.SuperscriptColor = System.Drawing.Color.Gray;
|
||||||
|
this.progressBar.SuperscriptMargin = new System.Windows.Forms.Padding(0, 30, 0, 0);
|
||||||
|
this.progressBar.SuperscriptText = "";
|
||||||
|
this.progressBar.TabIndex = 0;
|
||||||
|
this.progressBar.TextMargin = new System.Windows.Forms.Padding(2, 5, 0, 0);
|
||||||
|
this.progressBar.Value = 68;
|
||||||
|
//
|
||||||
|
// lbl_message
|
||||||
|
//
|
||||||
|
this.lbl_message.Font = new System.Drawing.Font("Microsoft Sans Serif", 27.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(178)));
|
||||||
|
this.lbl_message.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
|
||||||
|
this.lbl_message.Location = new System.Drawing.Point(3, 0);
|
||||||
|
this.lbl_message.Name = "lbl_message";
|
||||||
|
this.lbl_message.Size = new System.Drawing.Size(615, 61);
|
||||||
|
this.lbl_message.TabIndex = 1;
|
||||||
|
this.lbl_message.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// t_countdown
|
||||||
|
//
|
||||||
|
this.t_countdown.Interval = 1000;
|
||||||
|
this.t_countdown.Tick += new System.EventHandler(this.t_countdown_Tick);
|
||||||
|
//
|
||||||
|
// t_cancellation
|
||||||
|
//
|
||||||
|
this.t_cancellation.Interval = 1000;
|
||||||
|
this.t_cancellation.Tick += new System.EventHandler(this.t_cancellation_Tick);
|
||||||
|
//
|
||||||
|
// ApplyingProfileForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||||
|
this.ClientSize = new System.Drawing.Size(800, 450);
|
||||||
|
this.Controls.Add(this.progressPanel);
|
||||||
|
this.DoubleBuffered = true;
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||||
|
this.KeyPreview = true;
|
||||||
|
this.Name = "ApplyingProfileForm";
|
||||||
|
this.Opacity = 0D;
|
||||||
|
this.ShowIcon = false;
|
||||||
|
this.ShowInTaskbar = false;
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "HeliosPlus - Please Wait";
|
||||||
|
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ApplyingProfileForm_FormClosing);
|
||||||
|
this.Load += new System.EventHandler(this.ApplyingProfileForm_Reposition);
|
||||||
|
this.Shown += new System.EventHandler(this.ApplyingProfileForm_Shown);
|
||||||
|
this.LocationChanged += new System.EventHandler(this.ApplyingProfileForm_Reposition);
|
||||||
|
this.Leave += new System.EventHandler(this.ApplyingProfileForm_Reposition);
|
||||||
|
this.Move += new System.EventHandler(this.ApplyingProfileForm_Reposition);
|
||||||
|
this.progressPanel.ResumeLayout(false);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Panel progressPanel;
|
||||||
|
private CircularProgressBar.CircularProgressBar progressBar;
|
||||||
|
private System.Windows.Forms.Label lbl_sub_message;
|
||||||
|
private System.Windows.Forms.Label lbl_message;
|
||||||
|
private System.Windows.Forms.Timer t_countdown;
|
||||||
|
private System.Windows.Forms.Timer t_cancellation;
|
||||||
|
}
|
||||||
|
}
|
300
HeliosPlus/UIForms/ApplyingProfileForm.cs
Normal file
300
HeliosPlus/UIForms/ApplyingProfileForm.cs
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using WinFormAnimation;
|
||||||
|
|
||||||
|
namespace HeliosPlus.UIForms
|
||||||
|
{
|
||||||
|
public partial class ApplyingProfileForm : Form
|
||||||
|
{
|
||||||
|
private readonly Bitmap _progressImage;
|
||||||
|
private readonly List<Point> _progressPositions = new List<Point>();
|
||||||
|
private int _countdownCounter;
|
||||||
|
private readonly int _displayChangeMaxDelta = -1;
|
||||||
|
private int _displayChangeDelta;
|
||||||
|
private int _lastCount;
|
||||||
|
private bool _isClosing;
|
||||||
|
private int _cancellationCounter;
|
||||||
|
|
||||||
|
public ApplyingProfileForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
_progressImage = new Bitmap(progressPanel.Width, progressPanel.Height);
|
||||||
|
Controls.Remove(progressPanel);
|
||||||
|
progressPanel.BackColor = BackColor;
|
||||||
|
progressBar.Invalidated += (sender, args) => Invalidate();
|
||||||
|
progressPanel.Invalidated += (sender, args) => Invalidate();
|
||||||
|
Reposition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplyingProfileForm(int cancellationTimeout = 0, int countdown = 0, string title = null, string message = null, int displayChangeMaxDelta = 5) : this()
|
||||||
|
{
|
||||||
|
_cancellationCounter = cancellationTimeout;
|
||||||
|
_countdownCounter = countdown;
|
||||||
|
_lastCount = _countdownCounter;
|
||||||
|
_displayChangeMaxDelta = displayChangeMaxDelta;
|
||||||
|
if (!string.IsNullOrEmpty(title)) CountdownTitle = title;
|
||||||
|
if (!string.IsNullOrEmpty(message)) CountdownMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CancellationTitle { get; set; } = "Starting in ...";
|
||||||
|
public string CancellationMessage { get; set; } = "Please press ESC to cancel";
|
||||||
|
|
||||||
|
public string CountdownTitle { get; set; } = "Please wait...";
|
||||||
|
public string CountdownMessage { get; set; } = "It won't be long now!";
|
||||||
|
|
||||||
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
lock (_progressPositions)
|
||||||
|
{
|
||||||
|
progressPanel.DrawToBitmap(_progressImage, new Rectangle(Point.Empty, progressPanel.Size));
|
||||||
|
|
||||||
|
foreach (var position in _progressPositions)
|
||||||
|
{
|
||||||
|
e.Graphics.DrawImage(_progressImage, new Rectangle(position, progressPanel.Size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnPaint(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||||
|
{
|
||||||
|
if (keyData != Keys.Escape)
|
||||||
|
{
|
||||||
|
return base.ProcessCmdKey(ref msg, keyData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_cancellation.Enabled)
|
||||||
|
{
|
||||||
|
t_cancellation.Stop();
|
||||||
|
t_countdown.Stop();
|
||||||
|
DialogResult = DialogResult.Cancel;
|
||||||
|
Close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDisplayChangeDelta()
|
||||||
|
{
|
||||||
|
if (_displayChangeMaxDelta <= -1) return;
|
||||||
|
_displayChangeDelta = _lastCount - _countdownCounter;
|
||||||
|
if (_displayChangeDelta > _displayChangeMaxDelta)
|
||||||
|
{
|
||||||
|
Debug.Print("_displayChangeDelta > _displayChangeMaxDelta! " + _displayChangeDelta + " > " + _displayChangeMaxDelta);
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoCountdown()
|
||||||
|
{
|
||||||
|
if (_countdownCounter > 0)
|
||||||
|
{
|
||||||
|
lbl_message.Text = CountdownTitle;
|
||||||
|
lbl_sub_message.Text = CountdownMessage;
|
||||||
|
progressBar.ProgressColor = Color.OrangeRed;
|
||||||
|
progressBar.Text = (progressBar.Value = progressBar.Maximum = _countdownCounter).ToString();
|
||||||
|
t_countdown.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progressBar.Style = ProgressBarStyle.Marquee;
|
||||||
|
progressBar.Text = "";
|
||||||
|
progressBar.Maximum = 100;
|
||||||
|
progressBar.Value = 50;
|
||||||
|
progressBar.Style = ProgressBarStyle.Marquee;
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleDisplayChangeDelta();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoCancellationTimeout()
|
||||||
|
{
|
||||||
|
if (_cancellationCounter > 0)
|
||||||
|
{
|
||||||
|
lbl_message.Text = CancellationTitle;
|
||||||
|
lbl_sub_message.Text = CancellationMessage;
|
||||||
|
progressBar.ProgressColor = Color.DodgerBlue;
|
||||||
|
progressBar.Text = (progressBar.Value = progressBar.Maximum = _cancellationCounter).ToString();
|
||||||
|
t_cancellation.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DoCountdown();
|
||||||
|
}
|
||||||
|
HandleDisplayChangeDelta();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reposition()
|
||||||
|
{
|
||||||
|
lock (_progressPositions)
|
||||||
|
{
|
||||||
|
|
||||||
|
Screen[] screens = Screen.AllScreens;
|
||||||
|
Size = screens.Select(screen => screen.Bounds)
|
||||||
|
.Aggregate(Rectangle.Union)
|
||||||
|
.Size;
|
||||||
|
|
||||||
|
_progressPositions.Clear();
|
||||||
|
_progressPositions.AddRange(
|
||||||
|
screens.Select(
|
||||||
|
screen =>
|
||||||
|
new Point(screen.Bounds.X + ((screen.Bounds.Width - progressPanel.Width) / 2),
|
||||||
|
screen.Bounds.Y + ((screen.Bounds.Height - progressPanel.Height) / 2))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyingProfileForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if (_isClosing)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isClosing = true;
|
||||||
|
e.Cancel = true;
|
||||||
|
var dialogResult = DialogResult;
|
||||||
|
new Animator(new Path((float)Opacity, 0, 200))
|
||||||
|
.Play(new SafeInvoker<float>(f =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Opacity = f;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"ApplyingProfileForm/ApplyingProfileForm_FormClosing exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}, this), new SafeInvoker(() =>
|
||||||
|
{
|
||||||
|
DialogResult = dialogResult;
|
||||||
|
Close();
|
||||||
|
}, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyingProfileForm_Reposition(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Reposition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyingProfileForm_Shown(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
new Animator(new Path((float)Opacity, 0.97f, 200))
|
||||||
|
.Play(new SafeInvoker<float>(f =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Opacity = f;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"ApplyingProfileForm/ApplyingProfileForm_Shown exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}, this), new SafeInvoker(DoCancellationTimeout, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void t_countdown_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_countdownCounter < 0)
|
||||||
|
{
|
||||||
|
t_countdown.Stop();
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleDisplayChangeDelta();
|
||||||
|
|
||||||
|
progressBar.Value = _countdownCounter;
|
||||||
|
progressBar.Text = progressBar.Value.ToString();
|
||||||
|
_countdownCounter--;
|
||||||
|
Reposition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void t_cancellation_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_cancellationCounter < 0)
|
||||||
|
{
|
||||||
|
t_cancellation.Stop();
|
||||||
|
DoCountdown();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar.Value = _cancellationCounter;
|
||||||
|
progressBar.Text = progressBar.Value.ToString();
|
||||||
|
_cancellationCounter--;
|
||||||
|
Reposition();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void WndProc(ref Message m)
|
||||||
|
{
|
||||||
|
const int WM_SETTINGCHANGE = 0x001A;
|
||||||
|
const int SPI_SETWORKAREA = 0x02F;
|
||||||
|
const int WM_DISPLAYCHANGE = 0x007E;
|
||||||
|
|
||||||
|
const int x_bitshift = 0;
|
||||||
|
const int y_bitshift = 16;
|
||||||
|
const int xy_mask = 0xFFFF;
|
||||||
|
|
||||||
|
bool displayChange = false;
|
||||||
|
|
||||||
|
switch (m.Msg)
|
||||||
|
{
|
||||||
|
case WM_SETTINGCHANGE:
|
||||||
|
Debug.Print("Message: " + m.ToString());
|
||||||
|
Debug.Print("WM_SETTINGCHANGE");
|
||||||
|
switch ((int)m.WParam)
|
||||||
|
{
|
||||||
|
case SPI_SETWORKAREA:
|
||||||
|
Debug.Print("SPI_SETWORKAREA");
|
||||||
|
displayChange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DISPLAYCHANGE:
|
||||||
|
int cxScreen = (xy_mask & ((int)m.LParam) >> x_bitshift);
|
||||||
|
int cyScreen = (xy_mask & ((int)m.LParam) >> y_bitshift);
|
||||||
|
Debug.Print("Message: " + m.ToString());
|
||||||
|
Debug.Print("WM_DISPLAYCHANGE");
|
||||||
|
Debug.Print("cxScreen: " + cxScreen + " cyScreen: " + cyScreen);
|
||||||
|
displayChange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (displayChange)
|
||||||
|
{
|
||||||
|
_displayChangeDelta = _lastCount - _countdownCounter;
|
||||||
|
_lastCount = _countdownCounter;
|
||||||
|
Debug.Print("Display Change Detected at t " + _lastCount + " difference between changes is " + _displayChangeDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.WndProc(ref m);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
126
HeliosPlus/UIForms/ApplyingProfileForm.resx
Normal file
126
HeliosPlus/UIForms/ApplyingProfileForm.resx
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="t_countdown.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>143, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="t_cancellation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
@ -312,9 +312,8 @@ namespace HeliosPlus.UIForms
|
|||||||
this.MinimumSize = new System.Drawing.Size(800, 400);
|
this.MinimumSize = new System.Drawing.Size(800, 400);
|
||||||
this.Name = "DisplayProfileForm";
|
this.Name = "DisplayProfileForm";
|
||||||
this.ShowInTaskbar = false;
|
this.ShowInTaskbar = false;
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
this.Text = "HeliosPlus - Setup Display Profiles";
|
this.Text = "HeliosPlus - Setup Display Profiles";
|
||||||
this.TopMost = true;
|
|
||||||
this.Activated += new System.EventHandler(this.DisplayProfileForm_Activated);
|
this.Activated += new System.EventHandler(this.DisplayProfileForm_Activated);
|
||||||
this.Load += new System.EventHandler(this.DisplayProfileForm_Load);
|
this.Load += new System.EventHandler(this.DisplayProfileForm_Load);
|
||||||
this.menu_profiles.ResumeLayout(false);
|
this.menu_profiles.ResumeLayout(false);
|
||||||
|
@ -46,7 +46,8 @@ namespace HeliosPlus.UIForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the Profile
|
// Apply the Profile
|
||||||
ProfileRepository.ApplyProfile(_selectedProfile);
|
//ProfileRepository.ApplyProfile(_selectedProfile);
|
||||||
|
Program.ApplyProfile(_selectedProfile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user