Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a layout for MauiButton on Windows which supports LineBreakMode #14036

Merged
merged 1 commit into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,30 @@ public static class ButtonExtensions
{
public static void UpdateContentLayout(this UI.Xaml.Controls.Button mauiButton, Button button)
{
// If the Content isn't the StackPanel setup by Maui.Core then
// The user has set a custom Content or the content isn't a mix of text/images
if (mauiButton.Content is not StackPanel container)
return;

var image = mauiButton.GetContent<UI.Xaml.Controls.Image>();
var textBlock = mauiButton.GetContent<UI.Xaml.Controls.TextBlock>();

// If either of these are null then the user has taken control of the content
// and we don't know how to apply our changes
if (image == null || textBlock == null)
if (mauiButton.Content is not DefaultMauiButtonContent content)
{
// If the content is the default for Maui.Core, then
// The user has set a custom Content or the content isn't a mix of text/images
return;
}

container.Children.Clear();
var layout = button.ContentLayout;
var spacing = layout.Spacing;

switch (layout.Position)
{
case Button.ButtonContentLayout.ImagePosition.Top:
container.Orientation = Orientation.Vertical;
image.Margin = WinUIHelpers.CreateThickness(0, 0, 0, spacing);
container.Children.Add(image);
container.Children.Add(textBlock);
content.LayoutImageTop(spacing);
break;
case Button.ButtonContentLayout.ImagePosition.Bottom:
container.Orientation = Orientation.Vertical;
image.Margin = WinUIHelpers.CreateThickness(0, spacing, 0, 0);
container.Children.Add(textBlock);
container.Children.Add(image);
content.LayoutImageBottom(spacing);
break;
case Button.ButtonContentLayout.ImagePosition.Right:
container.Orientation = Orientation.Horizontal;
image.Margin = WinUIHelpers.CreateThickness(spacing, 0, 0, 0);
container.Children.Add(textBlock);
container.Children.Add(image);
content.LayoutImageRight(spacing);
break;
default:
// Defaults to image on the left
container.Orientation = Orientation.Horizontal;
image.Margin = WinUIHelpers.CreateThickness(0, 0, spacing, 0);
container.Children.Add(image);
container.Children.Add(textBlock);
content.LayoutImageLeft(spacing);
break;
}
}
Expand Down
150 changes: 128 additions & 22 deletions src/Core/src/Platform/Windows/MauiButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Windows.Security.Credentials.UI;
using WThickness = Microsoft.UI.Xaml.Thickness;

namespace Microsoft.Maui.Platform
Expand All @@ -10,38 +11,143 @@ public class MauiButton : Button
{
public MauiButton()
{
Content = new DefaultMauiButtonContent();

VerticalAlignment = VerticalAlignment.Stretch;
HorizontalAlignment = HorizontalAlignment.Stretch;
Content = new StackPanel
}

protected override AutomationPeer OnCreateAutomationPeer()
{
return new MauiButtonAutomationPeer(this);
}
}

internal class DefaultMauiButtonContent : Grid
{
readonly Image _image;
readonly TextBlock _textBlock;

public DefaultMauiButtonContent()
{
RowDefinitions.Add(new RowDefinition { Height = UI.Xaml.GridLength.Auto });
RowDefinitions.Add(new RowDefinition { Height = UI.Xaml.GridLength.Auto });

ColumnDefinitions.Add(new ColumnDefinition { Width = UI.Xaml.GridLength.Auto });
ColumnDefinitions.Add(new ColumnDefinition { Width = UI.Xaml.GridLength.Auto });

HorizontalAlignment = HorizontalAlignment.Center;
VerticalAlignment = VerticalAlignment.Center;
Margin = new WThickness(0);

_image = new Image
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Stretch = Stretch.None,
Margin = new WThickness(0),
Visibility = UI.Xaml.Visibility.Collapsed,
};

_textBlock = new TextBlock
{
VerticalAlignment = VerticalAlignment.Center,
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new WThickness(0),
Children =
{
new Image
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Stretch = Stretch.Uniform,
Margin = new WThickness(0),
Visibility = UI.Xaml.Visibility.Collapsed,
},
new TextBlock
{
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new WThickness(0),
Visibility = UI.Xaml.Visibility.Collapsed,
}
}
Visibility = UI.Xaml.Visibility.Collapsed,
};

Children.Add(_image);
Children.Add(_textBlock);

LayoutImageLeft(0);
}

protected override AutomationPeer OnCreateAutomationPeer()
public void LayoutImageLeft(double spacing)
{
return new MauiButtonAutomationPeer(this);
SetupHorizontalLayout(spacing);

Grid.SetColumn(_image, 0);
Grid.SetColumn(_textBlock, 1);

ColumnDefinitions[0].Width = UI.Xaml.GridLength.Auto;
ColumnDefinitions[1].Width = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);
}

public void LayoutImageRight(double spacing)
{
SetupHorizontalLayout(spacing);

Grid.SetColumn(_image, 1);
Grid.SetColumn(_textBlock, 0);

ColumnDefinitions[0].Width = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);
ColumnDefinitions[1].Width = UI.Xaml.GridLength.Auto;
}

public void LayoutImageTop(double spacing)
{
SetupVerticalLayout(spacing);

Grid.SetRow(_image, 0);
Grid.SetRow(_textBlock, 1);
}

public void LayoutImageBottom(double spacing)
{
SetupVerticalLayout(spacing);

Grid.SetRow(_image, 1);
Grid.SetRow(_textBlock, 0);
}

double AdjustSpacing(double spacing)
{
if (_image.Visibility == UI.Xaml.Visibility.Collapsed
|| _textBlock.Visibility == UI.Xaml.Visibility.Collapsed)
{
return 0;
}

return spacing;
}

void SetupHorizontalLayout(double spacing)
{
RowSpacing = 0;
ColumnSpacing = AdjustSpacing(spacing);

RowDefinitions[0].Height = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);
RowDefinitions[1].Height = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);

Grid.SetRow(_image, 0);
Grid.SetRowSpan(_image, 2);
Grid.SetColumnSpan(_image, 1);

Grid.SetRow(_textBlock, 0);
Grid.SetRowSpan(_textBlock, 2);
Grid.SetColumnSpan(_textBlock, 1);

}

void SetupVerticalLayout(double spacing)
{
ColumnSpacing = 0;
RowSpacing = AdjustSpacing(spacing);

RowDefinitions[0].Height = UI.Xaml.GridLength.Auto;
RowDefinitions[1].Height = UI.Xaml.GridLength.Auto;

ColumnDefinitions[0].Width = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);
ColumnDefinitions[1].Width = new UI.Xaml.GridLength(1, UI.Xaml.GridUnitType.Star);

Grid.SetRowSpan(_image, 1);
Grid.SetColumn(_image, 0);
Grid.SetColumnSpan(_image, 2);

Grid.SetRowSpan(_textBlock, 1);
Grid.SetColumn(_textBlock, 0);
Grid.SetColumnSpan(_textBlock, 2);
}
}
}