Skip to content

Commit 5978ac6

Browse files
committed
Option to customize colors
1 parent c9e34c6 commit 5978ac6

File tree

7 files changed

+240
-22
lines changed

7 files changed

+240
-22
lines changed

src/BasicTimer/App.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:local="clr-namespace:BasicTimer"
5-
StartupUri="MainWindow.xaml">
5+
StartupUri="TimerWindow.xaml">
66
<Application.Resources>
77

88
</Application.Resources>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows.Media;
8+
9+
namespace BasicTimer
10+
{
11+
internal class ColorPickerViewModel : INotifyPropertyChanged
12+
{
13+
public Brush ForegroundBrush { get; set; } = Brushes.Gray;
14+
15+
public Brush BackgroundBrush { get; set; } = Brushes.Red;
16+
17+
private string _backgroundColorString = "#003366";
18+
19+
private string _foregroundColorString = "#006699";
20+
21+
public string BackgroundColorString
22+
{
23+
get => _backgroundColorString;
24+
set
25+
{
26+
_backgroundColorString = value;
27+
28+
try
29+
{
30+
BackgroundBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(value));
31+
}
32+
catch (FormatException)
33+
{
34+
System.Diagnostics.Debug.WriteLine($"Invalid color: {value}");
35+
return;
36+
}
37+
System.Diagnostics.Debug.WriteLine($"Valid color: {value}");
38+
39+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(BackgroundColorString)));
40+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(BackgroundBrush)));
41+
}
42+
}
43+
44+
45+
public string ForegroundColorString
46+
{
47+
get => _foregroundColorString;
48+
set
49+
{
50+
_foregroundColorString = value;
51+
52+
try
53+
{
54+
ForegroundBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(value));
55+
}
56+
catch (FormatException)
57+
{
58+
System.Diagnostics.Debug.WriteLine($"Invalid color: {value}");
59+
return;
60+
}
61+
System.Diagnostics.Debug.WriteLine($"Valid color: {value}");
62+
63+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ForegroundColorString)));
64+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ForegroundBrush)));
65+
}
66+
}
67+
68+
public event PropertyChangedEventHandler? PropertyChanged;
69+
}
70+
}

src/BasicTimer/ColorPickerWindow.xaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<Window x:Class="BasicTimer.ColorPickerWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:local="clr-namespace:BasicTimer"
7+
mc:Ignorable="d"
8+
Title="ColorPickerWindow" Height="200" Width="300">
9+
<Grid
10+
x:Name="MainGrid"
11+
Background="#003366"
12+
>
13+
14+
<Grid.RowDefinitions>
15+
<RowDefinition />
16+
<RowDefinition />
17+
</Grid.RowDefinitions>
18+
19+
<GroupBox
20+
Grid.Row="0"
21+
Name="ForegroundGroupBox"
22+
Header="Foreground"
23+
Foreground="{Binding ElementName=ForegroundTextbox, Path=Foreground}"
24+
Background="#006699"
25+
Margin="5 0 5 0"
26+
>
27+
<TextBox
28+
Name="ForegroundTextbox"
29+
Background="Transparent"
30+
HorizontalContentAlignment="Center"
31+
VerticalContentAlignment="Center"
32+
FontSize="36"
33+
Foreground="#FFFFFF"
34+
FontFamily="Consolas"
35+
Text="#006699"
36+
TextChanged="ForegroundTextbox_TextChanged"/>
37+
</GroupBox>
38+
39+
<GroupBox
40+
Grid.Row="1"
41+
Header="Background"
42+
Foreground="{Binding ElementName=BackgroundTextbox, Path=Foreground}"
43+
Margin="5 0 5 5"
44+
>
45+
<TextBox
46+
Name="BackgroundTextbox"
47+
Grid.Row="1"
48+
Background="Transparent"
49+
HorizontalContentAlignment="Center"
50+
VerticalContentAlignment="Center"
51+
FontSize="36"
52+
Foreground="#FFFFFF"
53+
FontFamily="Consolas"
54+
TextChanged="BackgroundTextbox_TextChanged"
55+
Text="#003366"/>
56+
</GroupBox>
57+
58+
</Grid>
59+
</Window>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Controls;
8+
using System.Windows.Data;
9+
using System.Windows.Documents;
10+
using System.Windows.Input;
11+
using System.Windows.Media;
12+
using System.Windows.Media.Imaging;
13+
using System.Windows.Shapes;
14+
15+
namespace BasicTimer
16+
{
17+
/// <summary>
18+
/// Interaction logic for ColorPickerWindow.xaml
19+
/// </summary>
20+
public partial class ColorPickerWindow : Window
21+
{
22+
public Brush ForegroundBrush => ForegroundGroupBox.Background;
23+
public Brush BackgroundBrush => MainGrid.Background;
24+
25+
public ColorPickerWindow()
26+
{
27+
InitializeComponent();
28+
}
29+
30+
private void ForegroundTextbox_TextChanged(object sender, TextChangedEventArgs e)
31+
{
32+
TextBox? textBox = sender as TextBox;
33+
string text = textBox?.Text ?? string.Empty;
34+
35+
try
36+
{
37+
Brush fgBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(text));
38+
ForegroundGroupBox.Background = fgBrush;
39+
}
40+
catch (FormatException) { }
41+
}
42+
43+
private void BackgroundTextbox_TextChanged(object sender, TextChangedEventArgs e)
44+
{
45+
TextBox? textBox = sender as TextBox;
46+
string text = textBox?.Text ?? string.Empty;
47+
48+
try
49+
{
50+
Brush bgBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(text));
51+
MainGrid.Background = bgBrush;
52+
}
53+
catch (FormatException) { }
54+
}
55+
}
56+
}

