From d6c57a2a938f77609af294dad0b6ff4d6cd95686 Mon Sep 17 00:00:00 2001 From: Camilo Henao Date: Fri, 29 Nov 2024 07:15:08 -0500 Subject: [PATCH 01/12] =?UTF-8?q?Inicio=20migraci=C3=B3n=20MaterialChipsGr?= =?UTF-8?q?oup:=20attribuites,=20properties?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controls/Chips/MaterialChipsGroup.cs | 388 ++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs diff --git a/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs new file mode 100644 index 0000000..ea73375 --- /dev/null +++ b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs @@ -0,0 +1,388 @@ + +namespace HorusStudio.Maui.MaterialDesignControls.Controls.Chips; + +/// +/// A Chips help people enter information, make selections, filter content, or trigger actions see here. +/// +/// +/// +/// https://raw.githubusercontent.com/HorusSoftwareUY/MaterialDesignControlsPlugin/develop/screenshots/MaterialChips.gif +/// +///

XAML sample

+/// +/// +/// xmlns:material="clr-namespace:HorusStudio.Maui.MaterialDesignControls;assembly=HorusStudio.Maui.MaterialDesignControls" +/// +/// <material:MaterialChips +/// Type="Normal" +/// IconStateOnSelection="BothVisible" +/// LeadingIcon="plus.png" +/// Text="Suggestion both" +/// TrailingIcon="horus_logo.png"/> +/// +/// +/// +///

C# sample

