diff --git a/.github/workflows/dotnet-format-daily.yml b/.github/workflows/dotnet-format-daily.yml new file mode 100644 index 00000000000..587c17b5ec8 --- /dev/null +++ b/.github/workflows/dotnet-format-daily.yml @@ -0,0 +1,60 @@ +name: Daily code format check +on: + schedule: + - cron: 0 0 * * * # Every day at midnight (UTC) +jobs: + dotnet-format: + runs-on: windows-latest + steps: + - name: Install dotnet-format + run: dotnet tool install -g dotnet-format + + - name: Checkout repo + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + + - name: Run dotnet format + id: format + uses: jfversluis/dotnet-format@v1.0.4 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + action: "fix" + #only-changed-files: true # only works for PRs + workspace: "Xamarin.Forms.sln" + + - name: Commit files + if: steps.format.outputs.has-changes == 'true' + run: | + git config --local user.name "github-actions[bot]" + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -a -m 'Automated dotnet-format update' + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + title: '[housekeeping] Automated PR to fix formatting errors' + body: | + Automated PR to fix formatting errors + committer: GitHub + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + labels: housekeeping + assignees: rmarinho,samhouts + reviewers: rmarinho,samhouts + branch: housekeeping/fix-codeformatting + + # Pushing won't work to forked repos + # - name: Commit files + # if: steps.format.outputs.has-changes == 'true' + # run: | + # git config --local user.name "github-actions[bot]" + # git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + # git commit -a -m 'Automated dotnet-format update + # Co-authored-by: ${{ github.event.pull_request.user.login }} <${{ github.event.pull_request.user.id }}+${{ github.event.pull_request.user.login }}@users.noreply.github.com>' + + # - name: Push changes + # if: steps.format.outputs.has-changes == 'true' + # uses: ad-m/github-push-action@v0.6.0 + # with: + # github_token: ${{ secrets.GITHUB_TOKEN }} + # branch: ${{ github.event.pull_request.head.ref }} diff --git a/GitInfo.txt b/GitInfo.txt index 28cbf7c0aae..32f3eaad0d9 100644 --- a/GitInfo.txt +++ b/GitInfo.txt @@ -1 +1 @@ -5.0.0 \ No newline at end of file +5.0.1 \ No newline at end of file diff --git a/README.md b/README.md index f90aa71ec44..701e454c613 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Read more about the platform at https://www.xamarin.com/forms. ## Build Status ## -![Azure DevOps](https://devdiv.visualstudio.com/DevDiv/_apis/build/status/Xamarin/XamarinForms/Xamarin%20Forms?branchName=main "Azure Pipelines") +[![Build Status](https://devdiv.visualstudio.com/DevDiv/_apis/build/status/Xamarin%20Forms%20Yaml?repoName=xamarin%2FXamarin.Forms&branchName=main)](https://devdiv.visualstudio.com/DevDiv/_build/latest?definitionId=10386&repoName=xamarin%2FXamarin.Forms&branchName=main) ## Packages ## diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3106.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3106.cs new file mode 100644 index 00000000000..480eebb90b1 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3106.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 3106, "Added LineBreakMode on Button")] + public class Issue3106 : TestContentPage + { + int count; + const string content = "Welcome to Xamarin.Forms! Welcome to Xamarin.Forms! Welcome to Xamarin.Forms! Welcome to Xamarin.Forms!"; + const string content2 = "Now users can set a line break mode to texts on Button, the default value doesn't affect any user."; + + Button mainButton; + Button materialButton; + Label lineBreakModeType; + + protected override void Init() + { + mainButton = new Button + { + Text = content, + LineBreakMode = LineBreakMode.WordWrap, + HorizontalOptions = LayoutOptions.CenterAndExpand, + VerticalOptions = LayoutOptions.CenterAndExpand + }; + mainButton.Clicked += MainButton_Clicked; + + materialButton = new Button + { + Text = content, + LineBreakMode = LineBreakMode.WordWrap, + HorizontalOptions = LayoutOptions.CenterAndExpand, + VerticalOptions = LayoutOptions.CenterAndExpand, + Visual = VisualMarker.Material + }; + materialButton.Clicked += MaterialButton_Clicked; + + lineBreakModeType = new Label + { + Text = LineBreakMode.WordWrap.ToString(), + VerticalOptions = LayoutOptions.EndAndExpand, + LineBreakMode = LineBreakMode.WordWrap, + }; + var layout = new StackLayout + { + Children = + { + new Label + { + Text = "Press the first button to change the LineBreakMode. Press the second button to change the text", + VerticalOptions = LayoutOptions.StartAndExpand + }, + mainButton, + materialButton, + lineBreakModeType + } + }; + + Content = layout; + } + + void MaterialButton_Clicked(object sender, EventArgs e) + { + if (materialButton.Text.Equals(content2)) + materialButton.Text = mainButton.Text = content; + else + materialButton.Text = mainButton.Text = content2; + } + + void MainButton_Clicked(object sender, EventArgs e) + { + materialButton.LineBreakMode = mainButton.LineBreakMode = SelectLineBreakMode(); + lineBreakModeType.Text = mainButton.LineBreakMode.ToString(); + } + + LineBreakMode SelectLineBreakMode() + { + count++; + switch (count) + { + case 1: + return LineBreakMode.CharacterWrap; + case 2: + return LineBreakMode.HeadTruncation; + case 3: + return LineBreakMode.MiddleTruncation; + case 4: + return LineBreakMode.NoWrap; + case 5: + return LineBreakMode.TailTruncation; + default: + count = 0; + return LineBreakMode.WordWrap; + } + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index ff82490ed9a..44c257042f3 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -26,6 +26,7 @@ + Issue11794.xaml diff --git a/Xamarin.Forms.Core/Button.cs b/Xamarin.Forms.Core/Button.cs index e191492bf6a..f06de4122ed 100644 --- a/Xamarin.Forms.Core/Button.cs +++ b/Xamarin.Forms.Core/Button.cs @@ -59,6 +59,9 @@ public class Button : View, IFontElement, ITextElement, IBorderElement, IButtonC public static readonly BindableProperty PaddingProperty = PaddingElement.PaddingProperty; + public static readonly BindableProperty LineBreakModeProperty = BindableProperty.Create(nameof(LineBreakMode), typeof(LineBreakMode), typeof(Button), LineBreakMode.NoWrap, + propertyChanged: (bindable, oldvalue, newvalue) => ((Button)bindable).InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged)); + public Thickness Padding { get { return (Thickness)GetValue(PaddingElement.PaddingProperty); } @@ -70,6 +73,12 @@ Thickness IPaddingElement.PaddingDefaultValueCreator() return default(Thickness); } + public LineBreakMode LineBreakMode + { + get { return (LineBreakMode)GetValue(LineBreakModeProperty); } + set { SetValue(LineBreakModeProperty, value); } + } + void IPaddingElement.OnPaddingPropertyChanged(Thickness oldValue, Thickness newValue) { InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged); diff --git a/Xamarin.Forms.CustomAttributes/TestAttributes.cs b/Xamarin.Forms.CustomAttributes/TestAttributes.cs index 78368a579f4..9ae5194fd1d 100644 --- a/Xamarin.Forms.CustomAttributes/TestAttributes.cs +++ b/Xamarin.Forms.CustomAttributes/TestAttributes.cs @@ -233,7 +233,8 @@ public enum Button BorderRadius, Image, Padding, - Pressed + Pressed, + LineBreakMode } public enum VisualElement diff --git a/Xamarin.Forms.Platform.Android/ButtonLayoutManager.cs b/Xamarin.Forms.Platform.Android/ButtonLayoutManager.cs index 90a113fb458..f5bcc72de91 100644 --- a/Xamarin.Forms.Platform.Android/ButtonLayoutManager.cs +++ b/Xamarin.Forms.Platform.Android/ButtonLayoutManager.cs @@ -8,6 +8,7 @@ using ARect = Android.Graphics.Rect; using AView = Android.Views.View; using AButton = Android.Widget.Button; +using Android.Text; namespace Xamarin.Forms.Platform.Android { @@ -183,6 +184,7 @@ public void Update() if (!UpdateTextAndImage()) UpdateImage(); UpdatePadding(); + UpdateLineBreakMode(); } void OnElementChanged(object sender, VisualElementChangedEventArgs e) @@ -215,6 +217,8 @@ void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) UpdateTextAndImage(); else if (e.PropertyName == Button.BorderWidthProperty.PropertyName && _borderAdjustsPadding) _element.InvalidateMeasureNonVirtual(InvalidationTrigger.MeasureChanged); + else if (e.PropertyName == Button.LineBreakModeProperty.PropertyName) + UpdateLineBreakMode(); } void UpdatePadding() @@ -347,5 +351,16 @@ void UpdateImage() }); } } + + void UpdateLineBreakMode() + { + AButton view = View; + + if (view == null || _element == null || _renderer?.View == null) + return; + + view.SetLineBreakMode(_element); + _renderer.View.SetAllCaps(_element.TextTransform == TextTransform.Default); + } } } diff --git a/Xamarin.Forms.Platform.Android/Extensions/TextViewExtensions.cs b/Xamarin.Forms.Platform.Android/Extensions/TextViewExtensions.cs index 3f6a8567d71..da7e410f303 100644 --- a/Xamarin.Forms.Platform.Android/Extensions/TextViewExtensions.cs +++ b/Xamarin.Forms.Platform.Android/Extensions/TextViewExtensions.cs @@ -22,21 +22,18 @@ public static void SetMaxLines(this TextView textView, Label label) textView.SetMaxLines(maxLines); } - static void SetMaxLines(this TextView textView, Label label, int lines) + public static void SetLineBreakMode(this TextView textView, Label label) { - // If the Label's MaxLines has been explicitly set, we should not set it here - if (label.MaxLines != (int)Label.MaxLinesProperty.DefaultValue) - { - return; - } - - textView.SetMaxLines(lines); + var maxLines = SetLineBreak(textView, label.LineBreakMode); + textView.SetMaxLines(maxLines); } - public static void SetLineBreakMode(this TextView textView, Label label) - { - var lineBreakMode = label.LineBreakMode; + public static void SetLineBreakMode(this TextView textView, Button button) => + SetLineBreak(textView, button.LineBreakMode); + + public static int SetLineBreak( TextView textView, LineBreakMode lineBreakMode) + { int maxLines = Int32.MaxValue; bool singleLine = false; @@ -44,6 +41,7 @@ public static void SetLineBreakMode(this TextView textView, Label label) { case LineBreakMode.NoWrap: maxLines = 1; + singleLine = true; textView.Ellipsize = null; break; case LineBreakMode.WordWrap: @@ -59,6 +57,7 @@ public static void SetLineBreakMode(this TextView textView, Label label) break; case LineBreakMode.TailTruncation: maxLines = 1; + singleLine = true; textView.Ellipsize = TextUtils.TruncateAt.End; break; case LineBreakMode.MiddleTruncation: @@ -69,7 +68,7 @@ public static void SetLineBreakMode(this TextView textView, Label label) } textView.SetSingleLine(singleLine); - textView.SetMaxLines(label, maxLines); + return maxLines; } public static void RecalculateSpanPositions(this TextView textView, Label element, SpannableString spannableString, SizeRequest finalSize) diff --git a/Xamarin.Forms.Platform.Android/Renderers/ListViewRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ListViewRenderer.cs index 9b22ea91679..e680f2795df 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/ListViewRenderer.cs @@ -609,6 +609,7 @@ public TrackElement(int position) AView _trackedView; int _trackedViewPrevPosition; + int _trackedViewPrevHeight; int _trackedViewPrevTop; public void SyncState(AbsListView view) @@ -616,6 +617,7 @@ public void SyncState(AbsListView view) if (view.ChildCount > 0) { _trackedView = GetChild(view); + _trackedViewPrevHeight = view.Height; _trackedViewPrevTop = GetY(); _trackedViewPrevPosition = view.GetPositionForView(_trackedView); } @@ -653,7 +655,7 @@ AView GetChild(AbsListView view) } int GetY() { - return _position <= 1 ? _trackedView.Bottom : _trackedView.Top; + return _position <= 1 ? (_trackedView.Bottom - (_trackedView.Height - _trackedViewPrevHeight)) : _trackedView.Top; } } @@ -710,6 +712,9 @@ public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun t.SyncState(view); } } + + if (!wasTracked) + _contentOffset = 0; } public void OnScrollStateChanged(AbsListView view, ScrollState scrollState) diff --git a/Xamarin.Forms.Platform.UAP/ButtonRenderer.cs b/Xamarin.Forms.Platform.UAP/ButtonRenderer.cs index c88de44724d..02a4b6b0cac 100644 --- a/Xamarin.Forms.Platform.UAP/ButtonRenderer.cs +++ b/Xamarin.Forms.Platform.UAP/ButtonRenderer.cs @@ -8,12 +8,16 @@ using WImage = Windows.UI.Xaml.Controls.Image; using WStretch = Windows.UI.Xaml.Media.Stretch; using WThickness = Windows.UI.Xaml.Thickness; +using System; +using Xamarin.Forms.Platform.UAP.Extensions; +using System.Linq; namespace Xamarin.Forms.Platform.UWP { public class ButtonRenderer : ViewRenderer { bool _fontApplied; + TextBlock _textBlock = null; FormsButton _button; PointerEventHandler _pointerPressedHandler; @@ -74,6 +78,15 @@ protected override void OnElementChanged(ElementChangedEventArgs