Browse Source

Added Popup.IsLightDismissEnabled property.

And deprecate `StaysOpen` in favor of this property.
pull/4099/head
Steven Kirk 6 years ago
parent
commit
b2a7339b4b
  1. 2
      src/Avalonia.Controls/ContextMenu.cs
  2. 41
      src/Avalonia.Controls/Primitives/Popup.cs
  3. 2
      src/Avalonia.Controls/Primitives/PopupClosedEventArgs.cs
  4. 2
      src/Avalonia.Themes.Default/AutoCompleteBox.xaml
  5. 2
      src/Avalonia.Themes.Default/ComboBox.xaml
  6. 4
      src/Avalonia.Themes.Default/MenuItem.xaml
  7. 2
      src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml
  8. 2
      src/Avalonia.Themes.Fluent/CalendarDatePicker.xaml
  9. 2
      src/Avalonia.Themes.Fluent/ComboBox.xaml
  10. 2
      src/Avalonia.Themes.Fluent/DatePicker.xaml
  11. 5
      src/Avalonia.Themes.Fluent/MenuItem.xaml
  12. 2
      src/Avalonia.Themes.Fluent/TimePicker.xaml
  13. 6
      tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

2
src/Avalonia.Controls/ContextMenu.cs

@ -265,7 +265,7 @@ namespace Avalonia.Controls
PlacementMode = PlacementMode, PlacementMode = PlacementMode,
PlacementRect = PlacementRect, PlacementRect = PlacementRect,
PlacementTarget = PlacementTarget ?? control, PlacementTarget = PlacementTarget ?? control,
StaysOpen = false IsLightDismissEnabled = true,
}; };
_popup.Opened += PopupOpened; _popup.Opened += PopupOpened;

41
src/Avalonia.Controls/Primitives/Popup.cs