src/BasicTimer/TimerViewModel.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,27 @@ public double WindowHeight
2424
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(WindowHeight)));
2525
}
2626
}
27-
public Brush ProgressForeground { get; set; } = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#006699"));
2827

29-
public Brush ProgressBackground { get; set; } = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#003366"));
28+
private Brush _progressForegroundBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#006699"));
29+
public Brush ProgressForegroundBrush
30+
{
31+
get => _progressForegroundBrush;
32+
set {
33+
_progressForegroundBrush = value;
34+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProgressForegroundBrush)));
35+
}
36+
}
37+
38+
private Brush _progressBackgroundBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#003366"));
39+
public Brush ProgressBackgroundBrush
40+
{
41+
get => _progressBackgroundBrush;
42+
set
43+
{
44+
_progressBackgroundBrush = value;
45+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProgressBackgroundBrush)));
46+
}
47+
}
3048

3149
private int _fontSize = 36;
3250
public int FontSize

src/BasicTimer/MainWindow.xaml renamed to src/BasicTimer/TimerWindow.xaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@
88
WindowStyle="None"
99
ResizeMode="NoResize"
1010
Title="Stupid Timer"
11-
Height="{Binding WindowHeight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
11+
Height="{Binding WindowHeight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, FallbackValue=60}"
1212
Width="300"
1313
MouseDown="Window_MouseDown"
1414
>
1515
<Canvas
1616
Name="MainCanvas"
17-
Background="{Binding Path=ProgressBackground, UpdateSourceTrigger=PropertyChanged, FallbackValue=#003366}"
17+
Background="{Binding Path=ProgressBackgroundBrush, UpdateSourceTrigger=PropertyChanged, FallbackValue=#003366}"
1818
SizeChanged="MainCanvas_SizeChanged">
1919

2020
<Label
2121
Name="ProgressBar"
22-
Background="{Binding Path=ProgressForeground, UpdateSourceTrigger=PropertyChanged, FallbackValue=#006699}"
22+
Background="{Binding Path=ProgressForegroundBrush, UpdateSourceTrigger=PropertyChanged, FallbackValue=#006699}"
2323
Width="{Binding ProgressWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, FallbackValue=100}"
2424
Height="{Binding ActualHeight, ElementName=MainCanvas}" />
2525
<Label
2626
Content="{Binding Text, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, FallbackValue='00:00:00.00'}"
2727
Foreground="White"
2828
FontFamily="Lucida Console"
29-
FontSize="{Binding FontSize, NotifyOnSourceUpdated=True}"
29+
FontSize="{Binding FontSize, NotifyOnSourceUpdated=True, FallbackValue=36}"
3030
Width="{Binding ActualWidth, ElementName=MainCanvas}"
3131
Height="{Binding ActualHeight, ElementName=MainCanvas}"
3232
HorizontalContentAlignment="Center"
@@ -60,6 +60,8 @@
6060
<MenuItem Header="1 hr" Click="MenuItem_ProgressUnitSize_Click" Tag="3600"/>
6161
<MenuItem Header="Disable" Click="MenuItem_ProgressUnitSize_Click" Tag="0"/>
6262
</MenuItem>
63+
<MenuItem Header="Set Background Color" Click="MenuItem_SetBackgroundColor_Click"/>
64+
<MenuItem Header="Set Progress Color" Click="MenuItem_SetProgressColor_Click"/>
6365
<MenuItem Header="Toggle Title Bar" Click="MenuItem_ToggleTitleBar_Click"/>
6466
<MenuItem Header="Always on top" Click="MenuItem_ToggleAlwaysOnTop_Click" IsCheckable="True"/>
6567
<Separator />

