Skip to content

Commit

Permalink
Add UI to change settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
skst committed May 5, 2024
1 parent f50d07c commit 104f7da
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 156 deletions.
9 changes: 6 additions & 3 deletions App.config
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@
</configSections>
<userSettings>
<Sandman.Properties.Settings>
<setting name="DelayBeforeSuspending" serializeAs="String">
<setting name="DelayBeforeSleep" serializeAs="String">
<value>00:00:10</value>
</setting>
<setting name="TimeUserInactiveBeforeSuspending" serializeAs="String">
<setting name="TimeUserInactiveBeforeSleep" serializeAs="String">
<value>00:30:00</value>
</setting>
<setting name="DelayAfterResume" serializeAs="String">
<value>00:10:00</value>
</setting>
<setting name="BlacklistedProcesses" serializeAs="String">
<setting name="BlockingProcesses" serializeAs="String">
<value>vlc;mpc-hc;steam</value>
</setting>
<setting name="DelayForElevatedProcess" serializeAs="String">
<value>00:01:00</value>
</setting>
<setting name="UpgradeRequired" serializeAs="String">
<value>True</value>
</setting>
</Sandman.Properties.Settings>
</userSettings>
</configuration>
87 changes: 74 additions & 13 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,79 @@
<Window x:Class="Sandman.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sandman"
mc:Ignorable="d"
Title="Sandman" Width="600" Height="400"
Icon="/Sandman;component/Resources/weather_moon_half.png"
Loaded="Window_Loaded"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sandman"
xmlns:props="clr-namespace:Sandman.Properties"
mc:Ignorable="d"
Title="Sandman" Width="600" Height="400"
Icon="/Sandman;component/Resources/weather_moon_half.png"
Loaded="Window_Loaded"
Closing="Window_Closing"
>
<Grid>
<TextBox TextWrapping="Wrap" Text="{Binding ConsoleLog, Mode=OneWay}"
BorderThickness="0" IsReadOnly="True" IsReadOnlyCaretVisible="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
/>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="Margin" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="5" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="Border">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="5" />
<Setter Property="Padding" Value="5,0" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="5" />
<Setter Property="Padding" Value="3" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>

<Label Grid.Row="0" Grid.Column="0" Content="Delay immediately before sleep:" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding DelayBeforeSleep, Mode=TwoWay, Source={x:Static props:Settings.Default}}" />
<TextBlock Grid.Row="0" Grid.Column="2" Text="hh:mm:ss" />

<Label Grid.Row="1" Grid.Column="0" Content="User inactive before sleep:" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding TimeUserInactiveBeforeSleep, Mode=TwoWay, Source={x:Static props:Settings.Default}}" />
<TextBlock Grid.Row="1" Grid.Column="2" Text="hh:mm:ss" />

<Label Grid.Row="2" Grid.Column="0" Content="Delay after resume:" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding DelayAfterResume, Mode=TwoWay, Source={x:Static props:Settings.Default}}" />
<TextBlock Grid.Row="2" Grid.Column="2" Text="hh:mm:ss" />

<Label Grid.Row="3" Grid.Column="0" Content="Elevated process delay:" />
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DelayForElevatedProcess, Mode=TwoWay, Source={x:Static props:Settings.Default}}" />
<TextBlock Grid.Row="3" Grid.Column="2" Text="hh:mm:ss" />

<Label Grid.Row="4" Grid.Column="0" Content="Blocking processes:" />
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding BlockingProcesses, Mode=TwoWay, Source={x:Static props:Settings.Default}}" />

<Button Grid.Row="4" Grid.Column="2" Content="Restart" Click="RestartButton_Click" />

<Border Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="Black" BorderThickness="1">
<TextBox x:Name="CtlLog" Margin="0" Padding="0" BorderThickness="0" TextWrapping="Wrap" VerticalAlignment="Stretch"
Text="{Binding ConsoleLog, Mode=OneWay}"
IsReadOnly="True" IsReadOnlyCaretVisible="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
/>
</Border>
</Grid>
</Window>
94 changes: 72 additions & 22 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Sandman.Properties;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows;

namespace Sandman;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
[ObservableObject]
public partial class MainWindow : Window
{
[ObservableProperty]
private StringBuilder _consoleLog = new();

public static readonly string ExecutableFolder = string.Empty;
public StringBuilder ConsoleLog { get; set; } = new StringBuilder();

private readonly Shared.NotificationIcon _notificationIcon;

Expand All @@ -27,8 +28,36 @@ static MainWindow()
ExecutableFolder = Path.GetDirectoryName(asm.Location) ?? string.Empty;
}
}

