Skip to content

Commit

Permalink
feat: Added support for DropDownButton from MUX
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Mar 17, 2020
1 parent 555dcdc commit de78481
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\DropDownButton\DropDownButtonPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_Unloaded.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -3422,6 +3426,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ControlTests\Control_IsEnabled_Inheritance.xaml.cs">
<DependentUpon>Control_IsEnabled_Inheritance.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\DropDownButton\DropDownButtonPage.xaml.cs">
<DependentUpon>DropDownButtonPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\FlyoutButtonViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\DatePicker\DatePickerFlyout_Unloaded.xaml.cs">
<DependentUpon>DatePickerFlyout_Unloaded.xaml</DependentUpon>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<UserControl
x:Class="MUXControlsTestApp.DropDownButtonPage"
x:Name="DropDownButtonTestPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MUXControlsTestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<!--<Page.Resources>
<local:MyCommand x:Key="TestExecuteCommand" />
</Page.Resources>-->

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<ScrollViewer Grid.Column="0" Height="Auto">
<StackPanel Orientation="Vertical" VerticalAlignment="Top" Width="Auto" Height="Auto">
<TextBlock Text="Demo controls" Style="{ThemeResource StandardGroupHeader}" Margin="0"/>
<StackPanel Orientation="Horizontal" Margin="0,12,0,0">
<controls:DropDownButton CornerRadius="2" x:Name="TestDropDownButton" AutomationProperties.Name="TestDropDownButton" Content="Test Button" Click="TestDropDownButton_Click">
<controls:DropDownButton.Flyout>
<Flyout x:Name="TestFlyout" AutomationProperties.Name="TestFlyout" Placement="Bottom" Opened="TestDropDownButtonFlyout_Opened" Closed="TestDropDownButtonFlyout_Closed">
<TextBlock Text="Hello"/>
</Flyout>
</controls:DropDownButton.Flyout>
</controls:DropDownButton>

<Button Margin="6,0,0,0" Content="For Comparison">
<Button.Flyout>
<Flyout>
<TextBlock Text="Button flyout"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>


<TextBlock Text="Options" Style="{ThemeResource StandardGroupHeader}" Margin="0,16,0,8"/>
<CheckBox x:Name="SetFlyoutCheckbox" AutomationProperties.Name="SetFlyoutCheckbox" IsChecked="True"
Content="Flyout set" Checked="SetFlyoutCheckbox_Checked" Unchecked="SetFlyoutCheckbox_Unchecked"/>

<TextBlock Text="Status" Style="{ThemeResource StandardGroupHeader}" Margin="0,16,0,8"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0">Click count:</TextBlock>
<TextBlock x:Name="ClickCountTextBlock" AutomationProperties.Name="ClickCountTextBlock"
Margin="4,0,0,0" Text="0" Grid.Row="0" Grid.Column="1"/>
<TextBlock Grid.Row="1">Flyout opened:</TextBlock>
<TextBlock x:Name="FlyoutOpenedCountTextBlock" AutomationProperties.Name="FlyoutOpenedCountTextBlock"
Margin="4,0,0,0" Text="0" Grid.Row="1" Grid.Column="1"/>
<TextBlock Grid.Row="2">Flyout closed:</TextBlock>
<TextBlock x:Name="FlyoutClosedCountTextBlock" AutomationProperties.Name="FlyoutClosedCountTextBlock"
Margin="4,0,0,0" Text="0" Grid.Row="2" Grid.Column="1"/>
</Grid>


</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Markup;
using Windows.UI;
using System.Windows.Input;
using Uno.UI.Samples.Controls;