@ -92,6 +92,12 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<double> HorizontalOffsetProperty = public static readonly StyledProperty<double> HorizontalOffsetProperty =
AvaloniaProperty.Register<Popup, double>(nameof(HorizontalOffset)); AvaloniaProperty.Register<Popup, double>(nameof(HorizontalOffset));
/// <summary>
/// Defines the <see cref="IsLightDismissEnabled"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsLightDismissEnabledProperty =
AvaloniaProperty.Register<Popup, bool>(nameof(IsLightDismissEnabled));
/// <summary> /// <summary>
/// Defines the <see cref="VerticalOffset"/> property. /// Defines the <see cref="VerticalOffset"/> property.
/// </summary> /// </summary>
@ -101,8 +107,13 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="StaysOpen"/> property. /// Defines the <see cref="StaysOpen"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<bool> StaysOpenProperty = [Obsolete("Use IsLightDismissEnabledProperty")]
AvaloniaProperty.Register<Popup, bool>(nameof(StaysOpen), true); public static readonly DirectProperty<Popup, bool> StaysOpenProperty =
AvaloniaProperty.RegisterDirect<Popup, bool>(
nameof(StaysOpen),
o => o.StaysOpen,
(o, v) => o.StaysOpen = v,
true);
/// <summary> /// <summary>
/// Defines the <see cref="Topmost"/> property. /// Defines the <see cref="Topmost"/> property.
@ -165,6 +176,15 @@ namespace Avalonia.Controls.Primitives
set; set;
} }
/// <summary>
/// Gets or sets a value that determines how the <see cref="Popup"/> can be dismissed.
/// </summary>
public bool IsLightDismissEnabled
{
get => GetValue(IsLightDismissEnabledProperty);
set => SetValue(IsLightDismissEnabledProperty, value);
}
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the popup is currently open. /// Gets or sets a value indicating whether the popup is currently open.
/// </summary> /// </summary>
@ -268,10 +288,11 @@ namespace Avalonia.Controls.Primitives
/// Gets or sets a value indicating whether the popup should stay open when the popup is /// Gets or sets a value indicating whether the popup should stay open when the popup is
/// pressed or loses focus. /// pressed or loses focus.
/// </summary> /// </summary>
[Obsolete("Use IsLightDismissEnabled")]
public bool StaysOpen public bool StaysOpen
{ {
get { return GetValue(StaysOpenProperty); } get => !IsLightDismissEnabled;
set { SetValue(StaysOpenProperty, value); } set => IsLightDismissEnabled = !value;
} }
/// <summary> /// <summary>
@ -382,7 +403,7 @@ namespace Avalonia.Controls.Primitives
state.popupHost.Dispose(); state.popupHost.Dispose();
}); });
if (!StaysOpen) if (IsLightDismissEnabled)
{ {
var dismissLayer = LightDismissOverlayLayer.GetLightDismissOverlayLayer(placementTarget); var dismissLayer = LightDismissOverlayLayer.GetLightDismissOverlayLayer(placementTarget);
@ -512,7 +533,7 @@ namespace Avalonia.Controls.Primitives
{ {
var mouse = e as RawPointerEventArgs; var mouse = e as RawPointerEventArgs;
if (!StaysOpen && mouse?.Type == RawPointerEventType.NonClientLeftButtonDown) if (IsLightDismissEnabled && mouse?.Type == RawPointerEventType.NonClientLeftButtonDown)
{ {
CloseCore(e); CloseCore(e);
} }
@ -520,7 +541,7 @@ namespace Avalonia.Controls.Primitives
private void PointerPressedDismissOverlay(object sender, PointerPressedEventArgs e) private void PointerPressedDismissOverlay(object sender, PointerPressedEventArgs e)
{ {
if (!StaysOpen && e.Source is IVisual v && !IsChildOrThis(v)) if (IsLightDismissEnabled && e.Source is IVisual v && !IsChildOrThis(v))
{ {
CloseCore(e); CloseCore(e);
} }
@ -616,7 +637,7 @@ namespace Avalonia.Controls.Primitives
private void WindowDeactivated(object sender, EventArgs e) private void WindowDeactivated(object sender, EventArgs e)
{ {
if (!StaysOpen) if (IsLightDismissEnabled)
{ {
Close(); Close();
} }
@ -624,7 +645,7 @@ namespace Avalonia.Controls.Primitives
private void ParentClosed(object sender, EventArgs e) private void ParentClosed(object sender, EventArgs e)
{ {
if (!StaysOpen) if (IsLightDismissEnabled)
{ {
Close(); Close();
} }
@ -632,7 +653,7 @@ namespace Avalonia.Controls.Primitives
private void WindowLostFocus() private void WindowLostFocus()
{ {
if(!StaysOpen) if(IsLightDismissEnabled)
Close(); Close();
} }

2
src/Avalonia.Controls/Primitives/PopupClosedEventArgs.cs

@ -23,7 +23,7 @@ namespace Avalonia.Controls.Primitives
/// Gets the event that closed the popup, if any. /// Gets the event that closed the popup, if any.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// If <see cref="Popup.StaysOpen"/> is false, then this property will hold details of the /// If <see cref="Popup.IsLightDismissEnabled"/> is true, then this property will hold details of the
/// interaction that caused the popup to close if the close was caused by e.g. a pointer press /// interaction that caused the popup to close if the close was caused by e.g. a pointer press
/// outside the popup. It can be used to mark the event as handled if the event should not /// outside the popup. It can be used to mark the event as handled if the event should not
/// be propagated. /// be propagated.

2
src/Avalonia.Themes.Default/AutoCompleteBox.xaml

@ -19,7 +19,7 @@
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
PlacementTarget="{TemplateBinding}" PlacementTarget="{TemplateBinding}"
StaysOpen="False"> IsLightDismissEnabled="True">
<Border BorderBrush="{DynamicResource ThemeBorderMidBrush}" <Border BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1"> BorderThickness="1">
<ListBox Name="PART_SelectingItemsControl" <ListBox Name="PART_SelectingItemsControl"

2
src/Avalonia.Themes.Default/ComboBox.xaml

@ -56,7 +56,7 @@
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
PlacementTarget="{TemplateBinding}" PlacementTarget="{TemplateBinding}"
StaysOpen="False"> IsLightDismissEnabled="True">
<Border BorderBrush="{DynamicResource ThemeBorderMidBrush}" <Border BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1"> BorderThickness="1">
<ScrollViewer> <ScrollViewer>

4
src/Avalonia.Themes.Default/MenuItem.xaml

@ -59,7 +59,6 @@
Grid.Column="4"/> Grid.Column="4"/>
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
PlacementMode="Right" PlacementMode="Right"
StaysOpen="True"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"> IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}" BorderBrush="{DynamicResource ThemeBorderMidBrush}"
@ -108,8 +107,7 @@
</ContentPresenter.DataTemplates> </ContentPresenter.DataTemplates>
</ContentPresenter> </ContentPresenter>
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}" IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
StaysOpen="True">
<Border Background="{TemplateBinding Background}" <Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource ThemeBorderMidBrush}" BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">

2
src/Avalonia.Themes.Fluent/AutoCompleteBox.xaml

@ -47,7 +47,7 @@
WindowManagerAddShadowHint="False" WindowManagerAddShadowHint="False"
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
StaysOpen="False" IsLightDismissEnabled="True"
PlacementTarget="{TemplateBinding}"> PlacementTarget="{TemplateBinding}">
<Border Name="PART_SuggestionsContainer" <Border Name="PART_SuggestionsContainer"
Padding="{DynamicResource AutoCompleteListMargin}" Padding="{DynamicResource AutoCompleteListMargin}"

2
src/Avalonia.Themes.Fluent/CalendarDatePicker.xaml

@ -116,7 +116,7 @@
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
PlacementTarget="{TemplateBinding}" PlacementTarget="{TemplateBinding}"
StaysOpen="False"> IsLightDismissEnabled="True">
<Calendar Name="PART_Calendar" <Calendar Name="PART_Calendar"
FirstDayOfWeek="{TemplateBinding FirstDayOfWeek}" FirstDayOfWeek="{TemplateBinding FirstDayOfWeek}"
IsTodayHighlighted="{TemplateBinding IsTodayHighlighted}"/> IsTodayHighlighted="{TemplateBinding IsTodayHighlighted}"/>

2
src/Avalonia.Themes.Fluent/ComboBox.xaml

@ -123,7 +123,7 @@
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
PlacementTarget="{TemplateBinding}" PlacementTarget="{TemplateBinding}"
StaysOpen="False"> IsLightDismissEnabled="True">
<Border x:Name="PopupBorder" <Border x:Name="PopupBorder"
Background="{DynamicResource ComboBoxDropDownBackground}" Background="{DynamicResource ComboBoxDropDownBackground}"
BorderBrush="{DynamicResource ComboBoxDropDownBorderBrush}" BorderBrush="{DynamicResource ComboBoxDropDownBorderBrush}"

2
src/Avalonia.Themes.Fluent/DatePicker.xaml

@ -190,7 +190,7 @@
</Button> </Button>
<Popup Name="Popup" WindowManagerAddShadowHint="False" <Popup Name="Popup" WindowManagerAddShadowHint="False"
StaysOpen="False" PlacementTarget="{TemplateBinding}" IsLightDismissEnabled="True" PlacementTarget="{TemplateBinding}"
PlacementMode="Bottom"> PlacementMode="Bottom">
<DatePickerPresenter Name="PickerPresenter" /> <DatePickerPresenter Name="PickerPresenter" />
</Popup> </Popup>

5
src/Avalonia.Themes.Fluent/MenuItem.xaml

@ -108,7 +108,6 @@
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
WindowManagerAddShadowHint="True" WindowManagerAddShadowHint="True"
PlacementMode="Right" PlacementMode="Right"
StaysOpen="True"
IsOpen="{TemplateBinding IsSubMenuOpen, IsOpen="{TemplateBinding IsSubMenuOpen,
Mode=TwoWay}"> Mode=TwoWay}">
<Border Background="{DynamicResource MenuFlyoutPresenterBackground}" <Border Background="{DynamicResource MenuFlyoutPresenterBackground}"
@ -155,9 +154,7 @@
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
WindowManagerAddShadowHint="False" WindowManagerAddShadowHint="False"
MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{Binding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
IsOpen="{TemplateBinding IsSubMenuOpen, IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
Mode=TwoWay}"
StaysOpen="True">
<Border Background="{DynamicResource MenuFlyoutPresenterBackground}" <Border Background="{DynamicResource MenuFlyoutPresenterBackground}"
BorderBrush="{DynamicResource MenuFlyoutPresenterBorderBrush}" BorderBrush="{DynamicResource MenuFlyoutPresenterBorderBrush}"
BorderThickness="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" BorderThickness="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}"

2
src/Avalonia.Themes.Fluent/TimePicker.xaml

@ -123,7 +123,7 @@
</Button> </Button>
<Popup Name="Popup" WindowManagerAddShadowHint="False" <Popup Name="Popup" WindowManagerAddShadowHint="False"
StaysOpen="False" PlacementTarget="{TemplateBinding}" IsLightDismissEnabled="True" PlacementTarget="{TemplateBinding}"
PlacementMode="Bottom"> PlacementMode="Bottom">
<TimePickerPresenter Name="PickerPresenter" /> <TimePickerPresenter Name="PickerPresenter" />
</Popup> </Popup>

6
tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

@ -349,7 +349,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
} }
[Fact] [Fact]
public void StaysOpen_False_Should_Not_Handle_Closing_Click() public void LightDismiss_Should_Not_Handle_Closing_Click()
{ {
using (CreateServices()) using (CreateServices())
{ {
@ -357,7 +357,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
var target = new Popup() var target = new Popup()
{ {
PlacementTarget = window , PlacementTarget = window ,
StaysOpen = false, IsLightDismissEnabled = true,
}; };
target.Open(); target.Open();
@ -378,7 +378,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
var target = new Popup() var target = new Popup()
{ {
PlacementTarget = window, PlacementTarget = window,
StaysOpen = false, IsLightDismissEnabled = true,
}; };
target.Open(); target.Open();

Loading…
Cancel
Save