+/// +/// var chips = new MaterialChips +/// { +/// Type = MaterialChipsType.Normal, +/// IconStateOnSelection = IconStateType.BothVisible, +/// LeadingIcon = "plus.png", +/// Text = "Suggestion both", +/// TrailingIcon="horus_logo.png" +/// }; +/// +/// +/// [See more example](../../samples/HorusStudio.Maui.MaterialDesignControls.Sample/Pages/ChipsPage.xaml) +/// +///
+/// +/// * Modify all comments before this line +/// +public class MaterialChipsGroup : ContentView +{ + #region Attributes + + private readonly static bool DefaultToUpper = false; + private readonly static Thickness DefaultPadding = new Thickness(12, 0); + private readonly static Thickness DefaultChipsPadding = new Thickness(16, 0); + private readonly static Thickness DefaultChipsMargin = new Thickness(6); + private readonly static double DefaultChipsHeightRequest = 32.0; + private readonly static double DefaultChipsFlexLayoutBasisPercentage = 0.0; + private readonly static bool DefaultIsEnabled = true; + private readonly static string DefaultLabelText = null; + private readonly static IEnumerable DefaultItemsSource = null; + private readonly static string DefaultSelectedItem = null; + private readonly static List DefaultSelectedItems = null; + private readonly static string DefaultSupportingText = null; + private readonly static Color DefaultLabelTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Text, Dark = MaterialLightTheme.Text }.GetValueForCurrentTheme(); + private readonly static Color DefaultSupportingTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Error, Dark = MaterialLightTheme.Error }.GetValueForCurrentTheme(); + private readonly static double DefaultLabelSize = MaterialFontSize.BodySmall; + private readonly static double DefaultSupportingSize = MaterialFontSize.BodySmall; + private readonly static Color DefaultTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); + private readonly static Color DefaultSelectedTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.OnPrimary, Dark = MaterialLightTheme.OnPrimary }.GetValueForCurrentTheme(); + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //private readonly static Color DefaultDisabledTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Disable, Dark = MaterialLightTheme.Disable }.GetValueForCurrentTheme(); + private readonly static Color DefaultDisabledSelectedTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Text, Dark = MaterialLightTheme.Text }.GetValueForCurrentTheme(); + private readonly static Color DefaultBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.PrimaryContainer, Dark = MaterialLightTheme.PrimaryContainer }.GetValueForCurrentTheme(); + private readonly static Color DefaultSelectedBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //private readonly static Color DefaultDisabledBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.DisableContainer, Dark = MaterialLightTheme.DisableContainer }.GetValueForCurrentTheme(); + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //private readonly static Color DefaultDisabledSelectedBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Disable, Dark = MaterialLightTheme.Disable }.GetValueForCurrentTheme(); + private readonly static Color DefaultBorderColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); + private readonly static double DefaultFontSize = MaterialFontSize.LabelLarge; + private readonly static string DefaultFontFamily = MaterialFontFamily.Default; + private readonly static double DefaultCornerRadius = 16.0; + private readonly static bool DefaultAnimateError = MaterialAnimation.AnimateOnError; + private readonly static bool DefaultIsMultipleSelection = false; + private readonly static AnimationTypes DefaultAnimation = MaterialAnimation.Type; + private readonly static double? DefaultAnimationParameter = MaterialAnimation.Parameter; + + #endregion + + #region Bindable Properties + + public static readonly BindableProperty ToUpperProperty = BindableProperty.Create(nameof(ToUpper), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultToUpper); + + public static readonly new BindableProperty PaddingProperty = BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(MaterialChipsGroup), defaultValue: DefaultPadding); + + public static readonly BindableProperty ChipsPaddingProperty = BindableProperty.Create(nameof(ChipsPadding), typeof(Thickness), typeof(MaterialChipsGroup), defaultValue: DefaultChipsPadding); + + public static readonly BindableProperty ChipsMarginProperty = BindableProperty.Create(nameof(ChipsMargin), typeof(Thickness), typeof(MaterialChipsGroup), defaultValue: DefaultChipsMargin); + + public static readonly BindableProperty ChipsHeightRequestProperty = BindableProperty.Create(nameof(ChipsHeightRequest), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultChipsHeightRequest); + + public static readonly BindableProperty ChipsFlexLayoutBasisPercentageProperty = BindableProperty.Create(nameof(ChipsFlexLayoutPercentageBasis), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultChipsFlexLayoutBasisPercentage); + + public static readonly new BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultIsEnabled); + + public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(nameof(LabelText), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultLabelText); + + public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(MaterialChipsGroup), defaultValue: DefaultItemsSource, propertyChanged: (bindable, oldValue, newValue) => + { + if (bindable is MaterialChipsGroup self) + { + // self.SetState(self.Type); + } + }); + + public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(nameof(SelectedItem), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedItem, propertyChanged: (bindable, oldValue, newValue) => + { + if (bindable is MaterialChipsGroup self) + { + // self.SetState(self.Type); + } + }); + + public static readonly BindableProperty SelectedItemsProperty = BindableProperty.Create(nameof(SelectedItems), typeof(List), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedItems, propertyChanged: (bindable, oldValue, newValue) => + { + if (bindable is MaterialChipsGroup self) + { + // self.SetState(self.Type); + } + }); + + //TODO: Validar como manejar el último parámetro que venía en esta propiedad: , validateValue: OnSupportingTextValidate + public static readonly BindableProperty SupportingTextProperty = BindableProperty.Create(nameof(SupportingText), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingText); + + public static readonly BindableProperty LabelTextColorProperty = BindableProperty.Create(nameof(LabelTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultLabelTextColor); + + public static readonly BindableProperty SupportingTextColorProperty = BindableProperty.Create(nameof(SupportingTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingTextColor); + + public static readonly BindableProperty LabelSizeProperty = BindableProperty.Create(nameof(LabelSize), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultLabelSize); + + public static readonly BindableProperty SupportingSizeProperty = BindableProperty.Create(nameof(SupportingSize), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingSize); + + public static readonly BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultTextColor); + + public static readonly BindableProperty SelectedTextColorProperty = BindableProperty.Create(nameof(SelectedTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedTextColor); + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public static readonly BindableProperty DisabledTextColorProperty = BindableProperty.Create(nameof(DisabledTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledTextColor); + + public static readonly BindableProperty DisabledSelectedTextColorProperty = BindableProperty.Create(nameof(DisabledSelectedTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledSelectedTextColor); + + public static readonly new BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultBackgroundColor); + + public static readonly BindableProperty SelectedBackgroundColorProperty = BindableProperty.Create(nameof(SelectedBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedBackgroundColor); + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public static readonly BindableProperty DisabledBackgroundColorProperty = BindableProperty.Create(nameof(DisabledBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledBackgroundColor); + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public static readonly BindableProperty DisabledSelectedBackgroundColorProperty = BindableProperty.Create(nameof(DisabledSelectedBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledSelectedBackgroundColor); + + public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultBorderColor); + + public static readonly BindableProperty FontSizeProperty = BindableProperty.Create(nameof(FontSize), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultFontSize); + + public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultFontFamily); + + public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultCornerRadius); + + public static readonly BindableProperty AnimateErrorProperty = BindableProperty.Create(nameof(AnimateError), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultAnimateError); + + public static readonly BindableProperty IsMultipleSelectionProperty = BindableProperty.Create(nameof(IsMultipleSelection), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultIsMultipleSelection); + + public static readonly BindableProperty AnimationProperty = BindableProperty.Create(nameof(Animation), typeof(AnimationTypes), typeof(MaterialChips), defaultValue: DefaultAnimation); + + public static readonly BindableProperty AnimationParameterProperty = BindableProperty.Create(nameof(AnimationParameter), typeof(double?), typeof(MaterialChips), defaultValue: DefaultAnimationParameter); + + #endregion + + #region Properties + + public bool ToUpper + { + get { return (bool)GetValue(ToUpperProperty); } + set { SetValue(ToUpperProperty, value); } + } + + public new Thickness Padding + { + get { return (Thickness)GetValue(PaddingProperty); } + set { SetValue(PaddingProperty, value); } + } + + public Thickness ChipsPadding + { + get { return (Thickness)GetValue(ChipsPaddingProperty); } + set { SetValue(ChipsPaddingProperty, value); } + } + + public Thickness ChipsMargin + { + get { return (Thickness)GetValue(ChipsMarginProperty); } + set { SetValue(ChipsMarginProperty, value); } + } + + public double ChipsHeightRequest + { + get { return (double)GetValue(ChipsHeightRequestProperty); } + set { SetValue(ChipsHeightRequestProperty, value); } + } + + public double ChipsFlexLayoutPercentageBasis + { + get { return (double)GetValue(ChipsFlexLayoutBasisPercentageProperty); } + set { SetValue(ChipsFlexLayoutBasisPercentageProperty, value); } + } + + public new bool IsEnabled + { + get { return (bool)GetValue(IsEnabledProperty); } + set { SetValue(IsEnabledProperty, value); } + } + + public string LabelText + { + get { return (string)GetValue(LabelTextProperty); } + set { SetValue(LabelTextProperty, value); } + } + + public IEnumerable ItemsSource + { + get { return (IEnumerable)GetValue(ItemsSourceProperty); } + set { SetValue(ItemsSourceProperty, value); } + } + + public string SelectedItem + { + get { return (string)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + + public List SelectedItems + { + get { return (List)GetValue(SelectedItemsProperty); } + set { SetValue(SelectedItemsProperty, value); } + } + + public string SupportingText + { + get { return (string)GetValue(SupportingTextProperty); } + set { SetValue(SupportingTextProperty, value); } + } + + public Color LabelTextColor + { + get { return (Color)GetValue(LabelTextColorProperty); } + set { SetValue(LabelTextColorProperty, value); } + } + + public Color SupportingTextColor + { + get { return (Color)GetValue(SupportingTextColorProperty); } + set { SetValue(SupportingTextColorProperty, value); } + } + + public double LabelSize + { + get { return (double)GetValue(LabelSizeProperty); } + set { SetValue(LabelSizeProperty, value); } + } + + public double SupportingSize + { + get { return (double)GetValue(SupportingSizeProperty); } + set { SetValue(SupportingSizeProperty, value); } + } + + public Color TextColor + { + get { return (Color)GetValue(TextColorProperty); } + set { SetValue(TextColorProperty, value); } + } + + public Color SelectedTextColor + { + get { return (Color)GetValue(SelectedTextColorProperty); } + set { SetValue(SelectedTextColorProperty, value); } + } + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public Color DisabledTextColor + //{ + // get { return (Color)GetValue(DisabledTextColorProperty); } + // set { SetValue(DisabledTextColorProperty, value); } + //} + + public Color DisabledSelectedTextColor + { + get { return (Color)GetValue(DisabledSelectedTextColorProperty); } + set { SetValue(DisabledSelectedTextColorProperty, value); } + } + + public new Color BackgroundColor + { + get { return (Color)GetValue(BackgroundColorProperty); } + set { SetValue(BackgroundColorProperty, value); } + } + + public Color SelectedBackgroundColor + { + get { return (Color)GetValue(SelectedBackgroundColorProperty); } + set { SetValue(SelectedBackgroundColorProperty, value); } + } + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public Color DisabledBackgroundColor + //{ + // get { return (Color)GetValue(DisabledBackgroundColorProperty); } + // set { SetValue(DisabledBackgroundColorProperty, value); } + //} + + //TODO: Validar si la propiedad continua y cual es el equivalente del color + //public Color DisabledSelectedBackgroundColor + //{ + // get { return (Color)GetValue(DisabledSelectedBackgroundColorProperty); } + // set { SetValue(DisabledSelectedBackgroundColorProperty, value); } + //} + + public Color BorderColor + { + get { return (Color)GetValue(BorderColorProperty); } + set { SetValue(BorderColorProperty, value); } + } + + public double FontSize + { + get { return (double)GetValue(FontSizeProperty); } + set { SetValue(FontSizeProperty, value); } + } + + public string FontFamily + { + get { return (string)GetValue(FontFamilyProperty); } + set { SetValue(FontFamilyProperty, value); } + } + + public double CornerRadius + { + get { return (double)GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + public bool AnimateError + { + get { return (bool)GetValue(AnimateErrorProperty); } + set { SetValue(AnimateErrorProperty, value); } + } + + public bool IsMultipleSelection + { + get { return (bool)GetValue(IsMultipleSelectionProperty); } + set { SetValue(IsMultipleSelectionProperty, value); } + } + + public AnimationTypes Animation + { + get { return (AnimationTypes)GetValue(AnimationProperty); } + set { SetValue(AnimationProperty, value); } + } + + public double? AnimationParameter + { + get { return (double?)GetValue(AnimationParameterProperty); } + set { SetValue(AnimationParameterProperty, value); } + } + + #endregion + + #region Events + #endregion + + #region Layout + #endregion + + #region Constructor + #endregion + + #region Setters + #endregion + + #region Styles + #endregion +} \ No newline at end of file From 48ceedf2fc5c87c7fd8adddfe3645bb1e9512a17 Mon Sep 17 00:00:00 2001 From: Camilo Henao Date: Fri, 29 Nov 2024 11:44:35 -0500 Subject: [PATCH 02/12] =?UTF-8?q?Migraci=C3=B3n=20chips=20group,=20creaci?= =?UTF-8?q?=C3=B3n=20de=20layouts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controls/Chips/MaterialChipsGroup.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs index ea73375..e7443df 100644 --- a/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs +++ b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs @@ -1,4 +1,6 @@  +using Microsoft.Maui.Layouts; + namespace HorusStudio.Maui.MaterialDesignControls.Controls.Chips; /// @@ -375,9 +377,53 @@ public double? AnimationParameter #endregion #region Layout + + private StackLayout _container; + private MaterialLabel _lblLabel; + private FlexLayout _flexContainer; + private MaterialLabel _lblSupporting; + #endregion #region Constructor + + public MaterialChipsGroup() + { + _container = new StackLayout() + { + Spacing = 2, + }; + + _lblLabel = new MaterialLabel() + { + IsVisible = false, + LineBreakMode = LineBreakMode.NoWrap, + Margin = new Thickness(14, 0, 14, 2), + HorizontalTextAlignment = TextAlignment.Start, + TextColor = LabelTextColor, + FontFamily = FontFamily, + FontSize = LabelSize + }; + + _flexContainer = new FlexLayout() + { + Wrap = FlexWrap.Wrap, + Direction = FlexDirection.Row, + JustifyContent = FlexJustify.Start + }; + + _lblSupporting = new MaterialLabel() + { + IsVisible = false, + LineBreakMode = LineBreakMode.NoWrap, + Margin = new Thickness(14, 2, 14, 0), + HorizontalTextAlignment = TextAlignment.Start, + TextColor = SupportingTextColor, + FontFamily = FontFamily, + FontSize = SupportingSize + }; + } + #endregion #region Setters From 590e6f9de81bcbb0d6e864f9a844e9445c52c32e Mon Sep 17 00:00:00 2001 From: Camilo Henao Date: Sat, 30 Nov 2024 14:36:02 -0500 Subject: [PATCH 03/12] MaterialChipsGroup: Setters and removing unnecessary properties --- .../Controls/Chips/MaterialChipsGroup.cs | 282 ++++++++++++------ .../Converters/TextToBooleanConverter.cs | 17 ++ 2 files changed, 203 insertions(+), 96 deletions(-) create mode 100644 src/HorusStudio.Maui.MaterialDesignControls/Converters/TextToBooleanConverter.cs diff --git a/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs index e7443df..5f6abd3 100644 --- a/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs +++ b/src/HorusStudio.Maui.MaterialDesignControls/Controls/Chips/MaterialChipsGroup.cs @@ -1,19 +1,21 @@  +using HorusStudio.Maui.MaterialDesignControls; +using HorusStudio.Maui.MaterialDesignControls.Converters; using Microsoft.Maui.Layouts; -namespace HorusStudio.Maui.MaterialDesignControls.Controls.Chips; +namespace HorusStudio.Maui.MaterialDesign..Chips; /// /// A Chips help people enter information, make selections, filter content, or trigger actions see here. /// /// /// -/// https://raw.githubusercontent.com/HorusSoftwareUY/MaterialDesignControlsPlugin/develop/screenshots/MaterialChips.gif +/// https://raw.githubusercontent.com/HorusSoftwareUY/MaterialDesignPlugin/develop/screenshots/MaterialChips.gif /// ///