src/BasicTimer/MainWindow.xaml.cs renamed to src/BasicTimer/TimerWindow.xaml.cs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,61 +21,74 @@ namespace BasicTimer
2121
/// </summary>
2222
public partial class MainWindow : Window
2323
{
24-
private readonly TimerViewModel TimerViewModel = new();
24+
private readonly TimerViewModel VM = new();
2525
private DispatcherTimer RedrawTimer = new();
2626

2727
public MainWindow()
2828
{
2929
InitializeComponent();
30-
DataContext = TimerViewModel;
30+
DataContext = VM;
3131

3232
RedrawTimer.Interval = TimeSpan.FromMilliseconds(10);
33-
RedrawTimer.Tick += TimerViewModel.Tick;
33+
RedrawTimer.Tick += VM.Tick;
3434
RedrawTimer.Start();
3535

36-
TimerViewModel.Start();
36+
VM.Start();
3737
}
3838

39-
private void MainCanvas_SizeChanged(object sender, SizeChangedEventArgs e) => TimerViewModel.ProgressWidthMax = MainCanvas.ActualWidth;
40-
private void MenuItem_Restart_Click(object sender, RoutedEventArgs e) => TimerViewModel.Restart();
41-
private void MenuItem_Stop_Click(object sender, RoutedEventArgs e) => TimerViewModel.Stop();
42-
private void MenuItem_Start_Click(object sender, RoutedEventArgs e) => TimerViewModel.Start();
43-
private void MenuItem_Copy_Click(object sender, RoutedEventArgs e) => Clipboard.SetText(TimerViewModel.Text);
39+
private void MainCanvas_SizeChanged(object sender, SizeChangedEventArgs e) => VM.ProgressWidthMax = MainCanvas.ActualWidth;
40+
private void MenuItem_Restart_Click(object sender, RoutedEventArgs e) => VM.Restart();
41+
private void MenuItem_Stop_Click(object sender, RoutedEventArgs e) => VM.Stop();
42+
private void MenuItem_Start_Click(object sender, RoutedEventArgs e) => VM.Start();
43+
private void MenuItem_Copy_Click(object sender, RoutedEventArgs e) => Clipboard.SetText(VM.Text);
4444
private void MenuItem_ExitApp_Click(object sender, RoutedEventArgs e) => Close();
4545
private void MenuItem_CloseMenu_Click(object sender, RoutedEventArgs e) { }
4646

4747
private void MenuItem_FontSize_Click(object sender, RoutedEventArgs e) =>
48-
TimerViewModel.FontSize = int.Parse(((MenuItem)sender).Tag.ToString()!);
48+
VM.FontSize = int.Parse(((MenuItem)sender).Tag.ToString()!);
4949

5050
private void MenuItem_ProgressUnitSize_Click(object sender, RoutedEventArgs e) =>
51-
TimerViewModel.ProgressWidthSeconds = int.Parse(((MenuItem)sender).Tag.ToString()!);
51+
VM.ProgressWidthSeconds = int.Parse(((MenuItem)sender).Tag.ToString()!);
5252

5353
private void MenuItem_ToggleTitleBar_Click(object sender, RoutedEventArgs e)
5454
{
5555
if (WindowStyle == WindowStyle.None)
5656
{
5757
WindowStyle = WindowStyle.SingleBorderWindow;
5858
ResizeMode = ResizeMode.CanResizeWithGrip;
59-
TimerViewModel.WindowHeight = ActualHeight + SystemParameters.WindowCaptionHeight * 2;
59+
VM.WindowHeight = ActualHeight + SystemParameters.WindowCaptionHeight * 2;
6060
}
6161
else
6262
{
6363
WindowStyle = WindowStyle.None;
6464
ResizeMode = ResizeMode.NoResize;
65-
TimerViewModel.WindowHeight = ActualHeight - SystemParameters.WindowCaptionHeight * 2;
65+
VM.WindowHeight = ActualHeight - SystemParameters.WindowCaptionHeight * 2;
6666
}
6767
}
6868

69-
private void MenuItem_ToggleAlwaysOnTop_Click(object sender, RoutedEventArgs e) =>
69+
private void MenuItem_ToggleAlwaysOnTop_Click(object sender, RoutedEventArgs e) =>
7070
Topmost = ((MenuItem)sender).IsChecked;
7171

72-
private void MenuItem_Version_Click(object sender, RoutedEventArgs e) =>
72+
private void MenuItem_Version_Click(object sender, RoutedEventArgs e) =>
7373
System.Diagnostics.Process.Start("explorer", "https://github.com/swharden/BasicTimer");
7474

7575
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
7676
{
7777
if (e.ChangedButton == MouseButton.Left)
7878
DragMove();
7979
}
80+
81+
private void MenuItem_SetBackgroundColor_Click(object sender, RoutedEventArgs e)
82+
{
83+
}
84+
85+
private void MenuItem_SetProgressColor_Click(object sender, RoutedEventArgs e)
86+
{
87+
var win = new ColorPickerWindow();
88+
win.ShowDialog();
89+
VM.ProgressBackgroundBrush = win.BackgroundBrush;
90+
VM.ProgressForegroundBrush = win.ForegroundBrush;
91+
System.Diagnostics.Debug.WriteLine($"{VM.ProgressBackgroundBrush} {VM.ProgressForegroundBrush}");
92+
}
8093
}
8194
}

0 commit comments

Comments
 (0)