-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainWindow.xaml.cs
243 lines (208 loc) · 10.4 KB
/
MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using ZC.TimeCalculator.Resources.Utils;
namespace ZC.TimeCalculator
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
const string DEFAULT_TEXT = "__:__"; // Constant value of the default text
int[] timeStart = new int[2]; // Start time in hours and minutes separated
int[] _timeEnd = new int[2]; // End time in hours and minutes separated
int[] timeStartBreak = new int[2]; // Start break time in hours and minutes separated
int[] timeEndBreak = new int[2]; // End break time in hours and minutes separated
int[] timeSupp = new int[3]; // Supp hours in hours and minutes separated
int[] timeEndSupp = new int[2]; // End time calculated with supp time
int[] timeRequired = new int[2]; // Work time required in hours and minutes separated
bool componentInitialized = false; // If the component are initialized or not
Regex timeFinishedFormat = new Regex("(-?)([01][0-9]|2[0-3]):([0-5][0-9])"); // Regex for the date format when entierly written
List<TextBox> textBoxes = new List<TextBox>(); // List of all textboxes in the app
List<TextBox> negativeTextBoxes = new List<TextBox>(); // List of all textboxes that supports negative values
/// <summary>
/// Property that returns the value of timeEnd or assign it a value and change time end related text field
/// </summary>
public int[] TimeEnd
{
// Return the value of timeEnd
get => _timeEnd;
set
{
// Assign the value to timeEnd
if (value[0] < 24 && value[0] >= 0 &&
value[1] < 60 && value[1] >= 0)
_timeEnd = value;
// Display the result in 2 digits
txtTimeEnd.Text = _timeEnd[0].ToString("D2") + ":" + _timeEnd[1].ToString("D2");
}
}
/// <summary>
/// On preview key down, only allow specified keys
/// and write specfic character
/// </summary>
/// <param name="sender">The textbox that triggered the event</param>
/// <param name="e">Args of the key event</param>
private void Field_PreviewKeyDown(object sender, KeyEventArgs e)
{
TextBox textBox = sender as TextBox;
TimeUtils.Field_PreviewKeyDown(textBox, e, textBoxes, negativeTextBoxes);
}
/// <summary>
/// On text changes, calculate the new end time
/// </summary>
/// <param name="sender">Not used</param>
/// <param name="e">Not used</param>
private void FieldTimeRequired_TextChanged(object sender, TextChangedEventArgs e)
{
// If the text matches the finished time format
if (timeFinishedFormat.IsMatch(txtTimeRequired.Text))
{
// Create a table of the hours and minutes splitted
string[] fieldRequired = txtTimeRequired.Text.Split(':');
// Assign to the time required int table the new time required string values
timeRequired[0] = int.Parse(fieldRequired[0]);
timeRequired[1] = int.Parse(fieldRequired[1]);
// If the components are initialized and every textbox's text matches the finished time format
if (componentInitialized && timeFinishedFormat.IsMatch(txtTimeStart.Text) &&
timeFinishedFormat.IsMatch(txtTimeStartPause.Text) &&
timeFinishedFormat.IsMatch(txtTimeEndPause.Text))
// Start calculating end time
TimeEnd = TimeUtils.CalculateEnd(timeRequired, timeStart, timeStartBreak, timeEndBreak);
}
}
/// <summary>
/// On double-click, toggle mode between supp end time and default end time calculation
/// </summary>
/// <param name="sender">Not used</param>
/// <param name="e">Not used</param>
private void FieldEnd_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// If end time was already calculated
if (timeFinishedFormat.IsMatch(txtTimeEnd.Text))
{
// Toggle read-only mode on textBoxes
txtTimeEnd.IsReadOnly = !txtTimeEnd.IsReadOnly;
// If end fields are read-only
if (txtTimeEnd.IsReadOnly)
{
// Reset end time values to the calculated ones and h.supp to none
txtTimeEnd.Text = TimeEnd[0].ToString("D2") + ":" + TimeEnd[1].ToString("D2");
txtTimeSupp.Text = DEFAULT_TEXT;
txtTimeSupp.Focus();
}
// Else set focus on the end hour field
else
{
txtTimeEnd.Focus();
}
}
}
/// <summary>
/// On text changes, calculates h.supp
/// </summary>
/// <param name="sender">The textbox that triggered the event</param>
/// <param name="e">Not used</param>
private void FieldsEnd_TextChanged(object sender, TextChangedEventArgs e)
{
if (componentInitialized)
{
TextBox textBox = sender as TextBox;
// If textbox is read-only
if (textBox.IsReadOnly) return;
// If end time was calculated and both end fields content are set
if (TimeEnd[0] > 0 && TimeEnd[1] > 0 && timeFinishedFormat.IsMatch(txtTimeEnd.Text))
{
string[] endTime = txtTimeEnd.Text.Split(':');
int[] timeSuppUser = new int[2];
// Delta of hours and minutes
timeSuppUser[0] = int.Parse(endTime[0]);
timeSuppUser[1] = int.Parse(endTime[1]);
(int[] timeSupp, bool isNegativeBut0Hour) suppTime = TimeUtils.CalculateSuppTime(timeSuppUser, TimeEnd);
// Display the results in 2 digits
txtTimeSupp.Text = (suppTime.isNegativeBut0Hour ? "-" : "") + suppTime.timeSupp[0].ToString("D2") + ":" + suppTime.timeSupp[1].ToString("D2");
}
}
}
public MainWindow()
{
InitializeComponent();
componentInitialized = true;
timeRequired[0] = 8;
timeRequired[1] = 24;
// Start the app with a focus on the start field
txtTimeStart.Focus();
// Get all the references of textboxes of the app into a list
foreach (var item in gridTimeWork.Children)
// If the item type is of the TextBox type
if (item.GetType() == txtTimeStart.GetType())
textBoxes.Add(item as TextBox);
negativeTextBoxes.Add(txtTimeSupp);
}
/// <summary>
/// On text changes, calculates end time
/// </summary>
/// <param name="sender">The textbox that triggered the event</param>
/// <param name="e">Not used</param>
private void FieldsWorkTime_TextChanged(object sender, TextChangedEventArgs e)
{
// If the component are initialized
if (componentInitialized)
{
// If all the field required to calculate end time are sets
if (timeFinishedFormat.IsMatch(txtTimeStart.Text) && timeFinishedFormat.IsMatch(txtTimeStartPause.Text) && timeFinishedFormat.IsMatch(txtTimeEndPause.Text))
{
// Split fields value by double dots and insert them into a table
string[] fieldStart = txtTimeStart.Text.Split(':');
string[] fieldStartBreak = txtTimeStartPause.Text.Split(':');
string[] fieldEndBreak = txtTimeEndPause.Text.Split(':');
// Insert string time values into a table of int values
timeStart[0] = int.Parse(fieldStart[0]);
timeStart[1] = int.Parse(fieldStart[1]);
timeStartBreak[0] = int.Parse(fieldStartBreak[0]);
timeStartBreak[1] = int.Parse(fieldStartBreak[1]);
timeEndBreak[0] = int.Parse(fieldEndBreak[0]);
timeEndBreak[1] = int.Parse(fieldEndBreak[1]);
// Start calculating end time
TimeEnd = TimeUtils.CalculateEnd(timeRequired, timeStart, timeStartBreak, timeEndBreak);
}
}
}
/// <summary>
/// On text changes, calculates supp end time
/// </summary>
/// <param name="sender">The textbox that triggered the event</param>
/// <param name="e">Not used</param>
private void FieldsSupp_TextChanged(object sender, TextChangedEventArgs e)
{
// If the component are initialized
if (componentInitialized)
{
// If end fields are read-only
if (txtTimeEnd.IsReadOnly)
{
// If all the values required to calculate supp end time are sets
if (timeFinishedFormat.IsMatch(txtTimeEnd.Text) && timeFinishedFormat.IsMatch(txtTimeSupp.Text))
{
// Calculate supp end time hours
string[] fieldSupp = txtTimeSupp.Text.Split(':');
timeSupp[0] = int.Parse(fieldSupp[0]);
timeSupp[1] = int.Parse(fieldSupp[1]);
timeSupp[2] = txtTimeSupp.Text.StartsWith("-") ? 1 : 0;
// Start calculating supp end time
timeEndSupp = TimeUtils.CalculateEndSupp(timeRequired, timeStart, TimeEnd, timeSupp);
// Display the supp end time
txtTimeEndSupp.Text = timeEndSupp[0].ToString("D2") + ":" + timeEndSupp[1].ToString("D2");
}
}
}
}
}
}