Skip to content

Commit 71189e6

Browse files
Merge branch 'main' of https://github.com/syncfusion/maui-toolkit into BottomSheetAllowedState
2 parents dbc7e31 + fa29e20 commit 71189e6

File tree

7 files changed

+192
-21
lines changed

7 files changed

+192
-21
lines changed

maui/src/Accordion/AccordionItem.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,6 @@ static void OnIsExpandedPropertyChanged(BindableObject bindable, object oldValue
462462
// Content does not get collapsed when item is being collapsed in PCL view.
463463
if (bindable is AccordionItem accordionItem)
464464
{
465-
if (accordionItem.Content != null && (bool)newValue && accordionItem.Content.IsVisible)
466-
{
467-
accordionItem.Content.IsVisible = true;
468-
}
469-
470465
if (accordionItem._accordion != null && accordionItem._accordionItemView != null && accordionItem._accordionItemView.IsExpanded != accordionItem.IsExpanded)
471466
{
472467
accordionItem.OnIsExpandedChanging((bool)newValue);

maui/src/Accordion/SfAccordion.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ internal override Size LayoutMeasure(double widthConstraint, double heightConstr
13921392
/// <param name="newValue">The new value of expand mode property. </param>
13931393
static void OnExpandModePropertyChanged(BindableObject bindable, object oldValue, object newValue)
13941394
{
1395-
if (bindable is SfAccordion accordion)
1395+
if (bindable is SfAccordion accordion && accordion.IsViewLoaded)
13961396
{
13971397
accordion.UpdateAccordionItemsBasedOnExpandModes(true);
13981398
}
@@ -1406,7 +1406,7 @@ static void OnExpandModePropertyChanged(BindableObject bindable, object oldValue
14061406
/// <param name="newValue">The new value of item spacing property. </param>
14071407
static void OnItemSpacingPropertyChanged(BindableObject bindable, object oldValue, object newValue)
14081408
{
1409-
if (bindable is SfAccordion accordion)
1409+
if (bindable is SfAccordion accordion && accordion.IsViewLoaded)
14101410
{
14111411
foreach (var item in accordion.Items)
14121412
{
@@ -1427,7 +1427,7 @@ static void OnItemSpacingPropertyChanged(BindableObject bindable, object oldValu
14271427
/// <param name="newValue">The new value of animation duration property. </param>
14281428
static void OnAnimationDurationPropertyChanged(BindableObject bindable, object oldValue, object newValue)
14291429
{
1430-
if (bindable is SfAccordion accordion)
1430+
if (bindable is SfAccordion accordion && accordion.IsViewLoaded)
14311431
{
14321432
foreach (AccordionItem item in accordion.Items)
14331433
{
@@ -1447,7 +1447,7 @@ static void OnAnimationDurationPropertyChanged(BindableObject bindable, object o
14471447
/// <param name="newValue">The new value of animation easing property. </param>
14481448
static void OnAnimationEasingPropertyChanged(BindableObject bindable, object oldValue, object newValue)
14491449
{
1450-
if (bindable is SfAccordion accordion)
1450+
if (bindable is SfAccordion accordion && accordion.IsViewLoaded)
14511451
{
14521452
foreach (AccordionItem item in accordion.Items)
14531453
{
@@ -1467,7 +1467,7 @@ static void OnAnimationEasingPropertyChanged(BindableObject bindable, object old
14671467
/// <param name="newValue">The new value of header icon position property. </param>
14681468
static void OnHeaderIconPositionPropertyChanged(BindableObject bindable, object oldValue, object newValue)
14691469
{
1470-
if (bindable is SfAccordion accordion)
1470+
if (bindable is SfAccordion accordion && accordion.IsViewLoaded)
14711471
{
14721472
foreach (AccordionItem item in accordion.Items)
14731473
{

maui/src/Button/SfButton.Methods.cs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,15 +540,20 @@ double CalculateWidth(double widthConstraint)
540540
{
541541
if (widthConstraint == double.PositiveInfinity || widthConstraint < 0 || WidthRequest < 0)
542542
{
543+
double buttonContentWidth = 0;
543544
if (ShowIcon && ImageSource != null)
544545
{
545-
return ImageAlignment == Alignment.Top || ImageAlignment == Alignment.Bottom
546+
buttonContentWidth = ImageAlignment == Alignment.Top || ImageAlignment == Alignment.Bottom
546547
? Math.Max(ImageSize, TextSize.Width) + Padding.Left + Padding.Right + StrokeThickness + (_leftPadding * 2) + (_rightPadding * 2)
547548
: ImageSize + TextSize.Width + StrokeThickness + Padding.Left + Padding.Right + (_leftPadding * 2) + (_rightPadding * 2);
548549
}
549550
else
550551
{
551-
return TextSize.Width + Padding.Left + Padding.Right + StrokeThickness + (_leftPadding * 2) + (_rightPadding * 2);
552+
buttonContentWidth = TextSize.Width + Padding.Left + Padding.Right + StrokeThickness + (_leftPadding * 2) + (_rightPadding * 2);
553+
}
554+
if (buttonContentWidth <= widthConstraint)
555+
{
556+
return buttonContentWidth;
552557
}
553558
}
554559
return widthConstraint;
@@ -564,6 +569,7 @@ double CalculateHeight(double heightConstraint, double width)
564569
{
565570
if (heightConstraint == double.PositiveInfinity || heightConstraint < 0 || VerticalOptions != LayoutOptions.Fill)
566571
{
572+
width = CalculateAvailableTextWidth(width);
567573
if (LineBreakMode == LineBreakMode.WordWrap || LineBreakMode == LineBreakMode.CharacterWrap)
568574
{
569575
_numberOfLines = StringExtensions.GetLinesCount(Text, (float)width, this, LineBreakMode, out _);
@@ -587,6 +593,46 @@ double CalculateHeight(double heightConstraint, double width)
587593
return heightConstraint;
588594
}
589595

596+
/// <summary>
597+
/// Calculates the available width for the text area within the button.
598+
/// </summary>
599+
/// <param name="width"></param>
600+
/// <returns></returns>
601+
double CalculateAvailableTextWidth(double width)
602+
{
603+
if (ShowIcon && ImageSource != null)
604+
{
605+
if (ImageAlignment == Alignment.Start || ImageAlignment == Alignment.Left)
606+
{
607+
width = (ImageAlignment == Alignment.Start && _isRightToLeft) ? Math.Abs((float)(width - _textRectF.X - ImageSize - (_leftIconPadding * 2) - _textAreaPadding - (StrokeThickness / 2) - Padding.Right))
608+
: Math.Abs((float)(width - _textRectF.X - (StrokeThickness / 2) - _textAreaPadding - Padding.Right));
609+
610+
}
611+
else if (ImageAlignment == Alignment.End || ImageAlignment == Alignment.Right)
612+
{
613+
width = (ImageAlignment == Alignment.End && _isRightToLeft) ? Math.Abs((float)(width - _textRectF.X - (StrokeThickness / 2) - _textAreaPadding - Padding.Right))
614+
: Math.Abs((float)(width - _textRectF.X - ImageSize - _leftIconPadding - _leftIconPadding - _textAreaPadding - (StrokeThickness / 2) - Padding.Right));
615+
}
616+
else if (ImageAlignment == Alignment.Top)
617+
{
618+
width = Math.Abs((float)(width - _textAreaPadding - Padding.Left - Padding.Right - _textAreaPadding - (StrokeThickness / 2) - (StrokeThickness / 2)));
619+
}
620+
else if (ImageAlignment == Alignment.Bottom)
621+
{
622+
width = Math.Abs((float)(width - _textAreaPadding - Padding.Left - Padding.Right - _textAreaPadding - (StrokeThickness / 2) - (StrokeThickness / 2)));
623+
}
624+
else
625+
{
626+
width = Math.Abs((float)(width - _textRectF.X - (StrokeThickness / 2) - _textAreaPadding - Padding.Right));
627+
}
628+
}
629+
else
630+
{
631+
width = Math.Abs((float)(width - _textAreaPadding - Padding.Left - Padding.Right - _textAreaPadding - StrokeThickness));
632+
}
633+
return width;
634+
}
635+
590636
/// <summary>
591637
/// Measures the size of child elements if present and returns the size.
592638
/// </summary>
@@ -735,7 +781,10 @@ internal override void DrawText(ICanvas canvas, RectF dirtyRect)
735781
canvas.SaveState();
736782
float availableWidth = _textRectF.Width;
737783
#if ANDROID
738-
availableWidth-=AndroidTextMargin;
784+
if (LineBreakMode != LineBreakMode.WordWrap)
785+
{
786+
availableWidth -= AndroidTextMargin;
787+
}
739788
#endif
740789
var trimmedText = _isFontIconText ? Text : StringExtensions.GetTextBasedOnLineBreakMode(ApplyTextTransform(Text), this, availableWidth, _textRectF.Height, LineBreakMode);
741790
if (_textRectF.Width > 0 && _textRectF.Height > 0)

maui/src/Core/Extensions/StringExtensions.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ public static Size Measure(this string text, double availableWidth, ITextElement
4747
/// </summary>
4848
/// Note: It can be used from chart and sunbrust chart datalabels implement.
4949
public static string TrimTextToFit(this string inputText, ITextElement textElement, double availableWidth)
50-
{
51-
while (inputText.Measure(textElement).Width > availableWidth && inputText.Length > 0)
52-
{
53-
inputText = inputText.Substring(0, inputText.Length - 1);
54-
}
55-
return inputText;
56-
}
50+
{
51+
string trimmedText = inputText.TrimEnd();
52+
while (trimmedText.Measure(textElement).Width >= availableWidth && trimmedText.Length > 0)
53+
{
54+
trimmedText = trimmedText.Substring(0, trimmedText.Length - 1);
55+
trimmedText = trimmedText.TrimEnd();
56+
}
57+
return trimmedText;
58+
}
5759

5860
/// <summary>
5961
/// This method is utilized to get the total number of lines count from the text to fit within the available width.
@@ -171,13 +173,24 @@ public static string GetTextBasedOnLineBreakMode(this string text, ITextElement
171173
var leftTrimmedTextSize = leftTrimmedText.Measure((ITextElement)textElement);
172174
int leftLength = 0;
173175

174-
while (leftTrimmedTextSize.Width > charsToKeep && leftTrimmedText.Length > 0)
176+
while (leftTrimmedTextSize.Width >= charsToKeep && leftTrimmedText.Length > 0)
175177
{
176178
leftTrimmedText = leftTrimmedText.Substring(0, leftTrimmedText.Length - 1);
177179
leftTrimmedTextSize = leftTrimmedText.Measure((ITextElement)textElement);
178180
leftLength++;
179181
}
180182
string rightText = text.Substring(leftLength);
183+
184+
leftTrimmedText = leftTrimmedText.TrimEnd();
185+
rightText = rightText.TrimStart();
186+
187+
var rightTrimmedTextSize = rightText.Measure((ITextElement)textElement);
188+
while (rightTrimmedTextSize.Width >= charsToKeep && rightText.Length > 0)
189+
{
190+
leftLength++;
191+
rightText = text.Substring(leftLength).TrimStart();
192+
rightTrimmedTextSize = rightText.Measure((ITextElement)textElement);
193+
}
181194
string trimmedText = leftTrimmedText + "..." + rightText;
182195
return trimmedText;
183196

maui/src/Expander/ExpanderHeader.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,12 +604,35 @@ public void OnTouch(Internals.PointerEventArgs e)
604604
if (e.Action == PointerActions.Released)
605605
{
606606
Expander._effectsView.Reset();
607+
608+
// Restore icon color based on current state.
609+
if (IsMouseHover)
610+
{
611+
if (Expander.HasVisualStateGroups())
612+
{
613+
UpdateIconColor(Expander.HeaderIconColor);
614+
}
615+
else
616+
{
617+
UpdateIconColor(Expander.HoverIconColor);
618+
}
619+
}
620+
else if (!Expander.IsSelected)
621+
{
622+
UpdateIconColor(Expander.HeaderIconColor);
623+
}
607624
}
608625

609626
if (e.Action == PointerActions.Cancelled)
610627
{
611628
Expander._effectsView.Reset();
612629
IsMouseHover = false;
630+
631+
// Restore icon color to normal state since mouse hover is reset
632+
if (!Expander.IsSelected)
633+
{
634+
UpdateIconColor(Expander.HeaderIconColor);
635+
}
613636
}
614637
}
615638
}

maui/tests/Syncfusion.Maui.Toolkit.UnitTest/Buttons/SfButtonUnitTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,32 @@ public void CalculateWidth_ShouldReturnWidth(double width, double expectedValue)
699699
Assert.Equal(expectedValue, actualValue);
700700
}
701701

702+
[Theory]
703+
[InlineData(150, 142, "SampleImage1.png", Alignment.Left)]
704+
[InlineData(150, 108, "SampleImage1.png", Alignment.Right)]
705+
[InlineData(180, 164, "SampleImage1.png", Alignment.Top)]
706+
[InlineData(250, 234, "SampleImage1.png", Alignment.Bottom)]
707+
[InlineData(200, 184, "SampleImage1.png", null)]
708+
public void CalculateAvailableTextWidth_ShouldReturnExpectedWidth(double width, double expectedValue, string imagePath, Alignment? alignment = null)
709+
{
710+
// Arrange
711+
var button = new SfButton();
712+
button.ImageSource = ImageSource.FromFile(imagePath);
713+
714+
if (alignment != null)
715+
{
716+
button.ShowIcon = true;
717+
button.ImageAlignment = (Alignment)alignment;
718+
}
719+
720+
// Set up as needed
721+
button.Padding = new Thickness(4, 4, 4, 4);
722+
723+
var actualValue = InvokePrivateMethod(button, "CalculateAvailableTextWidth", width);
724+
725+
Assert.Equal(expectedValue, actualValue);
726+
}
727+
702728
[Theory]
703729
[InlineData(true, false, false, false, "#000000")]
704730
[InlineData(true, true, false, false, "#FF0000")]

maui/tests/Syncfusion.Maui.Toolkit.UnitTest/Layout/SfAccordionUnitTests.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,68 @@ public void ItemsProperty_SetItems_TriggersOnItemsPropertyChanged()
523523
Assert.Equal(2, itemsFromProperty.Count);
524524
}
525525

526+
[Fact]
527+
public void AccordionStyle_WhenApplied_SetsCorrectProperties()
528+
{
529+
// Arrange
530+
var animationDuration = 100;
531+
ExpanderAnimationEasing easing = new ExpanderAnimationEasing();
532+
easing = ExpanderAnimationEasing.SinInOut;
533+
ExpanderIconPosition expanderIconPosition = new ExpanderIconPosition();
534+
expanderIconPosition = ExpanderIconPosition.Start;
535+
var itemSpacing = 100;
536+
AccordionExpandMode expandMode = new AccordionExpandMode();
537+
expandMode = AccordionExpandMode.Multiple;
538+
AccordionAutoScrollPosition autoScrollPosition = new AccordionAutoScrollPosition();
539+
autoScrollPosition = AccordionAutoScrollPosition.MakeVisible;
540+
var style = new Style(typeof(SfAccordion));
541+
style.Setters.Add(new Setter
542+
{
543+
Property = SfAccordion.AnimationDurationProperty,
544+
Value = animationDuration
545+
});
546+
style.Setters.Add(new Setter
547+
{
548+
Property = SfAccordion.HeaderIconPositionProperty,
549+
Value = expanderIconPosition
550+
});
551+
style.Setters.Add(new Setter
552+
{
553+
Property = SfAccordion.AnimationEasingProperty,
554+
Value = easing
555+
});
556+
style.Setters.Add(new Setter
557+
{
558+
Property = SfAccordion.ExpandModeProperty,
559+
Value = expandMode
560+
});
561+
style.Setters.Add(new Setter
562+
{
563+
Property = SfAccordion.ItemSpacingProperty,
564+
Value = itemSpacing
565+
});
566+
style.Setters.Add(new Setter
567+
{
568+
Property = SfAccordion.AutoScrollPositionProperty,
569+
Value = autoScrollPosition
570+
});
571+
var resources = new ResourceDictionary();
572+
resources.Add("AccordionStyle", style);
573+
Application.Current = new Application();
574+
Application.Current.Resources = resources;
575+
var accordion = new SfAccordion();
576+
// Act
577+
accordion.Style = (Style)Application.Current.Resources["AccordionStyle"];
578+
// Assert
579+
Assert.Equal(animationDuration, accordion.AnimationDuration);
580+
Assert.Equal(expanderIconPosition, accordion.HeaderIconPosition);
581+
Assert.Equal(easing, accordion.AnimationEasing);
582+
Assert.Equal(expandMode, accordion.ExpandMode);
583+
Assert.Equal(animationDuration, accordion.AnimationDuration);
584+
Assert.Equal(itemSpacing, accordion.ItemSpacing);
585+
Assert.Equal(autoScrollPosition, accordion.AutoScrollPosition);
586+
}
587+
526588
#endregion
527589

528590
#region Methods
@@ -1044,6 +1106,7 @@ public void OnHeaderIconPositionPropertyChanged_UpdatesIconPosition()
10441106
var accordionItem = new AccordionItem();
10451107
accordion.Items.Add(accordionItem);
10461108
accordionItem._accordionItemView = [];
1109+
accordion.IsViewLoaded = true;
10471110
accordion.HeaderIconPosition = ExpanderIconPosition.Start;
10481111
var oldValue = ExpanderIconPosition.End;
10491112
var newValue = ExpanderIconPosition.Start;
@@ -1070,6 +1133,7 @@ public void OnAnimationEasingPropertyChanged_UpdatesAnimationEasing(ExpanderAnim
10701133
var accordionItem = new AccordionItem();
10711134
accordion.Items.Add(accordionItem);
10721135
accordionItem._accordionItemView = [];
1136+
accordion.IsViewLoaded = true;
10731137
accordion.AnimationEasing = newValue;
10741138
MethodInfo? methodInfo = typeof(SfAccordion).GetMethod(
10751139
"OnAnimationEasingPropertyChanged",
@@ -1093,6 +1157,7 @@ public void OnAnimationDurationPropertyChanged_UpdatesAnimationDuration(int newV
10931157
var accordionItem = new AccordionItem();
10941158
accordion.Items.Add(accordionItem);
10951159
accordionItem._accordionItemView = [];
1160+
accordion.IsViewLoaded = true;
10961161
accordion.AnimationDuration = newValue;
10971162
MethodInfo? methodInfo = typeof(SfAccordion).GetMethod(
10981163
"OnAnimationDurationPropertyChanged",

0 commit comments

Comments
 (0)