XAML sample

/// /// -/// xmlns:material="clr-namespace:HorusStudio.Maui.MaterialDesignControls;assembly=HorusStudio.Maui.MaterialDesignControls" +/// xmlns:material="clr-namespace:HorusStudio.Maui.MaterialDesign;assembly=HorusStudio.Maui.MaterialDesign" /// /// <material:MaterialChips /// Type="Normal" @@ -36,7 +38,7 @@ namespace HorusStudio.Maui.MaterialDesignControls.Controls.Chips; /// }; /// /// -/// [See more example](../../samples/HorusStudio.Maui.MaterialDesignControls.Sample/Pages/ChipsPage.xaml) +/// [See more example](../../samples/HorusStudio.Maui.MaterialDesign.Sample/Pages/ChipsPage.xaml) /// ///
/// @@ -45,8 +47,7 @@ namespace HorusStudio.Maui.MaterialDesignControls.Controls.Chips; public class MaterialChipsGroup : ContentView { #region Attributes - - private readonly static bool DefaultToUpper = false; + private readonly static Thickness DefaultPadding = new Thickness(12, 0); private readonly static Thickness DefaultChipsPadding = new Thickness(16, 0); private readonly static Thickness DefaultChipsMargin = new Thickness(6); @@ -62,17 +63,8 @@ public class MaterialChipsGroup : ContentView private readonly static Color DefaultSupportingTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Error, Dark = MaterialLightTheme.Error }.GetValueForCurrentTheme(); private readonly static double DefaultLabelSize = MaterialFontSize.BodySmall; private readonly static double DefaultSupportingSize = MaterialFontSize.BodySmall; - private readonly static Color DefaultTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); - private readonly static Color DefaultSelectedTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.OnPrimary, Dark = MaterialLightTheme.OnPrimary }.GetValueForCurrentTheme(); - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //private readonly static Color DefaultDisabledTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Disable, Dark = MaterialLightTheme.Disable }.GetValueForCurrentTheme(); - private readonly static Color DefaultDisabledSelectedTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Text, Dark = MaterialLightTheme.Text }.GetValueForCurrentTheme(); - private readonly static Color DefaultBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.PrimaryContainer, Dark = MaterialLightTheme.PrimaryContainer }.GetValueForCurrentTheme(); - private readonly static Color DefaultSelectedBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //private readonly static Color DefaultDisabledBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.DisableContainer, Dark = MaterialLightTheme.DisableContainer }.GetValueForCurrentTheme(); - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //private readonly static Color DefaultDisabledSelectedBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Disable, Dark = MaterialLightTheme.Disable }.GetValueForCurrentTheme(); + private readonly static Color DefaultTextColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); + private readonly static Color DefaultBackgroundColor = new AppThemeBindingExtension { Light = MaterialLightTheme.PrimaryContainer, Dark = MaterialLightTheme.PrimaryContainer }.GetValueForCurrentTheme(); private readonly static Color DefaultBorderColor = new AppThemeBindingExtension { Light = MaterialLightTheme.Primary, Dark = MaterialLightTheme.Primary }.GetValueForCurrentTheme(); private readonly static double DefaultFontSize = MaterialFontSize.LabelLarge; private readonly static string DefaultFontFamily = MaterialFontFamily.Default; @@ -86,8 +78,6 @@ public class MaterialChipsGroup : ContentView #region Bindable Properties - public static readonly BindableProperty ToUpperProperty = BindableProperty.Create(nameof(ToUpper), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultToUpper); - public static readonly new BindableProperty PaddingProperty = BindableProperty.Create(nameof(Padding), typeof(Thickness), typeof(MaterialChipsGroup), defaultValue: DefaultPadding); public static readonly BindableProperty ChipsPaddingProperty = BindableProperty.Create(nameof(ChipsPadding), typeof(Thickness), typeof(MaterialChipsGroup), defaultValue: DefaultChipsPadding); @@ -98,7 +88,13 @@ public class MaterialChipsGroup : ContentView public static readonly BindableProperty ChipsFlexLayoutBasisPercentageProperty = BindableProperty.Create(nameof(ChipsFlexLayoutPercentageBasis), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultChipsFlexLayoutBasisPercentage); - public static readonly new BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultIsEnabled); + public static readonly new BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(MaterialChipsGroup), defaultValue: DefaultIsEnabled, propertyChanged: (bindable, oldValue, newValue) => + { + if (bindable is MaterialChipsGroup self) + { + self.SetIsEnabled(newValue); + } + }); public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(nameof(LabelText), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultLabelText); @@ -106,15 +102,15 @@ public class MaterialChipsGroup : ContentView { if (bindable is MaterialChipsGroup self) { - // self.SetState(self.Type); + self.SetItemsSource(newValue); } - }); + }); public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(nameof(SelectedItem), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedItem, propertyChanged: (bindable, oldValue, newValue) => { if (bindable is MaterialChipsGroup self) { - // self.SetState(self.Type); + self.SetSelectedItem(); } }); @@ -122,12 +118,18 @@ public class MaterialChipsGroup : ContentView { if (bindable is MaterialChipsGroup self) { - // self.SetState(self.Type); + self.SetSelectedItems(); } }); - //TODO: Validar como manejar el último parámetro que venía en esta propiedad: , validateValue: OnSupportingTextValidate - public static readonly BindableProperty SupportingTextProperty = BindableProperty.Create(nameof(SupportingText), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingText); + public static readonly BindableProperty SupportingTextProperty = BindableProperty.Create(nameof(SupportingText), typeof(string), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingText, propertyChanged: async (bindable, oldValue, newValue) => + { + if (bindable is MaterialChipsGroup self) + { + await self.ValidateText(newValue); + } + + }); public static readonly BindableProperty LabelTextColorProperty = BindableProperty.Create(nameof(LabelTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultLabelTextColor); @@ -137,24 +139,9 @@ public class MaterialChipsGroup : ContentView public static readonly BindableProperty SupportingSizeProperty = BindableProperty.Create(nameof(SupportingSize), typeof(double), typeof(MaterialChipsGroup), defaultValue: DefaultSupportingSize); - public static readonly BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultTextColor); - - public static readonly BindableProperty SelectedTextColorProperty = BindableProperty.Create(nameof(SelectedTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedTextColor); - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public static readonly BindableProperty DisabledTextColorProperty = BindableProperty.Create(nameof(DisabledTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledTextColor); - - public static readonly BindableProperty DisabledSelectedTextColorProperty = BindableProperty.Create(nameof(DisabledSelectedTextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledSelectedTextColor); + public static readonly BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultTextColor); - public static readonly new BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultBackgroundColor); - - public static readonly BindableProperty SelectedBackgroundColorProperty = BindableProperty.Create(nameof(SelectedBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultSelectedBackgroundColor); - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public static readonly BindableProperty DisabledBackgroundColorProperty = BindableProperty.Create(nameof(DisabledBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledBackgroundColor); - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public static readonly BindableProperty DisabledSelectedBackgroundColorProperty = BindableProperty.Create(nameof(DisabledSelectedBackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultDisabledSelectedBackgroundColor); + public static readonly new BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultBackgroundColor); public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(MaterialChipsGroup), defaultValue: DefaultBorderColor); @@ -176,12 +163,6 @@ public class MaterialChipsGroup : ContentView #region Properties - public bool ToUpper - { - get { return (bool)GetValue(ToUpperProperty); } - set { SetValue(ToUpperProperty, value); } - } - public new Thickness Padding { get { return (Thickness)GetValue(PaddingProperty); } @@ -278,51 +259,12 @@ public Color TextColor set { SetValue(TextColorProperty, value); } } - public Color SelectedTextColor - { - get { return (Color)GetValue(SelectedTextColorProperty); } - set { SetValue(SelectedTextColorProperty, value); } - } - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public Color DisabledTextColor - //{ - // get { return (Color)GetValue(DisabledTextColorProperty); } - // set { SetValue(DisabledTextColorProperty, value); } - //} - - public Color DisabledSelectedTextColor - { - get { return (Color)GetValue(DisabledSelectedTextColorProperty); } - set { SetValue(DisabledSelectedTextColorProperty, value); } - } - public new Color BackgroundColor { get { return (Color)GetValue(BackgroundColorProperty); } set { SetValue(BackgroundColorProperty, value); } } - public Color SelectedBackgroundColor - { - get { return (Color)GetValue(SelectedBackgroundColorProperty); } - set { SetValue(SelectedBackgroundColorProperty, value); } - } - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public Color DisabledBackgroundColor - //{ - // get { return (Color)GetValue(DisabledBackgroundColorProperty); } - // set { SetValue(DisabledBackgroundColorProperty, value); } - //} - - //TODO: Validar si la propiedad continua y cual es el equivalente del color - //public Color DisabledSelectedBackgroundColor - //{ - // get { return (Color)GetValue(DisabledSelectedBackgroundColorProperty); } - // set { SetValue(DisabledSelectedBackgroundColorProperty, value); } - //} - public Color BorderColor { get { return (Color)GetValue(BorderColorProperty); } @@ -378,8 +320,7 @@ public double? AnimationParameter #region Layout - private StackLayout _container; - private MaterialLabel _lblLabel; + private MaterialLabel _textLabel; private FlexLayout _flexContainer; private MaterialLabel _lblSupporting; @@ -389,12 +330,7 @@ public double? AnimationParameter public MaterialChipsGroup() { - _container = new StackLayout() - { - Spacing = 2, - }; - - _lblLabel = new MaterialLabel() + _textLabel = new MaterialLabel() { IsVisible = false, LineBreakMode = LineBreakMode.NoWrap, @@ -422,13 +358,167 @@ public MaterialChipsGroup() FontFamily = FontFamily, FontSize = SupportingSize }; + + var container = new StackLayout() + { + _textLabel, + _flexContainer, + _lblSupporting + }; + + _textLabel.SetBinding(Label.TextProperty, new Binding(nameof(LabelText), source: this)); + _textLabel.SetBinding(Label.IsVisibleProperty, new Binding(nameof(LabelText), source: this, converter: new TextToBooleanConverter())); + _textLabel.SetBinding(Label.TextColorProperty, new Binding(nameof(TextColor), source: this)); + _textLabel.SetBinding(Label.FontFamilyProperty, new Binding(nameof(FontFamily), source: this)); + _textLabel.SetBinding(Label.FontSizeProperty, new Binding(nameof(FontSize), source: this)); + + _flexContainer.SetBinding(FlexLayout.PaddingProperty, new Binding(nameof(Padding), source: this)); + + _lblSupporting.SetBinding(MaterialLabel.PaddingProperty, new Binding(nameof(Padding), source: this)); + _lblSupporting.SetBinding(MaterialLabel.TextColorProperty, new Binding(nameof(SupportingText), source: this)); + _lblSupporting.SetBinding(MaterialLabel.FontSizeProperty, new Binding(nameof(SupportingSize), source: this)); + _lblSupporting.SetBinding(MaterialLabel.IsVisibleProperty, new Binding(nameof(SupportingSize), source: this, converter: new TextToBooleanConverter())); + + container.Spacing = 2; + + Content = container; } #endregion #region Setters + + private async Task ValidateText(object value) + { + if (AnimateError && !string.IsNullOrEmpty(SupportingText) && SupportingText == (string)value) + await ShakeAnimation.AnimateAsync(Content); + + return true; + } + + private void SetSelectedItem() + { + if (_flexContainer.Children != null && SelectedItem != null) + { + foreach (var item in _flexContainer.Children) + { + if (item is MaterialChips itemMC) + itemMC.IsSelected = itemMC.Text.Equals(SelectedItem); + } + } + } + + private void SetSelectedItems() + { + if (_flexContainer.Children != null && SelectedItems != null && SelectedItems.Any()) + { + foreach (var item in _flexContainer.Children) + { + if (item is MaterialChips itemMC) + itemMC.IsSelected = SelectedItems.Contains((itemMC).Text); + } + } + } + + private void SetItemsSource(object newValue) + { + _flexContainer.Children.Clear(); + + if (newValue != null && newValue is IEnumerable) + { + foreach (var item in (IEnumerable)newValue) + { + var materialChips = new MaterialChips + { + Text = item.ToString(), + FontSize = FontSize, + FontFamily = FontFamily, + CornerRadius = CornerRadius, + Padding = ChipsPadding, + Margin = ChipsMargin, + BackgroundColor = BackgroundColor, + TextColor = TextColor, + BorderColor = BorderColor, + IsEnabled = IsEnabled, + Animation = Animation, + AnimationParameter = AnimationParameter + }; + + materialChips.HeightRequest = ChipsHeightRequest; + + if (IsMultipleSelection) + { + if (SelectedItems != null && SelectedItems.Any()) + materialChips.IsSelected = SelectedItems.Contains(materialChips.Text); + } + else + { + if (SelectedItem != null) + materialChips.IsSelected = materialChips.Text.Equals(SelectedItem); + } + + materialChips.Command = new Command(() => SelectionCommand(materialChips)); + + _flexContainer.Children.Add(materialChips); + + if (ChipsFlexLayoutPercentageBasis > 0 && ChipsFlexLayoutPercentageBasis <= 1) + FlexLayout.SetBasis(materialChips, new FlexBasis((float)ChipsFlexLayoutPercentageBasis, true)); + } + } + } + + private void SetIsEnabled(object newValue) + { + foreach (var view in _flexContainer.Children) + { + if (view is MaterialChips materialChips) + materialChips.IsEnabled = IsEnabled; + } + } + + private void SelectionCommand(MaterialChips materialChips) + { + if (!IsEnabled) + return; + + if (materialChips is MaterialChips) + { + if (IsMultipleSelection) + { + var selectedItems = SelectedItems == null ? new List() : SelectedItems.Select(x => x).ToList(); + + materialChips.IsSelected = !materialChips.IsSelected; + + if (materialChips.IsSelected && !selectedItems.Contains(materialChips.Text)) + selectedItems.Add(materialChips.Text); + else if (selectedItems.Contains(materialChips.Text)) + selectedItems.Remove(materialChips.Text); + + SelectedItems = selectedItems; + } + else + { + foreach (var item in _flexContainer.Children) + { + ((MaterialChips)item).IsSelected = false; + } + + materialChips.IsSelected = !materialChips.IsSelected; + + SelectedItem = materialChips.Text; + } + } + } + + #endregion #region Styles + + internal static IEnumerable