CoreTimeEditorControl.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. using Syncfusion.Windows.Shared;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Input;
  5. using System.Windows.Media;
  6. using Comal.Classes;
  7. using InABox.DynamicGrid;
  8. namespace PRS.Shared
  9. {
  10. public class CoreTimeEditorControl : DynamicEnclosedEditorControl<TimeBlock, CoreTimeEditor>
  11. {
  12. static CoreTimeEditorControl()
  13. {
  14. //DynamicEditorControlFactory.Register<CoreTimeEditorControl, CoreTimeEditor>();
  15. }
  16. private DockPanel Docker;
  17. private TextBox StartLabel;
  18. private DateTimeEdit Start;
  19. private TextBox DurationLabel;
  20. private TimeSpanEdit Duration;
  21. private TextBox FinishLabel;
  22. private DateTimeEdit Finish;
  23. private TimeBlock Time = new();
  24. public override void Configure()
  25. {
  26. }
  27. protected override FrameworkElement CreateEditor()
  28. {
  29. Docker = new DockPanel();
  30. Docker.LastChildFill = false;
  31. CreateTimeEdit("From:", 0, StartChanged, false, out StartLabel, out Start);
  32. CreateTimeSpanEdit("Dur:", 4, DurationChanged, true, out DurationLabel, out Duration);
  33. CreateTimeEdit("To:", 8, FinishChanged, true, out FinishLabel, out Finish);
  34. return Docker;
  35. }
  36. private void StartChanged(TimeSpan start)
  37. {
  38. Time.Start = start;
  39. UpdateEditors();
  40. }
  41. private void DurationChanged(TimeSpan duration)
  42. {
  43. Time.Duration = duration;
  44. UpdateEditors();
  45. }
  46. private void FinishChanged(TimeSpan finish)
  47. {
  48. Time.Finish = finish;
  49. UpdateEditors();
  50. }
  51. private void UpdateEditors()
  52. {
  53. SetValue(Start, Time.Start);
  54. SetValue(Duration, Time.Duration);
  55. SetValue(Finish, Time.Finish);
  56. CheckChanged();
  57. }
  58. public override void SetEnabled(bool enabled)
  59. {
  60. base.SetEnabled(enabled);
  61. Start.IsEnabled = enabled;
  62. Duration.IsEnabled = enabled;
  63. Finish.IsEnabled = enabled;
  64. SetColor(enabled ? Color : Colors.WhiteSmoke);
  65. }
  66. private void CreateTimeSpanEdit(string header, int column, Action<TimeSpan> onChanged, bool leftMargin, out TextBox label, out TimeSpanEdit editor)
  67. {
  68. DockPanel dock = new DockPanel();
  69. dock.SetValue(DockPanel.DockProperty, Dock.Left);
  70. dock.Margin = new Thickness(leftMargin ? 5 : 0, 0, 0, 0);
  71. dock.Width = 150;
  72. var edit = new TimeSpanEdit
  73. {
  74. Format = "h:mm",
  75. MinValue = new TimeSpan(),
  76. MaxValue = TimeSpan.MaxValue,
  77. VerticalContentAlignment = VerticalAlignment.Center,
  78. HorizontalContentAlignment = HorizontalAlignment.Center,
  79. ShowArrowButtons = false
  80. };
  81. edit.SetValue(DockPanel.DockProperty, Dock.Left);
  82. var brush = edit.BorderBrush;
  83. var thickness = edit.BorderThickness.Left;
  84. edit.BorderThickness = new Thickness(0, thickness, thickness, thickness);
  85. label = new TextBox
  86. {
  87. Text = header,
  88. Margin = new Thickness(0),
  89. BorderBrush = brush,
  90. BorderThickness = new Thickness(thickness,thickness,0,thickness),
  91. VerticalContentAlignment = VerticalAlignment.Center,
  92. HorizontalContentAlignment = HorizontalAlignment.Left,
  93. IsReadOnly = true,
  94. Padding = new Thickness(2,0,0,0),
  95. Width = 40
  96. };
  97. label.SetValue(DockPanel.DockProperty, Dock.Left);
  98. edit.PreviewKeyDown += (o, e) =>
  99. {
  100. var separator = edit.Text.IndexOf(":");
  101. if (e.Key == Key.OemPeriod)
  102. {
  103. edit.Select(separator + 1, 2);
  104. e.Handled = true;
  105. }
  106. else if (e.Key == Key.Back)
  107. {
  108. if (string.Equals(edit.SelectedText, "00"))
  109. edit.Select(0, separator);
  110. else
  111. edit.SelectedText = "00";
  112. e.Handled = true;
  113. }
  114. else if (e.Key == Key.Tab)
  115. {
  116. if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift))
  117. {
  118. if (edit.SelectionStart > separator)
  119. {
  120. edit.Select(0, separator);
  121. e.Handled = true;
  122. }
  123. }
  124. else
  125. {
  126. if (edit.SelectionLength != edit.Text.Length && edit.SelectionStart < separator)
  127. {
  128. edit.Select(separator + 1, 2);
  129. e.Handled = true;
  130. }
  131. }
  132. }
  133. };
  134. var changed = false;
  135. edit.ValueChanged += (o, e) =>
  136. {
  137. changed = true;
  138. };
  139. edit.LostFocus += (o, e) =>
  140. {
  141. if (changed)
  142. onChanged(GetValue(edit));
  143. };
  144. var less = new Button
  145. {
  146. Content = "<",
  147. Width = 23,
  148. Margin = new Thickness(2, 0, 0, 0),
  149. Focusable = false
  150. };
  151. less.SetValue(DockPanel.DockProperty, Dock.Right);
  152. less.Click += (o, e) =>
  153. {
  154. edit.Value = edit.Value.HasValue && edit.Value >= new TimeSpan(0, 15, 0)
  155. ? edit.Value.Value.Subtract(new TimeSpan(0, 15, 0))
  156. : new TimeSpan(0);
  157. onChanged(GetValue(edit));
  158. };
  159. var more = new Button
  160. {
  161. Content = ">",
  162. Width = 23,
  163. Margin = new Thickness(2, 0, 0, 0),
  164. Focusable = false
  165. };
  166. more.SetValue(DockPanel.DockProperty, Dock.Right);
  167. more.Click += (o, e) =>
  168. {
  169. edit.Value = edit.Value.HasValue ? edit.Value.Value.Add(new TimeSpan(0, 15, 0)) : new TimeSpan(0, 15, 0);
  170. onChanged(GetValue(edit));
  171. };
  172. dock.Children.Add(label);
  173. dock.Children.Add(more);
  174. dock.Children.Add(less);
  175. dock.Children.Add(edit);
  176. Docker.Children.Add(dock);
  177. editor = edit;
  178. }
  179. private void CreateTimeEdit(string header, int column, Action<TimeSpan> onChanged, bool leftMargin, out TextBox label, out DateTimeEdit editor)
  180. {
  181. DockPanel dock = new DockPanel();
  182. dock.SetValue(DockPanel.DockProperty, Dock.Left);
  183. dock.Margin = new Thickness(leftMargin ? 5 : 0, 0, 0, 0);
  184. dock.Width = 150;
  185. var edit = new DateTimeEdit
  186. {
  187. Pattern = DateTimePattern.CustomPattern,
  188. CustomPattern = "HH:mm", //DateTimeFormat.Custom,
  189. //FormatString = "HH:mm",
  190. VerticalContentAlignment = VerticalAlignment.Center,
  191. HorizontalContentAlignment = HorizontalAlignment.Center,
  192. //TimeInterval = new TimeSpan(0, 15, 0),
  193. //ShowButtonSpinner = false
  194. DropDownView = DropDownViews.Clock,
  195. BorderThickness = new Thickness(0, 0.75, 0.75, 0.75),
  196. BorderBrush = new SolidColorBrush(Colors.Gray),
  197. IsButtonPopUpEnabled = false,
  198. };
  199. edit.SetValue(DockPanel.DockProperty, Dock.Left);
  200. label = new TextBox
  201. {
  202. Text = header,
  203. Margin = new Thickness(0),
  204. BorderBrush = new SolidColorBrush(Colors.Gray),
  205. BorderThickness = new Thickness(0.75, 0.75, 0, 0.75),
  206. VerticalContentAlignment = VerticalAlignment.Center,
  207. HorizontalContentAlignment = HorizontalAlignment.Left,
  208. Padding = new Thickness(2,0,0,0),
  209. IsReadOnly = true,
  210. Width = 40
  211. };
  212. label.SetValue(DockPanel.DockProperty, Dock.Left);
  213. edit.PreviewKeyDown += (o, e) =>
  214. {
  215. var separator = edit.Text.IndexOf(":");
  216. if (e.Key == Key.OemPeriod)
  217. {
  218. edit.Select(separator + 1, 2);
  219. e.Handled = true;
  220. }
  221. else if (e.Key == Key.Back)
  222. {
  223. if (string.Equals(edit.SelectedText, "00"))
  224. edit.Select(0, separator);
  225. else
  226. edit.SelectedText = "00";
  227. e.Handled = true;
  228. }
  229. else if (e.Key == Key.Tab)
  230. {
  231. if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift))
  232. {
  233. if (edit.SelectionStart > separator)
  234. {
  235. edit.Select(0, separator);
  236. e.Handled = true;
  237. }
  238. }
  239. else
  240. {
  241. if (edit.SelectionLength != edit.Text.Length && edit.SelectionStart < separator)
  242. {
  243. edit.Select(separator + 1, 2);
  244. e.Handled = true;
  245. }
  246. }
  247. }
  248. };
  249. var changed = false;
  250. edit.DateTimeChanged += (o, e) =>
  251. {
  252. changed = true;
  253. };
  254. edit.LostFocus += (o, e) =>
  255. {
  256. if (changed)
  257. {
  258. onChanged(GetValue(edit));
  259. }
  260. };
  261. var less = new Button
  262. {
  263. Content = "<",
  264. Width = 23,
  265. Margin = new Thickness(2, 0, 0, 0),
  266. Focusable = false
  267. };
  268. less.SetValue(DockPanel.DockProperty, Dock.Right);
  269. less.Click += (o, e) =>
  270. {
  271. edit.DateTime = edit.DateTime.HasValue && edit.DateTime.Value.TimeOfDay >= new TimeSpan(0, 15, 0)
  272. ? edit.DateTime.Value.Subtract(new TimeSpan(0, 15, 0))
  273. : edit.DateTime;
  274. onChanged(GetValue(edit));
  275. };
  276. var more = new Button
  277. {
  278. Content = ">",
  279. Width = 23,
  280. Margin = new Thickness(2, 0, 0, 0),
  281. Focusable = false
  282. };
  283. more.SetValue(DockPanel.DockProperty, Dock.Right);
  284. more.Click += (o, e) =>
  285. {
  286. edit.DateTime = edit.DateTime.HasValue && edit.DateTime.Value.TimeOfDay < new TimeSpan(23, 45, 0)
  287. ? edit.DateTime.Value.Add(new TimeSpan(0, 15, 0))
  288. : edit.DateTime;
  289. onChanged(GetValue(edit));
  290. };
  291. dock.Children.Add(label);
  292. dock.Children.Add(more);
  293. dock.Children.Add(less);
  294. dock.Children.Add(edit);
  295. Docker.Children.Add(dock);
  296. editor = edit;
  297. }
  298. private static TimeSpan GetValue(DateTimeEdit edit)
  299. {
  300. var result = new TimeSpan(0);
  301. if (edit.DateTime.HasValue)
  302. result = edit.DateTime.Value.TimeOfDay;
  303. result = new TimeSpan(result.Hours, result.Minutes, 0);
  304. return result;
  305. }
  306. private static void SetValue(DateTimeEdit edit, TimeSpan value)
  307. {
  308. if (value.Ticks > 0)
  309. edit.DateTime = DateTime.MinValue.Add(value);
  310. else
  311. edit.DateTime = null;
  312. }
  313. private static TimeSpan GetValue(TimeSpanEdit edit)
  314. {
  315. var result = new TimeSpan(0);
  316. if (edit.Value.HasValue)
  317. result = edit.Value.Value;
  318. return result;
  319. }
  320. private static void SetValue(TimeSpanEdit edit, TimeSpan value)
  321. {
  322. edit.Value = value;
  323. }
  324. public override int DesiredHeight()
  325. {
  326. return 25;
  327. }
  328. public override int DesiredWidth()
  329. {
  330. return int.MaxValue;
  331. }
  332. protected override IEnumerable<KeyValuePair<string, object?>> GetChildValues()
  333. {
  334. yield return new("Start", Time.Start);
  335. yield return new("Duration", Time.Duration);
  336. yield return new("Finish", Time.Finish);
  337. }
  338. protected override object? GetChildValue(string property)
  339. {
  340. if (property == "Start") return Time.Start;
  341. if (property == "Duration") return Time.Duration;
  342. if (property == "Finish") return Time.Finish;
  343. return null;
  344. }
  345. protected override void SetChildValue(string property, object? value)
  346. {
  347. if (value is not TimeSpan timeSpan) return;
  348. if (property == "Start") Time.Start = timeSpan;
  349. else if (property == "Duration") Time.Duration = timeSpan;
  350. else if (property == "Finish") Time.Finish = timeSpan;
  351. UpdateEditors();
  352. }
  353. public override void SetColor(Color color)
  354. {
  355. StartLabel.Background = new SolidColorBrush(color);
  356. Start.Background = new SolidColorBrush(color);
  357. DurationLabel.Background = new SolidColorBrush(color);
  358. Duration.Background = new SolidColorBrush(color);
  359. FinishLabel.Background = new SolidColorBrush(color);
  360. Finish.Background = new SolidColorBrush(color);
  361. }
  362. public override void SetFocus()
  363. {
  364. Start.Focus();
  365. }
  366. }
  367. }