Browse Source

Improve directional naviation a bit.

In SelectingItemsControl. Still not completely there as we should do a
visual search in the absence of INavigablePanel (e.g. for Canvas, Grid).
Fixes half of #44.
pull/58/head
Steven Kirk 12 years ago
parent
commit
c29cac0b9f
  1. 15
      Perspex.Controls/INavigablePanel.cs
  2. 1
      Perspex.Controls/Perspex.Controls.csproj
  3. 36
      Perspex.Controls/Primitives/SelectingItemsControl.cs
  4. 49
      Perspex.Controls/StackPanel.cs

15
Perspex.Controls/INavigablePanel.cs

@ -0,0 +1,15 @@
// -----------------------------------------------------------------------
// <copyright file="INavigablePanel.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using Perspex.Input;
public interface INavigablePanel
{
Control GetControl(FocusNavigationDirection direction, Control from);
}
}

1
Perspex.Controls/Perspex.Controls.csproj

@ -40,6 +40,7 @@
<Compile Include="DropDown.cs" />
<Compile Include="IContentControl.cs" />
<Compile Include="IItemsPanel.cs" />
<Compile Include="INavigablePanel.cs" />
<Compile Include="Platform\IPopupImpl.cs" />
<Compile Include="Platform\ITopLevelImpl.cs" />
<Compile Include="Popup.cs" />

36
Perspex.Controls/Primitives/SelectingItemsControl.cs

@ -65,33 +65,25 @@ namespace Perspex.Controls.Primitives
protected virtual void MoveSelection(FocusNavigationDirection direction)
{
if (this.SelectedItem != null)
var panel = this.Presenter?.Panel as INavigablePanel;
var selected = this.SelectedItem;
var container = selected != null ?
this.ItemContainerGenerator.GetContainerForItem(selected) :
null;
if (panel != null)
{
int offset = 0;
var next = panel.GetControl(direction, container);
switch (direction)
if (next != null)
{
case FocusNavigationDirection.Up:
case FocusNavigationDirection.Left:
offset = -1;
break;
case FocusNavigationDirection.Down:
case FocusNavigationDirection.Right:
offset = 1;
break;
}
if (offset != 0)
{
var currentIndex = GetIndexOfItem(this.SelectedItem);
var index = currentIndex + offset;
if (index >= 0 && index < this.Items.Cast<object>().Count())
{
this.SelectedItem = this.Items.Cast<object>().ElementAt(index);
}
this.SelectedItem = this.ItemContainerGenerator.GetItemForContainer(next);
}
}
else
{
// TODO: Try doing a visual search?
}
}
protected override void OnKeyDown(KeyEventArgs e)

49
Perspex.Controls/StackPanel.cs

@ -7,10 +7,8 @@
namespace Perspex.Controls
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Input;
public enum Orientation
{
@ -18,7 +16,7 @@ namespace Perspex.Controls
Horizontal,
}
public class StackPanel : Panel
public class StackPanel : Panel, INavigablePanel
{
public static readonly PerspexProperty<double> GapProperty =
PerspexProperty.Register<StackPanel, double>("Gap");
@ -38,6 +36,49 @@ namespace Perspex.Controls
set { this.SetValue(OrientationProperty, value); }
}
Control INavigablePanel.GetControl(FocusNavigationDirection direction, Control from)
{
var horiz = this.Orientation == Orientation.Horizontal;
int index = this.Children.IndexOf(from);
switch (direction)
{
case FocusNavigationDirection.First:
index = 0;
break;
case FocusNavigationDirection.Last:
index = this.Children.Count - 1;
break;
case FocusNavigationDirection.Next:
++index;
break;
case FocusNavigationDirection.Previous:
++index;
break;
case FocusNavigationDirection.Left:
index = horiz ? index - 1 : -1;
break;
case FocusNavigationDirection.Right:
index = horiz ? index + 1 : -1;
break;
case FocusNavigationDirection.Up:
index = horiz ? -1 : index - 1;
break;
case FocusNavigationDirection.Down:
index = horiz ? -1 : index + 1;
break;
}
if (index >= 0 && index < this.Children.Count)
{
return this.Children[index];
}
else
{
return null;
}
}
protected override Size MeasureOverride(Size availableSize)
{
double childAvailableWidth = double.PositiveInfinity;

Loading…
Cancel
Save