diff --git a/Trimble.Modus.Components/Controls/DropDown/TMDropDown.cs b/Trimble.Modus.Components/Controls/DropDown/TMDropDown.cs index f15e1662..1e2a0b14 100644 --- a/Trimble.Modus.Components/Controls/DropDown/TMDropDown.cs +++ b/Trimble.Modus.Components/Controls/DropDown/TMDropDown.cs @@ -1,24 +1,24 @@ -using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Shapes; using System.Collections; using Trimble.Modus.Components.Constant; using Trimble.Modus.Components.Helpers; using Trimble.Modus.Components.Popup.Animations; using Trimble.Modus.Components.Popup.Services; using Grid = Microsoft.Maui.Controls.Grid; +using StackLayout = Microsoft.Maui.Controls.StackLayout; namespace Trimble.Modus.Components; public class TMDropDown : ContentView { private double desiredHeight; private Label label; - private PopupPage listPopup; - private Border innerBorder, listBorder; - private ListView listView; - private ImageButton indicatorButton; + private Border innerBorder; + private StackLayout indicatorButton; private bool isVisible; private int radius = 15; private IEnumerable items; - private int count = 0; + private int count = 0, margin = 96; private uint AnimationDuration { get; set; } = 250; public IEnumerable ItemsSource { @@ -45,7 +45,7 @@ public int SelectedIndex BindableProperty.Create(nameof(SelectedIndex), typeof(int), typeof(TMDropDown), 0, propertyChanged: OnSelectedIndexChanged); public new static readonly BindableProperty WidthRequestProperty = - BindableProperty.Create(nameof(WidthRequest), typeof(double), typeof(TMDropDown), double.NaN, propertyChanged: OnWidthRequestChanged); + BindableProperty.Create(nameof(WidthRequest), typeof(double), typeof(TMDropDown), 240.0, propertyChanged: OnWidthRequestChanged); public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(TMDropDown), null, propertyChanged: OnItemsSourceChanged); @@ -65,16 +65,19 @@ public TMDropDown() TextColor = Colors.White, VerticalOptions = LayoutOptions.Center }; - indicatorButton = new ImageButton + var chevronIcon = new Image { - Source = ImageConstants.ChevronDownIconWhite, + Source = ImageConstants.ChevronDownIconWhite, HeightRequest = 32, WidthRequest = 32, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center, + }; + indicatorButton = new StackLayout() + { Padding = new Thickness(0) }; - + indicatorButton.Children.Add(chevronIcon); var grid = new Grid { ColumnDefinitions = new ColumnDefinitionCollection @@ -94,6 +97,15 @@ public TMDropDown() grid.Add(label, 0, 0); grid.Add(indicatorButton, 1, 0); + var stack = new StackLayout + { + Orientation = StackOrientation.Horizontal, + HorizontalOptions = LayoutOptions.Center, + VerticalOptions = LayoutOptions.Center, + Spacing = 2, + }; + stack.Children.Add(label); + stack.Children.Add(indicatorButton); innerBorder = new Border { Stroke = ResourcesDictionary.ColorsDictionary(ColorsConstants.TrimbleBlue), @@ -105,86 +117,37 @@ public TMDropDown() { CornerRadius = new CornerRadius(4) }, - Content = grid, + Content = stack, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, - Padding = new Thickness(10) - }; - - Point offset = new Point(-1, 1); - if (DeviceInfo.Platform == DevicePlatform.iOS) - { - radius = 3; - offset = new Point(0, 2); - } - else if (DeviceInfo.Platform == DevicePlatform.WinUI) - { - radius = 3; - } - - var _shadow = new Shadow - { - Brush = Colors.Black, - Radius = radius, - Opacity = 0.6F, - Offset = offset - }; - listView = new ListView - { - IsVisible = true, - RowHeight = 48, - ItemTemplate = new DataTemplate(() => - { - var customCell = new DropDownViewCell(); - customCell.SetBinding(DropDownViewCell.TextProperty, "."); - return customCell; - }), + Padding = new Thickness(0) }; - listView.ItemSelected += OnSelected; var tapGestureRecognizer = new TapGestureRecognizer(); tapGestureRecognizer.Tapped += OnTapped; + innerBorder.GestureRecognizers.Add(tapGestureRecognizer); indicatorButton.GestureRecognizers.Add(tapGestureRecognizer); - listBorder = new Border() - { - Margin = new Thickness(0, 96, 0, 0), - Stroke = ResourcesDictionary.ColorsDictionary(ColorsConstants.DropDownListBorder), - HorizontalOptions = LayoutOptions.Start, - VerticalOptions = LayoutOptions.Start, - StrokeThickness = 4, - Shadow = _shadow, - Padding = new Thickness(8), - WidthRequest = 240, - StrokeShape = new RoundRectangle - { - CornerRadius = new CornerRadius(4) - }, - Content = listView, - IsVisible = true - }; - listPopup = new PopupPage(innerBorder, Enums.ModalPosition.Bottom); - listPopup.Content = listBorder; - listPopup.BackgroundColor = Colors.Transparent; - listPopup.Animation = null; PopupService.Instance.Dismissed += OnPopupRemoved; Content = innerBorder; } - private void OnSelected(object sender, SelectedItemChangedEventArgs e) + private void OnSelected(object sender, SelectedItemChangedEventArgs e, ListView list) { if (SelectedItems != null) { SelectedItems.Clear(); SelectedItems.Add(e.SelectedItem); - UpdateCellColor(); + UpdateCellColor(list); } label.Text = e.SelectedItem.ToString(); - if (count > 0) + if (count > 0 && PopupService.Instance.PopupStack.Count > 0) { - PopupService.Instance.RemovePageAsync(listPopup, false); + + PopupService.Instance?.DismissAsync(); Close(); } + SelectedIndex = e.SelectedItemIndex; count = 1; } @@ -212,38 +175,80 @@ await Task.WhenAll( private async void Open() { + var dataTemplate = new DataTemplate(() => + { + var customCell = new DropDownViewCell(); + customCell.SetBinding(DropDownViewCell.TextProperty, "."); + return customCell; + }); + var listview = new ListView() { ItemsSource = ItemsSource, RowHeight = 48, ItemTemplate = dataTemplate }; + listview.ItemSelected += (sender, e) => OnSelected(sender, e, listview); + listview.SelectedItem = listview.ItemsSource.Cast().ToList()[SelectedIndex]; + Point offset = new Point(-1, 1); + if (DeviceInfo.Platform == DevicePlatform.iOS) + { + radius = 3; + offset = new Point(0, 2); + } + else if (DeviceInfo.Platform == DevicePlatform.WinUI) + { + radius = 3; + } + + var _shadow = new Shadow + { + Brush = Colors.Black, + Radius = radius, + Opacity = 0.6F, + Offset = offset + }; + var border = new Border() + { + Margin = new Thickness(0, margin, 0, 0), + Stroke = ResourcesDictionary.ColorsDictionary(ColorsConstants.DropDownListBorder), + HorizontalOptions = LayoutOptions.Start, + VerticalOptions = LayoutOptions.Start, + StrokeThickness = 4, + Shadow = _shadow, + Padding = new Thickness(8), + WidthRequest = 240, + StrokeShape = new RoundRectangle + { + CornerRadius = new CornerRadius(4) + }, + Content = listview, + IsVisible = true + }; + + border.HeightRequest = desiredHeight; + border.WidthRequest = WidthRequest; + var popup = new PopupPage(innerBorder, Enums.ModalPosition.Bottom) + { + Content = border, + BackgroundColor = Colors.Transparent, + Animation = new RevealAnimation(desiredHeight), + }; var locationFetcher = new LocationFetcher(); var loc = locationFetcher.GetCoordinates(this); var height = Application.Current.MainPage.Window.Height; if (height - loc.Y < desiredHeight) { - listPopup._position = Enums.ModalPosition.Top; - listBorder.Margin = new Thickness(0); - } - else - { - listPopup._position = Enums.ModalPosition.Bottom; + popup._position = Enums.ModalPosition.Top; + border.Margin = new Thickness(0,-15,0,0); } await Task.WhenAll( indicatorButton.RotateTo(-180, AnimationDuration) ); - if (listPopup.Animation == null) - { - listPopup.Animation = new RevealAnimation(desiredHeight); - } - await PopupService.Instance.PresentAsync(listPopup, true); + await PopupService.Instance?.PresentAsync(popup, true); if (count == 0) { - var list = listView.ItemsSource.Cast().ToList(); + var list = listview.ItemsSource.Cast().ToList(); var item = list[SelectedIndex]; - Console.WriteLine(item.GetType()); - listView.SelectedItem = (object)item; - + listview.SelectedItem = (object)item; } count = 1; - - } + private void OnPopupRemoved(object sender, EventArgs e) { Close(); @@ -269,15 +274,14 @@ private static void OnWidthRequestChanged(BindableObject bindable, object oldVal if (bindable is TMDropDown dropDown && dropDown != null) { dropDown.innerBorder.WidthRequest = (double)newValue; - dropDown.listBorder.WidthRequest = (double)newValue; } } private void UpdateSelectedItem(int selectedIndex, IEnumerable items) { - if (selectedIndex >= 0 && selectedIndex < listView.ItemsSource.Cast().Count() && listView != null) + if (selectedIndex >= 0 && selectedIndex < items.Cast().Count() && items != null) { - label.Text = listView.ItemsSource.Cast().ElementAt(selectedIndex).ToString(); + label.Text = items.Cast().ElementAt(selectedIndex).ToString(); } } @@ -285,8 +289,6 @@ private void UpdateListViewItemsSource(IEnumerable items) { if (items != null) { - listView.ItemsSource = items.Cast().ToList(); - label.Text = (listView.ItemsSource as List)?.FirstOrDefault()?.ToString(); UpdateSelectedItem(SelectedIndex, items); } } @@ -300,19 +302,14 @@ private void UpdateListBorderHeight(IEnumerable items) if (itemCount < 4) { desiredHeight = itemCount * 56; - listBorder.HeightRequest = desiredHeight; - var margin = ((itemCount - 1) * 56)-28; - listBorder.Margin = new Thickness(0, margin, 0, 0); - } - else - { - listBorder.MaximumHeightRequest = desiredHeight; + margin = ((itemCount - 1) * 56) - 28; } } } - private void UpdateCellColor() + private void UpdateCellColor(ListView list) { - foreach (var item in listView.TemplatedItems) + + foreach (var item in list.TemplatedItems) { if (item is DropDownViewCell textCell) {