Browse Source

Added KeyboardNavigationMode.Contained.

pull/72/merge
Steven Kirk 11 years ago
parent
commit
2472bf26cc
  1. 6
      Perspex.Input/KeyboardNavigationHandler.cs
  2. 32
      Perspex.Input/KeyboardNavigationMode.cs
  3. 13
      Tests/Perspex.Input.UnitTests/GlobalSuppressions.cs
  4. 160
      Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs
  5. 3
      Tests/Perspex.Input.UnitTests/Perspex.Input.UnitTests.csproj

6
Perspex.Input/KeyboardNavigationHandler.cs

@ -65,6 +65,8 @@ namespace Perspex.Input
case KeyboardNavigationMode.Cycle:
return GetNextInContainer(element, container) ??
GetDescendents(container).FirstOrDefault();
case KeyboardNavigationMode.Contained:
return GetNextInContainer(element, container);
default:
return GetFirstInNextContainer(container);
}
@ -98,6 +100,8 @@ namespace Perspex.Input
case KeyboardNavigationMode.Cycle:
return GetPreviousInContainer(element, container) ??
GetDescendents(container).LastOrDefault();
case KeyboardNavigationMode.Contained:
return GetPreviousInContainer(element, container);
default:
return GetLastInPreviousContainer(container);
}
@ -164,7 +168,7 @@ namespace Perspex.Input
{
var mode = KeyboardNavigation.GetTabNavigation((InputElement)element);
if (mode == KeyboardNavigationMode.Never)
if (mode == KeyboardNavigationMode.None)
{
yield break;
}

32
Perspex.Input/KeyboardNavigationMode.cs

@ -6,11 +6,41 @@
namespace Perspex.Input
{
/// <summary>
/// Defines the mode of keyboard traversal within a container when the tab or arrow keys are
/// pressed.
/// </summary>
public enum KeyboardNavigationMode
{
/// <summary>
/// Items in the container will be cycled through, and focus will be moved to the
/// previous/next container after the first/last control in the container.
/// </summary>
Continue,
/// <summary>
/// Items in the container will be cycled through, and moving past the first or last
/// control in the container will cause the last/first control to be focused.
/// </summary>
Cycle,
/// <summary>
/// Items in the container will be cycled through and focus will stop moving when the edge
/// of the container is reached.
/// </summary>
Contained,
/// <summary>
/// When focus is moved into the container, the control described by the
/// <see cref="KeyboardNavigation.TabOnceActiveElementProperty"/> attached property on the
/// container will be focused. When focus moves away from this control, focus will move to
/// the previous/next container.
/// </summary>
Once,
Never,
/// <summary>
/// The container's children will not be focused when using the tab key.
/// </summary>
None,
}
}

13
Tests/Perspex.Input.UnitTests/GlobalSuppressions.cs

@ -0,0 +1,13 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(
"StyleCop.CSharp.MaintainabilityRules",
"SA1401:Fields must be private",
Justification = "PerspexProperty fields should not be private.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(
"StyleCop.CSharp.DocumentationRules",
"SA1600:Elements must be documented",
Justification = "Tests should be self-documenting")]

160
Tests/Perspex.Input.UnitTests/KeyboardNavigationTests.cs → Tests/Perspex.Input.UnitTests/KeyboardNavigationTests_Tab.cs

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="KeyboardNavigationTests.cs" company="Steven Kirk">
// <copyright file="KeyboardNavigationTests_Tab.cs" company="Steven Kirk">
// Copyright 2015 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -9,7 +9,7 @@ namespace Perspex.Input.UnitTests
using Perspex.Controls;
using Xunit;
public class KeyboardNavigationTests
public class KeyboardNavigationTests_Tab
{
[Fact]
public void GetNextInTabOrder_Continue_Returns_Next_Control_In_Container()
@ -294,6 +294,82 @@ namespace Perspex.Input.UnitTests
Assert.Equal(next, result);
}
[Fact]
public void GetNextInTabOrder_Contained_Returns_Next_Control_In_Container()
{
StackPanel container;
Button current;
Button next;
var top = new StackPanel
{
Children = new Controls
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
Children = new Controls
{
new Button { Name = "Button1" },
(current = new Button { Name = "Button2" }),
(next = new Button { Name = "Button3" }),
}
}),
new StackPanel
{
Children = new Controls
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
new Button { Name = "Button6" },
}
},
}
};
var result = KeyboardNavigationHandler.GetNextInTabOrder(current);
Assert.Equal(next, result);
}
[Fact]
public void GetNextInTabOrder_Contained_Stops_At_End()
{
StackPanel container;
Button current;
Button next;
var top = new StackPanel
{
Children = new Controls
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
Children = new Controls
{
(next = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
(current = new Button { Name = "Button3" }),
}
}),
new StackPanel
{
Children = new Controls
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
new Button { Name = "Button6" },
}
},
}
};
var result = KeyboardNavigationHandler.GetNextInTabOrder(current);
Assert.Null(result);
}
[Fact]
public void GetNextInTabOrder_Once_Moves_To_Next_Container()
{
@ -385,7 +461,7 @@ namespace Perspex.Input.UnitTests
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Never,
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.None,
Children = new Controls
{
new Button { Name = "Button1" },
@ -423,7 +499,7 @@ namespace Perspex.Input.UnitTests
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Never,
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.None,
Children = new Controls
{
new Button { Name = "Button1" },
@ -715,6 +791,82 @@ namespace Perspex.Input.UnitTests
Assert.Equal(next, result);
}
[Fact]
public void GetPreviousInTabOrder_Contained_Returns_Previous_Control_In_Container()
{
StackPanel container;
Button current;
Button next;
var top = new StackPanel
{
Children = new Controls
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
Children = new Controls
{
(next = new Button { Name = "Button1" }),
(current = new Button { Name = "Button2" }),
new Button { Name = "Button3" },
}
}),
new StackPanel
{
Children = new Controls
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
new Button { Name = "Button6" },
}
},
}
};
var result = KeyboardNavigationHandler.GetPreviousInTabOrder(current);
Assert.Equal(next, result);
}
[Fact]
public void GetPreviousInTabOrder_Contained_Stops_At_Beginning()
{
StackPanel container;
Button current;
Button next;
var top = new StackPanel
{
Children = new Controls
{
(container = new StackPanel
{
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Contained,
Children = new Controls
{
(current = new Button { Name = "Button1" }),
new Button { Name = "Button2" },
(next = new Button { Name = "Button3" }),
}
}),
new StackPanel
{
Children = new Controls
{
new Button { Name = "Button4" },
new Button { Name = "Button5" },
new Button { Name = "Button6" },
}
},
}
};
var result = KeyboardNavigationHandler.GetPreviousInTabOrder(current);
Assert.Null(result);
}
[Fact]
public void GetPreviousInTabOrder_Once_Moves_To_Previous_Container()
{

3
Tests/Perspex.Input.UnitTests/Perspex.Input.UnitTests.csproj

@ -59,7 +59,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="KeyboardNavigationTests.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="KeyboardNavigationTests_Tab.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

Loading…
Cancel
Save