Merge pull request #316 from irihitech/286-modal
Automatically focus on overlay modal dialog/messagebox/drawer
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
<ControlTemplate TargetType="u:CustomDialogControl">
|
<ControlTemplate TargetType="u:CustomDialogControl">
|
||||||
<Border
|
<Border
|
||||||
Name="PART_Border"
|
Name="PART_Border"
|
||||||
|
Focusable="True"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -152,6 +153,7 @@
|
|||||||
<Border
|
<Border
|
||||||
Name="PART_Border"
|
Name="PART_Border"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
Focusable="True"
|
||||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||||
BoxShadow="0 0 8 0 #1A000000"
|
BoxShadow="0 0 8 0 #1A000000"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate TargetType="u:CustomDrawerControl">
|
<ControlTemplate TargetType="u:CustomDrawerControl">
|
||||||
<Border Name="PART_Root"
|
<Border Name="PART_Root"
|
||||||
|
Focusable="True"
|
||||||
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
|
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
@@ -77,6 +78,7 @@
|
|||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate TargetType="u:DefaultDrawerControl">
|
<ControlTemplate TargetType="u:DefaultDrawerControl">
|
||||||
<Border Name="PART_Root"
|
<Border Name="PART_Root"
|
||||||
|
Focusable="True"
|
||||||
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
|
Margin="{TemplateBinding Padding, Converter={x:Static c:ThicknessTakeConverter.Left}}"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
|
<Border Name="PART_TransparencyFallback" IsHitTestVisible="False" />
|
||||||
<Border Background="{TemplateBinding Background}" IsHitTestVisible="False" />
|
<Border Background="{TemplateBinding Background}" IsHitTestVisible="False" />
|
||||||
<Panel Margin="{TemplateBinding WindowDecorationMargin}" Background="Transparent" />
|
<Panel Margin="{TemplateBinding WindowDecorationMargin}" Background="Transparent" />
|
||||||
<ChromeOverlayLayer />
|
<VisualLayerManager>
|
||||||
<Grid RowDefinitions="Auto, *, Auto">
|
<Grid RowDefinitions="Auto, *, Auto">
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="24,24,24,0"
|
Margin="24,24,24,0"
|
||||||
ColumnDefinitions="Auto, *, Auto">
|
ColumnDefinitions="Auto, *, Auto">
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Theme="{DynamicResource CloseButton}" />
|
Theme="{DynamicResource CloseButton}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
MaxWidth="{DynamicResource MessageBoxWindowContentMaxWidth}"
|
MaxWidth="{DynamicResource MessageBoxWindowContentMaxWidth}"
|
||||||
Margin="{TemplateBinding Padding}"
|
Margin="{TemplateBinding Padding}"
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Margin="24,0,24,24"
|
Margin="24,0,24,24"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
@@ -109,6 +109,7 @@
|
|||||||
Theme="{DynamicResource SolidButton}" />
|
Theme="{DynamicResource SolidButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</VisualLayerManager>
|
||||||
</Panel>
|
</Panel>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
@@ -155,6 +156,7 @@
|
|||||||
<ControlTemplate TargetType="u:MessageBoxControl">
|
<ControlTemplate TargetType="u:MessageBoxControl">
|
||||||
<Border
|
<Border
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
Focusable="True"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="Shadow"
|
Classes="Shadow"
|
||||||
|
|||||||
@@ -65,7 +65,9 @@
|
|||||||
Margin="{Binding $parent[u:UrsaWindow].TitleBarMargin}"
|
Margin="{Binding $parent[u:UrsaWindow].TitleBarMargin}"
|
||||||
LeftContent="{Binding $parent[u:UrsaWindow].LeftContent}"
|
LeftContent="{Binding $parent[u:UrsaWindow].LeftContent}"
|
||||||
RightContent="{Binding $parent[u:UrsaWindow].RightContent}" />
|
RightContent="{Binding $parent[u:UrsaWindow].RightContent}" />
|
||||||
<u:OverlayDialogHost IsModalStatusReporter="True" />
|
<VisualLayerManager>
|
||||||
|
<u:OverlayDialogHost IsModalStatusReporter="True" />
|
||||||
|
</VisualLayerManager>
|
||||||
</VisualLayerManager.ChromeOverlayLayer>
|
</VisualLayerManager.ChromeOverlayLayer>
|
||||||
<Panel>
|
<Panel>
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
@@ -93,6 +94,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = view,
|
Content = view,
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDialogControl(t, options);
|
ConfigureCustomDialogControl(t, options);
|
||||||
host.AddDialog(t);
|
host.AddDialog(t);
|
||||||
@@ -108,6 +110,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = new TView(),
|
Content = new TView(),
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureDefaultDialogControl(t, options);
|
ConfigureDefaultDialogControl(t, options);
|
||||||
host.AddModalDialog(t);
|
host.AddModalDialog(t);
|
||||||
@@ -123,6 +126,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = control,
|
Content = control,
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureDefaultDialogControl(t, options);
|
ConfigureDefaultDialogControl(t, options);
|
||||||
host.AddModalDialog(t);
|
host.AddModalDialog(t);
|
||||||
@@ -139,6 +143,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = new TView(),
|
Content = new TView(),
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDialogControl(t, options);
|
ConfigureCustomDialogControl(t, options);
|
||||||
host.AddModalDialog(t);
|
host.AddModalDialog(t);
|
||||||
@@ -154,6 +159,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = control,
|
Content = control,
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDialogControl(t, options);
|
ConfigureCustomDialogControl(t, options);
|
||||||
host.AddModalDialog(t);
|
host.AddModalDialog(t);
|
||||||
@@ -172,6 +178,7 @@ public static class OverlayDialog
|
|||||||
{
|
{
|
||||||
Content = view,
|
Content = view,
|
||||||
DataContext = vm,
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDialogControl(t, options);
|
ConfigureCustomDialogControl(t, options);
|
||||||
host.AddModalDialog(t);
|
host.AddModalDialog(t);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Ursa.Common;
|
using Ursa.Common;
|
||||||
using Ursa.Controls.Options;
|
using Ursa.Controls.Options;
|
||||||
|
|
||||||
@@ -60,7 +61,8 @@ public static class Drawer
|
|||||||
var drawer = new DefaultDrawerControl
|
var drawer = new DefaultDrawerControl
|
||||||
{
|
{
|
||||||
Content = new TView(),
|
Content = new TView(),
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureDefaultDrawer(drawer, options);
|
ConfigureDefaultDrawer(drawer, options);
|
||||||
host.AddModalDrawer(drawer);
|
host.AddModalDrawer(drawer);
|
||||||
@@ -75,7 +77,8 @@ public static class Drawer
|
|||||||
var drawer = new DefaultDrawerControl
|
var drawer = new DefaultDrawerControl
|
||||||
{
|
{
|
||||||
Content = control,
|
Content = control,
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureDefaultDrawer(drawer, options);
|
ConfigureDefaultDrawer(drawer, options);
|
||||||
host.AddModalDrawer(drawer);
|
host.AddModalDrawer(drawer);
|
||||||
@@ -92,7 +95,8 @@ public static class Drawer
|
|||||||
var drawer = new DefaultDrawerControl
|
var drawer = new DefaultDrawerControl
|
||||||
{
|
{
|
||||||
Content = view,
|
Content = view,
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureDefaultDrawer(drawer, options);
|
ConfigureDefaultDrawer(drawer, options);
|
||||||
host.AddModalDrawer(drawer);
|
host.AddModalDrawer(drawer);
|
||||||
@@ -152,7 +156,8 @@ public static class Drawer
|
|||||||
var dialog = new CustomDrawerControl
|
var dialog = new CustomDrawerControl
|
||||||
{
|
{
|
||||||
Content = new TView(),
|
Content = new TView(),
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDrawer(dialog, options);
|
ConfigureCustomDrawer(dialog, options);
|
||||||
host.AddModalDrawer(dialog);
|
host.AddModalDrawer(dialog);
|
||||||
@@ -167,7 +172,8 @@ public static class Drawer
|
|||||||
var dialog = new CustomDrawerControl
|
var dialog = new CustomDrawerControl
|
||||||
{
|
{
|
||||||
Content = control,
|
Content = control,
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDrawer(dialog, options);
|
ConfigureCustomDrawer(dialog, options);
|
||||||
host.AddModalDrawer(dialog);
|
host.AddModalDrawer(dialog);
|
||||||
@@ -185,7 +191,8 @@ public static class Drawer
|
|||||||
var dialog = new CustomDrawerControl
|
var dialog = new CustomDrawerControl
|
||||||
{
|
{
|
||||||
Content = view,
|
Content = view,
|
||||||
DataContext = vm
|
DataContext = vm,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
ConfigureCustomDrawer(dialog, options);
|
ConfigureCustomDrawer(dialog, options);
|
||||||
host.AddModalDrawer(dialog);
|
host.AddModalDrawer(dialog);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Input;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
@@ -63,7 +64,8 @@ public static class MessageBox
|
|||||||
Content = message,
|
Content = message,
|
||||||
Title = title,
|
Title = title,
|
||||||
Buttons = button,
|
Buttons = button,
|
||||||
MessageIcon = icon
|
MessageIcon = icon,
|
||||||
|
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
|
||||||
};
|
};
|
||||||
host.AddModalDialog(messageControl);
|
host.AddModalDialog(messageControl);
|
||||||
var result = await messageControl.ShowAsync<MessageBoxResult>();
|
var result = await messageControl.ShowAsync<MessageBoxResult>();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
|
using Avalonia.VisualTree;
|
||||||
using Irihi.Avalonia.Shared.Helpers;
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
using Irihi.Avalonia.Shared.Shapes;
|
using Irihi.Avalonia.Shared.Shapes;
|
||||||
using Ursa.Controls.OverlayShared;
|
using Ursa.Controls.OverlayShared;
|
||||||
@@ -170,9 +171,13 @@ public partial class OverlayDialogHost
|
|||||||
{
|
{
|
||||||
_maskAppearAnimation.RunAsync(mask);
|
_maskAppearAnimation.RunAsync(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var element = control.GetVisualDescendants().OfType<InputElement>().FirstOrDefault(a => a.Focusable);
|
||||||
|
element?.Focus();
|
||||||
_modalCount++;
|
_modalCount++;
|
||||||
IsInModalStatus = _modalCount > 0;
|
IsInModalStatus = _modalCount > 0;
|
||||||
control.IsClosed = false;
|
control.IsClosed = false;
|
||||||
|
control.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle dialog layer change event
|
// Handle dialog layer change event
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ using Avalonia;
|
|||||||
using Avalonia.Animation;
|
using Avalonia.Animation;
|
||||||
using Avalonia.Animation.Easings;
|
using Avalonia.Animation.Easings;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
|
using Avalonia.VisualTree;
|
||||||
using Irihi.Avalonia.Shared.Shapes;
|
using Irihi.Avalonia.Shared.Shapes;
|
||||||
using Ursa.Common;
|
using Ursa.Common;
|
||||||
using Ursa.Controls.OverlayShared;
|
using Ursa.Controls.OverlayShared;
|
||||||
@@ -67,6 +69,8 @@ public partial class OverlayDialogHost
|
|||||||
{
|
{
|
||||||
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
await Task.WhenAll(animation.RunAsync(control), _maskAppearAnimation.RunAsync(mask));
|
||||||
}
|
}
|
||||||
|
var element = control.GetVisualDescendants().OfType<InputElement>().FirstOrDefault(a => a.Focusable);
|
||||||
|
element?.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetDrawerPosition(DrawerControlBase control)
|
private void SetDrawerPosition(DrawerControlBase control)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public abstract class OverlayFeedbackElement: ContentControl
|
|||||||
|
|
||||||
static OverlayFeedbackElement()
|
static OverlayFeedbackElement()
|
||||||
{
|
{
|
||||||
|
FocusableProperty.OverrideDefaultValue<OverlayFeedbackElement>(false);
|
||||||
DataContextProperty.Changed.AddClassHandler<OverlayFeedbackElement, object?>((o, e) => o.OnDataContextChange(e));
|
DataContextProperty.Changed.AddClassHandler<OverlayFeedbackElement, object?>((o, e) => o.OnDataContextChange(e));
|
||||||
ClosedEvent.AddClassHandler<OverlayFeedbackElement>((o,e)=>o.OnClosed(e));
|
ClosedEvent.AddClassHandler<OverlayFeedbackElement>((o,e)=>o.OnClosed(e));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user