using System; using InABox.Core; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using InABox.Wpf; using InABox.WPF; using InABox.Wpf.DynamicGrid; using Address = InABox.Core.Address; namespace InABox.DynamicGrid; public class AddressEditorControl : DynamicEnclosedEditorControl { private Grid Grid = null!; // Late-initialized in CreateEditor //private TextBox SearchBox = null!; // Late-initialized in CreateEditor //private ListBox Suggestions = null!; private TextBox StreetBox = null!; // Late-initialized in CreateEditor private TextBox CityBox = null!; // Late-initialized in CreateEditor private TextBox StateBox = null!; // Late-initialized in CreateEditor private TextBox PostcodeBox = null!; // Late-initialized in CreateEditor private Button MapButton = null!; // Late-initialized in CreateEditor public override int DesiredHeight() { return int.MaxValue; } public override int DesiredWidth() { return int.MaxValue; } public override void SetColor(Color color) { StreetBox.Background = new SolidColorBrush(color); CityBox.Background = new SolidColorBrush(color); StateBox.Background = new SolidColorBrush(color); PostcodeBox.Background = new SolidColorBrush(color); } public override void SetFocus() { StreetBox.Focus(); } public override void Configure() { } protected override FrameworkElement CreateEditor() { Grid = new Grid { VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch }; Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) }); //Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); // SearchBox = new TextBox(); // SearchBox.SetValue(Grid.RowProperty, 0); // SearchBox.SetValue(Grid.ColumnProperty, 0); // SearchBox.SetValue(Grid.ColumnSpanProperty, 4); // SearchBox.TextChanged += (sender, args) => // { // bool visible = SearchBox.Text.Length >= 5; // if (visible != (Suggestions.Visibility == Visibility.Visible)) // ShowSearch(visible); // if (visible) // { // var addresses = Client.Query( // new Filter(x => x.Address).BeginsWith(SearchBox.Text), // Columns.None().Add(x => x.Address)); // Suggestions.ItemsSource = // addresses.ExtractValues(x => x.Address).OrderBy(x => x).ToArray(); // // } // }; // Grid.Children.Add(SearchBox); // // Suggestions = new ListBox(); // Suggestions.SetValue(Grid.RowProperty, 1); // Suggestions.SetValue(Grid.RowSpanProperty, 2); // Suggestions.SetValue(Grid.ColumnProperty, 0); // Suggestions.SetValue(Grid.ColumnSpanProperty, 4); // Suggestions.Visibility = Visibility.Collapsed; // Suggestions.SelectionChanged += (sender, args) => // { // SearchBox.Text = ""; // //ShowSearch(false); // }; // Grid.Children.Add(Suggestions); StreetBox = CreateBox(0, 0, 4, 0, 0.0, 0.0, nameof(Address.Street), "Street"); CityBox = CreateBox(1, 0, 1, 0, 0.0, 5.0, nameof(Address.City),"City"); StateBox = CreateBox(1, 1, 1, 150, 5.0, 5.0, nameof(Address.State),"State"); PostcodeBox = CreateBox(1,2,1,80, 5.0, 5.0, nameof(Address.PostCode),"Postcode"); MapButton = new Button(); MapButton.SetValue(Grid.RowProperty,1); MapButton.SetValue(Grid.ColumnProperty,3); MapButton.Width = 25.0; MapButton.Margin = new Thickness(5.0, 5.0, 0.0, 0.0); MapButton.BorderThickness = new Thickness(0.75); MapButton.Background = Brushes.Transparent; MapButton.Content = new Image() { Source = InABox.Wpf.Resources.map.AsBitmapImage() }; MapButton.Click += (sender, args) => ShowMap(); MapButton.Visibility = EditorDefinition.ShowMapButton ? Visibility.Visible : Visibility.Collapsed; Grid.Children.Add(MapButton); return Grid; } // private void ShowSearch(bool suggestions) // { // Suggestions.Visibility = suggestions ? Visibility.Visible : Visibility.Collapsed; // StreetBox.Visibility = suggestions ? Visibility.Collapsed : Visibility.Visible; // CityBox.Visibility = suggestions ? Visibility.Collapsed : Visibility.Visible; // StateBox.Visibility = suggestions ? Visibility.Collapsed : Visibility.Visible; // PostcodeBox.Visibility = suggestions ? Visibility.Collapsed : Visibility.Visible; // MapButton.Visibility = suggestions ? Visibility.Collapsed : Visibility.Visible; // } private void ShowMap() { var values = new Dictionary(GetChildValues()); var address = new Address(); if (values.TryGetValue(nameof(Address.Street), out var street)) address.Street = street?.ToString() ?? ""; if (values.TryGetValue(nameof(Address.City), out var city)) address.City = city?.ToString() ?? ""; if (values.TryGetValue(nameof(Address.State), out var state)) address.State = state?.ToString() ?? ""; if (values.TryGetValue(nameof(Address.PostCode), out var postcode)) address.PostCode = postcode?.ToString() ?? ""; if (values.TryGetValue(nameof(Address.Geofence), out var geofence)) address.Geofence = geofence?.ToString() ?? ""; if (values.TryGetValue($"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}", out var latitude)) address.Location.Latitude = latitude != null ? (double)latitude : 0.0; if (values.TryGetValue($"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}", out var longitude)) address.Location.Longitude = longitude != null ? (double)longitude : 0.0; var map = new GeofenceEditor(address, true); map.ShowDialog(); _latitude = address.Location.Latitude; _longitude = address.Location.Longitude; _geofence = address.Geofence; CheckChanged($"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}"); CheckChanged($"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}"); CheckChanged(nameof(Address.Geofence)); } private TextBox CreateBox(int row, int col, int colspan, double minWidth, double leftpad, double toppad, string property, string watermark) { var box = new TextBox(); box.SetValue(Grid.RowProperty,row); box.SetValue(Grid.ColumnProperty,col); box.SetValue(Grid.ColumnSpanProperty,Math.Max(1,colspan)); box.MinWidth = minWidth; box.Margin = new Thickness(leftpad, toppad, 0, 0); box.TextChanged += AddressChanged; box.LostFocus += CheckChanged; box.Tag = property; TextBoxUtils.SetPlaceholder(box, watermark); Grid.Children.Add(box); return box; } private bool _dirty = false; private void CheckChanged(object sender, RoutedEventArgs e) { if (sender is not TextBox box) return; CheckChanged((box.Tag as string)!); if (_dirty) { _latitude = 0.0; _longitude = 0.0; _geofence = ""; CheckChanged($"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}"); CheckChanged($"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}"); CheckChanged($"{nameof(Address.Geofence)}"); _dirty = false; } MapButton.Background = string.IsNullOrWhiteSpace(_geofence) ? Brushes.Red : Brushes.LightGreen; } private void AddressChanged(object sender, TextChangedEventArgs e) { _dirty = true; } public override void SetEnabled(bool enabled) { StreetBox.IsEnabled = enabled; CityBox.IsEnabled = enabled; StateBox.IsEnabled = enabled; PostcodeBox.IsEnabled = enabled; base.SetEnabled(enabled); } protected override object? GetChildValue(string property) { if (string.Equals(property,nameof(Address.Street))) return StreetBox.Text; if (string.Equals(property,nameof(Address.City))) return CityBox.Text; if (string.Equals(property,nameof(Address.State))) return StateBox.Text; if (string.Equals(property,nameof(Address.PostCode))) return PostcodeBox.Text; if (string.Equals(property, $"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}")) return _latitude; if (string.Equals(property, $"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}")) return _longitude; if (string.Equals(property,nameof(Address.Geofence))) return _geofence; return null; } protected override IEnumerable> GetChildValues() { yield return new(nameof(Address.Street), StreetBox.Text); yield return new(nameof(Address.City), CityBox.Text); yield return new(nameof(Address.State), StateBox.Text); yield return new(nameof(Address.PostCode), PostcodeBox.Text); yield return new($"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}", _latitude); yield return new($"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}", _longitude); yield return new(nameof(Address.Geofence), _geofence); } private double _latitude = 0.0; private double _longitude = 0.0; private String _geofence = ""; protected override void SetChildValue(string property, object? value) { if (string.Equals(property,nameof(Address.Street))) StreetBox.Text = value?.ToString() ?? ""; if (string.Equals(property,nameof(Address.City))) CityBox.Text = value?.ToString() ?? ""; if (string.Equals(property,nameof(Address.State))) StateBox.Text = value?.ToString() ?? ""; if (string.Equals(property,nameof(Address.PostCode))) PostcodeBox.Text = value?.ToString() ?? ""; if (string.Equals(property, $"{nameof(Address.Location)}.{nameof(Address.Location.Latitude)}")) _latitude = (double?)value ?? 0.0; if (string.Equals(property, $"{nameof(Address.Location)}.{nameof(Address.Location.Longitude)}")) _longitude = (double?)value ?? 0.0; if (string.Equals(property, nameof(Address.Geofence))) { _geofence = value?.ToString() ?? ""; MapButton.Background = string.IsNullOrWhiteSpace(_geofence) ? Brushes.Red : Brushes.LightGreen; } } }