public MainWindow()
{
/*
* If necessary, migrate app.config settings to new app.config file.
*
* Note: This works for an "in-place" upgrade, such as a build,
* running setup.exe, or using ClickOnce.
* The reason is that .NET creates a hash from the path to determine
* where to store user settings.
* In "in-place" upgrades, all user.config files are in
* version-specific directories under a single app folder.
*
* REF: Upgrade() https://stackoverflow.com/questions/534261/how-do-you-keep-user-config-settings-across-different-assembly-versions-in-net/534335#534335
* REF: Reload() https://stackoverflow.com/questions/23924183/keep-users-settings-after-altering-assembly-file-version/47921377#47921377
*/
if (Settings.Default.UpgradeRequired)
{
try
{
Settings.Default.Upgrade();
Settings.Default.Reload();
Settings.Default.UpgradeRequired = false;
Settings.Default.Save();
}
catch (Exception)
{
}
}

// remove original default trace listener
Trace.Listeners.Clear();

Expand All @@ -52,17 +81,22 @@ public MainWindow()
DataContext = this;
}


private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await WatchAndWait.StartAsync(this).ConfigureAwait(continueOnCapturedContext: false);
}


private void Window_Closing(object sender, CancelEventArgs e)
{
Settings.Default.Save();

if (_notificationIcon.ShouldClose())
{
/// Calling <see cref="AddToConsoleLog(string)"/> while shutting down
/// will cause a <seealso cref="TaskCanceledException"/>.
/// So, we cancel the wait task before exiting.
WatchAndWait.CancelWaitTaskAsync().Wait(TimeSpan.FromSeconds(1));

Application.Current.Shutdown();
return;
}
Expand All @@ -72,30 +106,46 @@ private void Window_Closing(object sender, CancelEventArgs e)
Trace.Flush();
}

private async void RestartButton_Click(object sender, RoutedEventArgs e)
{
await WatchAndWait.RestartWaitAsync().ConfigureAwait(continueOnCapturedContext: false);
}

public void WriteOutput(string s)
public void WriteInformation(string s)
{
string timestampedMessage = $"[{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss}] (Thread {Environment.CurrentManagedThreadId:00}) {s}";
string timestampedMessage = TimestampMessage(s);
Trace.TraceInformation(timestampedMessage);
ConsoleLog.AppendLine(timestampedMessage);

RaisePropertyChanged(nameof(ConsoleLog));
AddToConsoleLog(timestampedMessage);
}

public void WriteWarning(string s)
{
string timestampedMessage = TimestampMessage(s);
Trace.TraceWarning(timestampedMessage);

// Boilerplate code
#region IRaisePropertyChanged

#region INotifyPropertyChanged
AddToConsoleLog(timestampedMessage);
}

public event PropertyChangedEventHandler? PropertyChanged;
public void WriteError(string s)
{
string timestampedMessage = TimestampMessage(s);
Trace.TraceError(timestampedMessage);

#endregion INotifyPropertyChanged
AddToConsoleLog(timestampedMessage);
}

public void RaisePropertyChanged(string propertyName)
private void AddToConsoleLog(string timestampedMessage)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
ConsoleLog.AppendLine(timestampedMessage);
OnPropertyChanged(nameof(ConsoleLog));

Dispatcher.Invoke(() =>
{
CtlLog.CaretIndex = CtlLog.Text.Length;
CtlLog.ScrollToEnd();
});
}

#endregion IRaisePropertyChanged
private static string TimestampMessage(string s) => $"[{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss}] (Thread {Environment.CurrentManagedThreadId:00}) {s}";
}
30 changes: 21 additions & 9 deletions Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions Properties/Settings.settings
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Sandman.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="DelayBeforeSuspending" Type="System.TimeSpan" Scope="User">
<Setting Name="DelayBeforeSleep" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:00:10</Value>
</Setting>
<Setting Name="TimeUserInactiveBeforeSuspending" Type="System.TimeSpan" Scope="User">
<Setting Name="TimeUserInactiveBeforeSleep" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:30:00</Value>
</Setting>
<Setting Name="DelayAfterResume" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:10:00</Value>
</Setting>
<Setting Name="BlacklistedProcesses" Type="System.String" Scope="User">
<Setting Name="BlockingProcesses" Type="System.String" Scope="User">
<Value Profile="(Default)">vlc;mpc-hc;steam</Value>
</Setting>
<Setting Name="DelayForElevatedProcess" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:01:00</Value>
</Setting>
<Setting Name="UpgradeRequired" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>
Loading

0 comments on commit 104f7da

Please sign in to comment.