namespace MUXControlsTestApp
{

[SampleControlInfo("DropDownButton", "MUX Page")]
public sealed partial class DropDownButtonPage
{
private int _clickCount = 0;
private int _flyoutOpenedCount = 0;
private int _flyoutClosedCount = 0;

private Flyout _flyout;

public DropDownButtonPage()
{
this.InitializeComponent();

_flyout = new Flyout();
_flyout.Placement = FlyoutPlacementMode.Bottom;
TextBlock textBlock = new TextBlock();
textBlock.Text = "New Flyout";
_flyout.Content = textBlock;
_flyout.Opened += TestDropDownButtonFlyout_Opened;
_flyout.Closed += TestDropDownButtonFlyout_Closed;
}

private void TestDropDownButton_Click(object sender, object e)
{
ClickCountTextBlock.Text = (++_clickCount).ToString();
}

private void TestDropDownButtonFlyout_Opened(object sender, object e)
{
FlyoutOpenedCountTextBlock.Text = (++_flyoutOpenedCount).ToString();
}

private void TestDropDownButtonFlyout_Closed(object sender, object e)
{
FlyoutClosedCountTextBlock.Text = (++_flyoutClosedCount).ToString();
}

private void SetFlyoutCheckbox_Checked(object sender, RoutedEventArgs e)
{
if (TestDropDownButton != null && _flyout != null)
{
TestDropDownButton.Flyout = _flyout;
}
}

private void SetFlyoutCheckbox_Unchecked(object sender, RoutedEventArgs e)
{
if (TestDropDownButton != null)
{
TestDropDownButton.Flyout = null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
#pragma warning disable 114 // new keyword hiding
namespace Windows.UI.Xaml.Controls
{
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __MACOS__
#if false || false || false || false || false
[global::Uno.NotImplemented]
#endif
public partial class DropDownButton : global::Windows.UI.Xaml.Controls.Button
{
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __MACOS__
#if false || false || false || false || false
[global::Uno.NotImplemented]
public DropDownButton() : base()
{
Expand Down
78 changes: 78 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/DropDownButton/DropDownButton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Automation.Peers;

namespace Windows.UI.Xaml.Controls
{
public partial class DropDownButton : Button
{
public DropDownButton()
{
DefaultStyleKey = typeof(PersonPicture);
}

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

// - Missing
// m_flyoutPropertyChangedRevoker = RegisterPropertyChanged(*this, winrt::Button::FlyoutProperty(), { this, &DropDownButton::OnFlyoutPropertyChanged });

// RegisterFlyoutEvents();
//}

//void DropDownButton::RegisterFlyoutEvents()
//{
// m_flyoutOpenedRevoker.revoke();
// m_flyoutClosedRevoker.revoke();

// if (Flyout())
// {
// m_flyoutOpenedRevoker = Flyout().Opened(winrt::auto_revoke, { this, &DropDownButton::OnFlyoutOpened });
// m_flyoutClosedRevoker = Flyout().Closed(winrt::auto_revoke, { this, &DropDownButton::OnFlyoutClosed });
// }
//}

//bool DropDownButton::IsFlyoutOpen()
//{
// return m_isFlyoutOpen;
//};

//void DropDownButton::OpenFlyout()
//{
// if (auto flyout = Flyout())
// {
// flyout.ShowAt(*this);
// }
//}

//void DropDownButton::CloseFlyout()
//{
// if (auto flyout = Flyout())
// {
// flyout.Hide();
// }
//}

//void DropDownButton::OnFlyoutPropertyChanged(const winrt::DependencyObject& sender, const winrt::DependencyProperty& args)
//{
// RegisterFlyoutEvents();
//}

//void DropDownButton::OnFlyoutOpened(const winrt::IInspectable& sender, const winrt::IInspectable& args)
//{
// m_isFlyoutOpen = true;
// SharedHelpers::RaiseAutomationPropertyChangedEvent(*this, winrt::ExpandCollapseState::Collapsed, winrt::ExpandCollapseState::Expanded);
//}

//void DropDownButton::OnFlyoutClosed(const winrt::IInspectable& sender, const winrt::IInspectable& args)
//{
// m_isFlyoutOpen = false;
// SharedHelpers::RaiseAutomationPropertyChangedEvent(*this, winrt::ExpandCollapseState::Expanded, winrt::ExpandCollapseState::Collapsed);
//}
}
}
128 changes: 128 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/DropDownButton/DropDownButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.UI.Xaml.Controls"
xmlns:contract7Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,7)"
xmlns:contract7NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,7)">

<Style x:Key="DefaultDropDownButtonStyle" TargetType="local:DropDownButton">
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="{StaticResource ButtonPadding}" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-3" />
<!--<contract7Present:Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid"
Background="{TemplateBinding Background}"
contract7Present:CornerRadius="{TemplateBinding CornerRadius}">
<!--contract7NotPresent:CornerRadius="{ThemeResource ControlCornerRadius}"-->

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>

<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>

<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>

<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerGrid" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ChevronTextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

<Grid x:Name="InnerGrid"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
contract7Present:CornerRadius="{TemplateBinding CornerRadius}">

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>

<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw" />

<TextBlock
x:Name="ChevronTextBlock"
Grid.Column="1"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Text="&#xE0E5;"
VerticalAlignment="Center"
Margin="6,0,0,0"
IsTextScaleFactorEnabled="False"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>

</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style TargetType="local:DropDownButton" BasedOn="{StaticResource DefaultDropDownButtonStyle}" />

</ResourceDictionary>

0 comments on commit de78481

Please sign in to comment.