using Syncfusion.Windows.Shared; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using Comal.Classes; using InABox.DynamicGrid; namespace PRS.Shared { public class CoreTimeEditorControl : DynamicEnclosedEditorControl { static CoreTimeEditorControl() { //DynamicEditorControlFactory.Register(); } private DockPanel Docker; private TextBox StartLabel; private DateTimeEdit Start; private TextBox DurationLabel; private TimeSpanEdit Duration; private TextBox FinishLabel; private DateTimeEdit Finish; private TimeBlock Time = new(); public override void Configure() { } protected override FrameworkElement CreateEditor() { Docker = new DockPanel(); Docker.LastChildFill = false; CreateTimeEdit("From:", 0, StartChanged, false, out StartLabel, out Start); CreateTimeSpanEdit("Dur:", 4, DurationChanged, true, out DurationLabel, out Duration); CreateTimeEdit("To:", 8, FinishChanged, true, out FinishLabel, out Finish); return Docker; } private void StartChanged(TimeSpan start) { Time.Start = start; UpdateEditors(); } private void DurationChanged(TimeSpan duration) { Time.Duration = duration; UpdateEditors(); } private void FinishChanged(TimeSpan finish) { Time.Finish = finish; UpdateEditors(); } private void UpdateEditors() { SetValue(Start, Time.Start); SetValue(Duration, Time.Duration); SetValue(Finish, Time.Finish); CheckChanged(); } public override void SetEnabled(bool enabled) { base.SetEnabled(enabled); Start.IsEnabled = enabled; Duration.IsEnabled = enabled; Finish.IsEnabled = enabled; SetColor(enabled ? Color : Colors.WhiteSmoke); } private void CreateTimeSpanEdit(string header, int column, Action onChanged, bool leftMargin, out TextBox label, out TimeSpanEdit editor) { DockPanel dock = new DockPanel(); dock.SetValue(DockPanel.DockProperty, Dock.Left); dock.Margin = new Thickness(leftMargin ? 5 : 0, 0, 0, 0); dock.Width = 150; var edit = new TimeSpanEdit { Format = "h:mm", MinValue = new TimeSpan(), MaxValue = TimeSpan.MaxValue, VerticalContentAlignment = VerticalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Center, ShowArrowButtons = false }; edit.SetValue(DockPanel.DockProperty, Dock.Left); var brush = edit.BorderBrush; var thickness = edit.BorderThickness.Left; edit.BorderThickness = new Thickness(0, thickness, thickness, thickness); label = new TextBox { Text = header, Margin = new Thickness(0), BorderBrush = brush, BorderThickness = new Thickness(thickness,thickness,0,thickness), VerticalContentAlignment = VerticalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Left, IsReadOnly = true, Padding = new Thickness(2,0,0,0), Width = 40 }; label.SetValue(DockPanel.DockProperty, Dock.Left); edit.PreviewKeyDown += (o, e) => { var separator = edit.Text.IndexOf(":"); if (e.Key == Key.OemPeriod) { edit.Select(separator + 1, 2); e.Handled = true; } else if (e.Key == Key.Back) { if (string.Equals(edit.SelectedText, "00")) edit.Select(0, separator); else edit.SelectedText = "00"; e.Handled = true; } else if (e.Key == Key.Tab) { if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift)) { if (edit.SelectionStart > separator) { edit.Select(0, separator); e.Handled = true; } } else { if (edit.SelectionLength != edit.Text.Length && edit.SelectionStart < separator) { edit.Select(separator + 1, 2); e.Handled = true; } } } }; var changed = false; edit.ValueChanged += (o, e) => { changed = true; }; edit.LostFocus += (o, e) => { if (changed) onChanged(GetValue(edit)); }; var less = new Button { Content = "<", Width = 23, Margin = new Thickness(2, 0, 0, 0), Focusable = false }; less.SetValue(DockPanel.DockProperty, Dock.Right); less.Click += (o, e) => { edit.Value = edit.Value.HasValue && edit.Value >= new TimeSpan(0, 15, 0) ? edit.Value.Value.Subtract(new TimeSpan(0, 15, 0)) : new TimeSpan(0); onChanged(GetValue(edit)); }; var more = new Button { Content = ">", Width = 23, Margin = new Thickness(2, 0, 0, 0), Focusable = false }; more.SetValue(DockPanel.DockProperty, Dock.Right); more.Click += (o, e) => { edit.Value = edit.Value.HasValue ? edit.Value.Value.Add(new TimeSpan(0, 15, 0)) : new TimeSpan(0, 15, 0); onChanged(GetValue(edit)); }; dock.Children.Add(label); dock.Children.Add(more); dock.Children.Add(less); dock.Children.Add(edit); Docker.Children.Add(dock); editor = edit; } private void CreateTimeEdit(string header, int column, Action onChanged, bool leftMargin, out TextBox label, out DateTimeEdit editor) { DockPanel dock = new DockPanel(); dock.SetValue(DockPanel.DockProperty, Dock.Left); dock.Margin = new Thickness(leftMargin ? 5 : 0, 0, 0, 0); dock.Width = 150; var edit = new DateTimeEdit { Pattern = DateTimePattern.CustomPattern, CustomPattern = "HH:mm", //DateTimeFormat.Custom, //FormatString = "HH:mm", VerticalContentAlignment = VerticalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Center, //TimeInterval = new TimeSpan(0, 15, 0), //ShowButtonSpinner = false DropDownView = DropDownViews.Clock, BorderThickness = new Thickness(0, 0.75, 0.75, 0.75), BorderBrush = new SolidColorBrush(Colors.Gray), IsButtonPopUpEnabled = false, }; edit.SetValue(DockPanel.DockProperty, Dock.Left); label = new TextBox { Text = header, Margin = new Thickness(0), BorderBrush = new SolidColorBrush(Colors.Gray), BorderThickness = new Thickness(0.75, 0.75, 0, 0.75), VerticalContentAlignment = VerticalAlignment.Center, HorizontalContentAlignment = HorizontalAlignment.Left, Padding = new Thickness(2,0,0,0), IsReadOnly = true, Width = 40 }; label.SetValue(DockPanel.DockProperty, Dock.Left); edit.PreviewKeyDown += (o, e) => { var separator = edit.Text.IndexOf(":"); if (e.Key == Key.OemPeriod) { edit.Select(separator + 1, 2); e.Handled = true; } else if (e.Key == Key.Back) { if (string.Equals(edit.SelectedText, "00")) edit.Select(0, separator); else edit.SelectedText = "00"; e.Handled = true; } else if (e.Key == Key.Tab) { if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift)) { if (edit.SelectionStart > separator) { edit.Select(0, separator); e.Handled = true; } } else { if (edit.SelectionLength != edit.Text.Length && edit.SelectionStart < separator) { edit.Select(separator + 1, 2); e.Handled = true; } } } }; var changed = false; edit.DateTimeChanged += (o, e) => { changed = true; }; edit.LostFocus += (o, e) => { if (changed) { onChanged(GetValue(edit)); } }; var less = new Button { Content = "<", Width = 23, Margin = new Thickness(2, 0, 0, 0), Focusable = false }; less.SetValue(DockPanel.DockProperty, Dock.Right); less.Click += (o, e) => { edit.DateTime = edit.DateTime.HasValue && edit.DateTime.Value.TimeOfDay >= new TimeSpan(0, 15, 0) ? edit.DateTime.Value.Subtract(new TimeSpan(0, 15, 0)) : edit.DateTime; onChanged(GetValue(edit)); }; var more = new Button { Content = ">", Width = 23, Margin = new Thickness(2, 0, 0, 0), Focusable = false }; more.SetValue(DockPanel.DockProperty, Dock.Right); more.Click += (o, e) => { edit.DateTime = edit.DateTime.HasValue && edit.DateTime.Value.TimeOfDay < new TimeSpan(23, 45, 0) ? edit.DateTime.Value.Add(new TimeSpan(0, 15, 0)) : edit.DateTime; onChanged(GetValue(edit)); }; dock.Children.Add(label); dock.Children.Add(more); dock.Children.Add(less); dock.Children.Add(edit); Docker.Children.Add(dock); editor = edit; } private static TimeSpan GetValue(DateTimeEdit edit) { var result = new TimeSpan(0); if (edit.DateTime.HasValue) result = edit.DateTime.Value.TimeOfDay; result = new TimeSpan(result.Hours, result.Minutes, 0); return result; } private static void SetValue(DateTimeEdit edit, TimeSpan value) { if (value.Ticks > 0) edit.DateTime = DateTime.MinValue.Add(value); else edit.DateTime = null; } private static TimeSpan GetValue(TimeSpanEdit edit) { var result = new TimeSpan(0); if (edit.Value.HasValue) result = edit.Value.Value; return result; } private static void SetValue(TimeSpanEdit edit, TimeSpan value) { edit.Value = value; } public override int DesiredHeight() { return 25; } public override int DesiredWidth() { return int.MaxValue; } protected override IEnumerable> GetChildValues() { yield return new("Start", Time.Start); yield return new("Duration", Time.Duration); yield return new("Finish", Time.Finish); } protected override object? GetChildValue(string property) { if (property == "Start") return Time.Start; if (property == "Duration") return Time.Duration; if (property == "Finish") return Time.Finish; return null; } protected override void SetChildValue(string property, object? value) { if (value is not TimeSpan timeSpan) return; if (property == "Start") Time.Start = timeSpan; else if (property == "Duration") Time.Duration = timeSpan; else if (property == "Finish") Time.Finish = timeSpan; UpdateEditors(); } public override void SetColor(Color color) { StartLabel.Background = new SolidColorBrush(color); Start.Background = new SolidColorBrush(color); DurationLabel.Background = new SolidColorBrush(color); Duration.Background = new SolidColorBrush(color); FinishLabel.Background = new SolidColorBrush(color); Finish.Background = new SolidColorBrush(color); } public override void SetFocus() { Start.Focus(); } } }