Initial checkin of GazeControls code
|
@ -0,0 +1,234 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.filters
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
## TODO: Comment the next line if you want to checkin your
|
||||
## web deploy settings but do note that will include unencrypted
|
||||
## passwords
|
||||
#*.pubxml
|
||||
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
BundleArtifacts
|
||||
!/build
|
||||
/build/tools/GitVersion.CommandLine
|
||||
AppPackages
|
||||
|
||||
# NuGet V3 artifacts
|
||||
*-packages.config
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
project.lock.json
|
||||
msbuild.binlog
|
||||
*.project.lock.json
|
||||
/build/tools/**
|
||||
!/build/tools/packages.config
|
||||
|
||||
# Generated file from .ttinclude
|
||||
**/Generated/TypeInfo.g.cs
|
||||
|
||||
# TAEF Log output
|
||||
WexLogFileOutput
|
||||
*.wtl
|
|
@ -0,0 +1,34 @@
|
|||
<Project Sdk="MSBuild.Sdk.Extras">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>uap10.0.17763</TargetFrameworks>
|
||||
<Title>Windows Community Toolkit Gaze Controls Library</Title>
|
||||
<Description>A library controls optimized for gaze interaction</Description>
|
||||
<PackageTags>Windows;Community;Toolkit;WCT;UWP;Gaze;Eye;Tracker;EyeTracker</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="KeyboardLayouts\FilenameEntry.xaml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="KeyboardLayouts\FullKeyboard.xaml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="KeyboardLayouts\MinAAC.xaml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="KeyboardLayouts\TwoStageKeyboard.xaml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Input.GazeInteraction" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI" Version="7.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Strings\en-us\Resources.resw" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,48 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Gaze optimized file picker to open files
|
||||
/// </summary>
|
||||
public sealed class GazeFileOpenPicker : GazeFilePicker
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GazeFileOpenPicker"/> class.
|
||||
/// </summary>
|
||||
public GazeFileOpenPicker()
|
||||
{
|
||||
Title = GetString("FileOpen/Title");
|
||||
this.FilePickerInitialized += OnGazeFileOpenPickerInitialized;
|
||||
}
|
||||
|
||||
private void OnGazeFileOpenPickerInitialized(object sender, EventArgs e)
|
||||
{
|
||||
SelectButton = Button2;
|
||||
SelectButton.Click += OnOpenButtonClicked;
|
||||
SelectButton.Content = GetString("Open");
|
||||
|
||||
Button3.Click += OnCancelClicked;
|
||||
Button3.Content = GetString("Cancel");
|
||||
}
|
||||
|
||||
private void OnCancelClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnOpenButtonClicked(object sender, RoutedEventArgs args)
|
||||
{
|
||||
Debug.Assert(!CurrentSelectedItem.IsFolder, "Selected item should not be a folder!");
|
||||
SelectedItem = CurrentSelectedItem?.Item as StorageFile;
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
<ContentDialog
|
||||
x:Class="CommunityToolkit.Labs.Uwp.GazeControls.GazeFilePicker"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
MinWidth="1000"
|
||||
Width="1500" Height="800"
|
||||
FullSizeDesired="True"
|
||||
>
|
||||
<ContentDialog.Resources>
|
||||
<DataTemplate x:Key="FolderItemTemplate" x:DataType="local:StorageItem">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="8*" />
|
||||
<RowDefinition Height="2*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image Grid.Row="0" Width="128" Height="128" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="{x:Bind Thumbnail}" />
|
||||
<TextBlock Grid.Row="1" HorizontalAlignment="Stretch" Text="{x:Bind Name}" HorizontalTextAlignment="Center" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<Style x:Key="CommandSpaceButtonStyles" TargetType="Button">
|
||||
<Setter Property="Height" Value="120" />
|
||||
<Setter Property="Width" Value="240" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Bottom" />
|
||||
</Style>
|
||||
<Style x:Key="PickerButtonStyles" TargetType="Button">
|
||||
<Setter Property="Height" Value="120" />
|
||||
<Setter Property="Width" Value="120" />
|
||||
<Setter Property="Margin" Value="0,0,16,8" />
|
||||
</Style>
|
||||
<x:Double x:Key="ContentDialogMaxWidth">9999</x:Double>
|
||||
<x:Double x:Key="ContentDialogMaxHeight">9999</x:Double>
|
||||
<Style TargetType="local:GazeFilePicker" BasedOn="{StaticResource DefaultContentDialogStyle}" />
|
||||
</ContentDialog.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="140"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" x:Name="FilenameEntryGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="80"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox x:Name="FilenameEditBox" Grid.Row="0" TextWrapping="Wrap" FontSize="45" Margin="3,3,0,3" AcceptsReturn="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
<local:GazeKeyboard x:Name="GazeKeyboard" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
<UserControl Grid.Row="0" x:Name="FileListingGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="130" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="130" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel x:Name="FavoritesPanel" Grid.Row="0" Orientation="Horizontal">
|
||||
</StackPanel>
|
||||
|
||||
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="1" Margin="0,0,0,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="140"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:ScrollGridView Grid.Row="0" Grid.Column="0" x:Name="CurrentFolderContents"
|
||||
IsItemClickEnabled="True"
|
||||
SelectionMode="Single"
|
||||
ItemTemplate="{StaticResource FolderItemTemplate}"
|
||||
ItemsSource="{x:Bind Mode=OneWay, Path=CurrentFolderItems}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
ItemClick="OnCurrentFolderContentsItemClick"
|
||||
MinWidth="1500"
|
||||
/>
|
||||
<local:GazeScrollBar Grid.Row="0" Grid.Column="1" x:Name="CurrentFolderScrollbar" Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="2" Margin="0,10,0,0" HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="144"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="ParentFolderButton" Grid.Column="0" Grid.RowSpan="2" Width="120" Height="120" Click="OnParentFolderClick" Content="" FontFamily="Segoe MDL2 Assets" FontSize="32" Margin="0,0,20,0"/>
|
||||
<Border Grid.Row="0" Grid.Column="1" BorderThickness="1" BorderBrush="Black" HorizontalAlignment="Stretch" Margin="0,0,0,8">
|
||||
<ScrollViewer x:Name="SelectedItemScrollViewer" VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Hidden" VerticalScrollMode="Disabled"
|
||||
HorizontalScrollMode="Enabled" >
|
||||
<TextBlock Text="{x:Bind Mode=OneWay, Path=CurrentSelectedItem.Path}"
|
||||
FontWeight="Bold" FontSize="18" Margin="16,0,0,0"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Stretch" Padding="0,0,16,0"/>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
<Border Grid.Row="1" Grid.Column="1" BorderThickness="1" BorderBrush="Black" Margin="0,8,0,0">
|
||||
<TextBlock x:Name="FileTypeFilterTextBlock" FontSize="18"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
<Border Grid.Row="0" x:Name="FileOverwriteConfirmationGrid"
|
||||
BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" Visibility="Collapsed" Background="White">
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="60"/>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="180"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="Blue" >
|
||||
<TextBlock Text="Confirm overwrite" HorizontalAlignment="Left" FontSize="32" Foreground="White" Padding="5,0,0,0"/>
|
||||
</Border>
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" Background="White" >
|
||||
<TextBlock Text="" FontSize="64" FontFamily="Segoe MDL2 Assets" Foreground="Yellow" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="OverwriteWarning" FontSize="32" VerticalAlignment="Bottom" Margin="0,0,20,0" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Text="Do you want to replace it?" FontSize="32" VerticalAlignment="Top" Margin="0,0,20,0" />
|
||||
<Grid Grid.Row="3" Grid.ColumnSpan="2" Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" x:Name="YesBtn" Content="Yes" HorizontalAlignment="Center" Style="{StaticResource CommandSpaceButtonStyles}" Margin="10,0,10,0"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" x:Name="NoBtn" Content="No" HorizontalAlignment="Center" Style="{StaticResource CommandSpaceButtonStyles}" Margin="10,0,10,0"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
<UserControl Grid.Row="1" x:Name="CommandRow" VerticalAlignment="Bottom">
|
||||
<Grid VerticalAlignment="Bottom">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0" x:Name="Col0Button" Style="{StaticResource CommandSpaceButtonStyles}" Visibility="Collapsed"/>
|
||||
<Button Grid.Column="1" x:Name="Col1Button" Style="{StaticResource CommandSpaceButtonStyles}" Visibility="Collapsed"/>
|
||||
<Button Grid.Column="2" x:Name="Col2Button" Style="{StaticResource CommandSpaceButtonStyles}" />
|
||||
<Button Grid.Column="3" x:Name="Col3Button" Style="{StaticResource CommandSpaceButtonStyles}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
</Grid>
|
||||
</ContentDialog>
|
|
@ -0,0 +1,382 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
|
||||
using Microsoft.Toolkit.Uwp.UI;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Foundation;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
internal enum FilePickerView
|
||||
{
|
||||
FileListing,
|
||||
FilenameEntry,
|
||||
FileOverwriteConfirmation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides file picker dialogs optimized for gaze input
|
||||
/// </summary>
|
||||
public abstract partial class GazeFilePicker : ContentDialog
|
||||
{
|
||||
private bool _dialogInitialized;
|
||||
private bool _refreshNeeded;
|
||||
private ResourceLoader _resourceLoader;
|
||||
|
||||
internal FilePickerView CurrentView { get; private set; }
|
||||
|
||||
internal Button SelectButton { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the event handler that is called when the file picker has fully initialized
|
||||
/// </summary>
|
||||
public EventHandler FilePickerInitialized { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selected file in the dialog as a StorageFile
|
||||
/// </summary>
|
||||
public StorageFile SelectedItem { get; protected set; }
|
||||
|
||||
internal Button Button0 { get; private set; }
|
||||
|
||||
internal Button Button1 { get; private set; }
|
||||
|
||||
internal Button Button2 { get; private set; }
|
||||
|
||||
internal Button Button3 { get; private set; }
|
||||
|
||||
internal Button YesButton { get; private set; }
|
||||
|
||||
internal Button NoButton { get; private set; }
|
||||
|
||||
internal TextBox FilenameTextbox { get; private set; }
|
||||
|
||||
private StorageFolder _currentFolder;
|
||||
|
||||
internal static readonly DependencyProperty CurrentSelectedItemProperty =
|
||||
DependencyProperty.Register(
|
||||
"CurrentSelectedItem",
|
||||
typeof(StorageItem),
|
||||
typeof(GazeFilePicker),
|
||||
null);
|
||||
|
||||
internal StorageItem CurrentSelectedItem
|
||||
{
|
||||
get { return (StorageItem)GetValue(CurrentSelectedItemProperty); }
|
||||
set { SetValue(CurrentSelectedItemProperty, value); }
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty CurrentFolderItemsProperty =
|
||||
DependencyProperty.Register(
|
||||
"CurrentFolderItems",
|
||||
typeof(ObservableCollection<StorageItem>),
|
||||
typeof(GazeFilePicker),
|
||||
null);
|
||||
|
||||
internal ObservableCollection<StorageItem> CurrentFolderItems
|
||||
{
|
||||
get { return (ObservableCollection<StorageItem>)GetValue(CurrentFolderItemsProperty); }
|
||||
set { SetValue(CurrentFolderItemsProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current folder for the file picker dialog
|
||||
/// </summary>
|
||||
public StorageFolder CurrentFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentFolder;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
RefreshContents(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of storage folders that appear as shortcuts
|
||||
/// on top of the folder view
|
||||
/// </summary>
|
||||
public List<StorageFolder> Favorites { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of file types that the file open picker displays.
|
||||
/// </summary>
|
||||
public List<string> FileTypeFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GazeFilePicker"/> class.
|
||||
/// </summary>
|
||||
public GazeFilePicker()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Loaded += this.OnGazeFilePickerLoaded;
|
||||
|
||||
FileTypeFilter = new List<string>();
|
||||
|
||||
var resourcePath = "CommunityToolkit.Labs.Uwp.GazeControls/Resources";
|
||||
_resourceLoader = ResourceLoader.GetForViewIndependentUse(resourcePath);
|
||||
}
|
||||
|
||||
private async void OnGazeFilePickerLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Button0 = Col0Button;
|
||||
Button1 = Col1Button;
|
||||
Button2 = Col2Button;
|
||||
Button3 = Col3Button;
|
||||
YesButton = YesBtn;
|
||||
NoButton = NoBtn;
|
||||
FilenameTextbox = FilenameEditBox;
|
||||
|
||||
CurrentFolderContents.GazeScrollBar = CurrentFolderScrollbar;
|
||||
|
||||
GazeInput.SetMaxDwellRepeatCount(this, 2);
|
||||
|
||||
GazeKeyboard.Target = FilenameTextbox;
|
||||
|
||||
var uri = new Uri($"ms-appx:///CommunityToolkit.Labs.Uwp.GazeControls/KeyboardLayouts/FilenameEntry.xaml");
|
||||
var layoutFile = await StorageFile.GetFileFromApplicationUriAsync(uri);
|
||||
await GazeKeyboard.TryLoadLayoutAsync(layoutFile);
|
||||
|
||||
var dialogSpace = this.FindDescendant("DialogSpace") as Grid;
|
||||
var commandSpace = this.FindDescendant("CommandSpace") as Grid;
|
||||
dialogSpace.Children.Remove(commandSpace);
|
||||
|
||||
SetFilePickerView(FilePickerView.FileListing);
|
||||
CreateFavoritesButtons();
|
||||
SetFileTypeFilterText();
|
||||
|
||||
_dialogInitialized = true;
|
||||
|
||||
if (_refreshNeeded)
|
||||
{
|
||||
RefreshContents(_currentFolder);
|
||||
}
|
||||
|
||||
if (FilePickerInitialized != null)
|
||||
{
|
||||
FilePickerInitialized(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the localized string from resources
|
||||
/// </summary>
|
||||
/// <param name="resource">Resource id of the string to get</param>
|
||||
/// <returns>Localized string</returns>
|
||||
protected string GetString(string resource)
|
||||
{
|
||||
return _resourceLoader.GetString(resource);
|
||||
}
|
||||
|
||||
private void SetFileTypeFilterText()
|
||||
{
|
||||
var filters = FileTypeFilter.Select(item => Regex.Replace(item, "^\u002E", "*."));
|
||||
var allFilters = string.Join(", ", filters);
|
||||
FileTypeFilterTextBlock.Text = allFilters;
|
||||
}
|
||||
|
||||
private async void CreateFavoritesButtons()
|
||||
{
|
||||
var favoritesPanel = this.FindDescendant("FavoritesPanel") as StackPanel;
|
||||
Debug.Assert(favoritesPanel != null, "KnownFoldersPanel not found");
|
||||
|
||||
var style = (Style)this.Resources["PickerButtonStyles"];
|
||||
|
||||
favoritesPanel.Children.Clear();
|
||||
|
||||
List<StorageFolder> favorites;
|
||||
if ((Favorites == null) || (Favorites.Count == 0))
|
||||
{
|
||||
KnownFolderId[] knownFolderIds =
|
||||
{
|
||||
KnownFolderId.DocumentsLibrary,
|
||||
KnownFolderId.PicturesLibrary,
|
||||
KnownFolderId.VideosLibrary,
|
||||
KnownFolderId.MusicLibrary
|
||||
};
|
||||
|
||||
favorites = new List<StorageFolder>();
|
||||
foreach (var folderId in knownFolderIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
var knownFolder = await KnownFolders.GetFolderAsync(folderId);
|
||||
favorites.Add(knownFolder);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
favorites = Favorites;
|
||||
}
|
||||
|
||||
foreach (var folder in favorites)
|
||||
{
|
||||
var button = new Button();
|
||||
button.Style = style;
|
||||
button.Tag = folder;
|
||||
button.Click += OnFavoritesClick;
|
||||
button.Content = folder.Name;
|
||||
|
||||
favoritesPanel.Children.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to create a folder in _currentFolder
|
||||
/// </summary>
|
||||
/// <returns>Task</returns>
|
||||
protected async Task CreateFolderAsync()
|
||||
{
|
||||
await _currentFolder.CreateFolderAsync(FilenameTextbox.Text);
|
||||
RefreshContents(_currentFolder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to create a file in the current folder
|
||||
/// </summary>
|
||||
/// <returns>IAsyncOperation[StorageFile]</returns>
|
||||
protected IAsyncOperation<StorageFile> CreateFileAsync(bool fromTextbox)
|
||||
{
|
||||
var filename = fromTextbox ? FilenameTextbox.Text : CurrentSelectedItem.Name;
|
||||
return _currentFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to set the overwrite warning text
|
||||
/// </summary>
|
||||
protected void SetOverwriteWarningText()
|
||||
{
|
||||
var warningTextFormat = GetString("OverwriteWarning");
|
||||
OverwriteWarning.Text = string.Format(warningTextFormat, CurrentSelectedItem.Name);
|
||||
}
|
||||
|
||||
internal void SetFilePickerView(FilePickerView filePickerView)
|
||||
{
|
||||
FrameworkElement[] viewGrids = { FileListingGrid, FilenameEntryGrid, FileOverwriteConfirmationGrid };
|
||||
foreach (var grid in viewGrids)
|
||||
{
|
||||
grid.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
viewGrids[(int)filePickerView].Visibility = Visibility.Visible;
|
||||
CurrentView = filePickerView;
|
||||
|
||||
if (CurrentView == FilePickerView.FileOverwriteConfirmation)
|
||||
{
|
||||
FileListingGrid.Visibility = Visibility.Visible;
|
||||
FileListingGrid.IsEnabled = false;
|
||||
CommandRow.IsEnabled = false;
|
||||
}
|
||||
else if (CurrentView == FilePickerView.FileListing)
|
||||
{
|
||||
FileListingGrid.IsEnabled = true;
|
||||
CommandRow.IsEnabled = true;
|
||||
}
|
||||
|
||||
FixFileListingButtons();
|
||||
}
|
||||
|
||||
private async void FixFileListingButtons()
|
||||
{
|
||||
var folder = await _currentFolder.GetParentAsync();
|
||||
ParentFolderButton.IsEnabled = folder != null;
|
||||
|
||||
SelectButton.IsEnabled = (CurrentSelectedItem != null) && (!CurrentSelectedItem.IsFolder);
|
||||
}
|
||||
|
||||
private Task[] GetThumbnailsAsync(ObservableCollection<StorageItem> storageItems)
|
||||
{
|
||||
Task[] tasks = new Task[storageItems.Count];
|
||||
for (int i = 0; i < storageItems.Count; i++)
|
||||
{
|
||||
tasks[i] = storageItems[i].GetThumbnailAsync();
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
private async void RefreshContents(StorageFolder folder)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentFolder = folder;
|
||||
|
||||
if (!_dialogInitialized)
|
||||
{
|
||||
_refreshNeeded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshNeeded = false;
|
||||
|
||||
var allItems = await folder.GetItemsAsync();
|
||||
var items = allItems.Where(item => item.IsOfType(StorageItemTypes.Folder) ||
|
||||
FileTypeFilter.Contains((item as StorageFile).FileType));
|
||||
var currentFolderItems = new ObservableCollection<StorageItem>(items.Select(item => new StorageItem(item)));
|
||||
|
||||
var tasks = GetThumbnailsAsync(currentFolderItems);
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
SelectedItemScrollViewer.ChangeView(SelectedItemScrollViewer.ExtentWidth, 0.0, 1.0f);
|
||||
|
||||
CurrentSelectedItem = new StorageItem(_currentFolder);
|
||||
CurrentFolderItems = currentFolderItems;
|
||||
|
||||
FixFileListingButtons();
|
||||
}
|
||||
|
||||
private void OnCurrentFolderContentsItemClick(object sender, ItemClickEventArgs e)
|
||||
{
|
||||
var clickedItem = e.ClickedItem as StorageItem;
|
||||
var selectedItem = CurrentFolderContents.SelectedItem as StorageItem;
|
||||
|
||||
if (clickedItem.IsFolder)
|
||||
{
|
||||
RefreshContents(clickedItem.Item as StorageFolder);
|
||||
SelectButton.IsEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectButton.IsEnabled = true;
|
||||
}
|
||||
|
||||
CurrentSelectedItem = clickedItem;
|
||||
}
|
||||
|
||||
private async void OnParentFolderClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var folder = await _currentFolder.GetParentAsync();
|
||||
RefreshContents(folder);
|
||||
}
|
||||
|
||||
private void OnFavoritesClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as Button;
|
||||
var folder = button.Tag as StorageFolder;
|
||||
RefreshContents(folder);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// This class provides a file-save picker dialog for UWP apps that is optimized for gaze input
|
||||
/// </summary>
|
||||
public sealed class GazeFileSavePicker : GazeFilePicker
|
||||
{
|
||||
private bool _newFolderMode;
|
||||
private Button _newFolderButton;
|
||||
private Button _enterFilenameButton;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GazeFileSavePicker"/> class.
|
||||
/// </summary>
|
||||
public GazeFileSavePicker()
|
||||
{
|
||||
Title = GetString("FileSave/Title");
|
||||
FilePickerInitialized += OnGazeFileSavePickerInitialized;
|
||||
}
|
||||
|
||||
private void ShowCommandspaceButtons(bool show)
|
||||
{
|
||||
var visibility = show ? Visibility.Visible : Visibility.Collapsed;
|
||||
_newFolderButton.Visibility = visibility;
|
||||
_enterFilenameButton.Visibility = visibility;
|
||||
|
||||
_newFolderButton.Content = GetString("NewFolder");
|
||||
_enterFilenameButton.Content = GetString("EnterFilename");
|
||||
SelectButton.Content = GetString("Save");
|
||||
Button3.Content = GetString("Cancel");
|
||||
}
|
||||
|
||||
private void OnEnterFilenameClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FilenameTextbox.Text = string.Empty;
|
||||
FilenameTextbox.TextChanged += OnFilenameChanged;
|
||||
ShowCommandspaceButtons(false);
|
||||
SetFilePickerView(FilePickerView.FilenameEntry);
|
||||
}
|
||||
|
||||
private void OnFilenameChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
SelectButton.IsEnabled = FilenameTextbox.Text.Length > 0;
|
||||
}
|
||||
|
||||
private void OnNewFolderClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_newFolderMode = true;
|
||||
FilenameTextbox.Text = string.Empty;
|
||||
FilenameTextbox.TextChanged += OnFilenameChanged;
|
||||
ShowCommandspaceButtons(false);
|
||||
SetFilePickerView(FilePickerView.FilenameEntry);
|
||||
}
|
||||
|
||||
private void OnGazeFileSavePickerInitialized(object sender, EventArgs e)
|
||||
{
|
||||
_newFolderButton = Button0;
|
||||
_newFolderButton.Click += OnNewFolderClicked;
|
||||
|
||||
_enterFilenameButton = Button1;
|
||||
_enterFilenameButton.Click += OnEnterFilenameClicked;
|
||||
|
||||
SelectButton = Button2;
|
||||
SelectButton.Click += OnSaveButtonClicked;
|
||||
|
||||
Button3.Click += OnCloseButtonClicked;
|
||||
|
||||
YesButton.Click += OnSaveButtonClicked;
|
||||
NoButton.Click += OnCloseButtonClicked;
|
||||
|
||||
ShowCommandspaceButtons(true);
|
||||
}
|
||||
|
||||
private async void OnSaveButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_newFolderMode)
|
||||
{
|
||||
_newFolderMode = false;
|
||||
await CreateFolderAsync();
|
||||
SetFilePickerView(FilePickerView.FileListing);
|
||||
ShowCommandspaceButtons(true);
|
||||
}
|
||||
else if (CurrentView == FilePickerView.FilenameEntry)
|
||||
{
|
||||
SelectedItem = await CreateFileAsync(true);
|
||||
Hide();
|
||||
}
|
||||
else if (CurrentView == FilePickerView.FileListing)
|
||||
{
|
||||
SetOverwriteWarningText();
|
||||
SetFilePickerView(FilePickerView.FileOverwriteConfirmation);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedItem = await CreateFileAsync(false);
|
||||
Hide();
|
||||
}
|
||||
|
||||
FilenameTextbox.TextChanged -= OnFilenameChanged;
|
||||
}
|
||||
|
||||
private void OnCloseButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (CurrentView == FilePickerView.FileListing)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFilePickerView(FilePickerView.FileListing);
|
||||
ShowCommandspaceButtons(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<UserControl
|
||||
x:Class="CommunityToolkit.Labs.Uwp.GazeControls.GazeKeyboard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="600"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid>
|
||||
<Grid x:Name="DummyHiddenGrid" Visibility="Collapsed">
|
||||
<Button local:GazeKeyboard.KeyType="Normal" local:GazeKeyboard.VK="1"/>
|
||||
</Grid>
|
||||
<Grid x:Name="LayoutRoot">
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,467 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Uwp.UI;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Data.Text;
|
||||
using Windows.Storage;
|
||||
using Windows.System;
|
||||
using Windows.UI.Input.Preview.Injection;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Markup;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Gaze optimized soft keyboard with support for custom layouts and predictions
|
||||
/// </summary>
|
||||
public sealed partial class GazeKeyboard : UserControl
|
||||
{
|
||||
private InputInjector _injector;
|
||||
private KeyboardPage _rootPage;
|
||||
private TextPredictionGenerator _textPredictionGenerator;
|
||||
private WordsSegmenter _wordsSegmenter;
|
||||
private string _predictionLanguage;
|
||||
private Button[] _predictionTargets;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target text box for injecting keys
|
||||
/// </summary>
|
||||
public TextBox Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text prediction language
|
||||
/// </summary>
|
||||
public string PredictionLanguage
|
||||
{
|
||||
get
|
||||
{
|
||||
return _predictionLanguage;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_predictionLanguage = value;
|
||||
_textPredictionGenerator = new TextPredictionGenerator(value);
|
||||
_textPredictionGenerator.InputScope = Windows.UI.Text.Core.CoreTextInputScope.Text;
|
||||
_wordsSegmenter = new WordsSegmenter(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the prediction targets
|
||||
/// </summary>
|
||||
public Button[] PredictionTargets
|
||||
{
|
||||
get
|
||||
{
|
||||
return _predictionTargets;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_predictionTargets != null)
|
||||
{
|
||||
foreach (var target in _predictionTargets)
|
||||
{
|
||||
target.Click -= OnPredictionSelected;
|
||||
}
|
||||
}
|
||||
|
||||
_predictionTargets = value;
|
||||
foreach (var target in _predictionTargets)
|
||||
{
|
||||
target.Click += OnPredictionSelected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GazeKeyboard"/> class.
|
||||
/// </summary>
|
||||
public GazeKeyboard()
|
||||
{
|
||||
InitializeComponent();
|
||||
PredictionLanguage = "en-US";
|
||||
_injector = InputInjector.TryCreate();
|
||||
}
|
||||
|
||||
private void BuildPageHierarchy(KeyboardPage parent)
|
||||
{
|
||||
var children = GazeKeyboard.GetPageList(parent.Page);
|
||||
foreach (var childName in children)
|
||||
{
|
||||
var node = parent.Page.FindName(childName) as FrameworkElement;
|
||||
if (node != null)
|
||||
{
|
||||
var childPage = new KeyboardPage(node, parent);
|
||||
parent.ChildrenNames.Add(childName);
|
||||
parent.Children.Add(childPage);
|
||||
BuildPageHierarchy(childPage);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent.Children.Count > 0)
|
||||
{
|
||||
parent.CurrentChild = parent.Children[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the given keyboard layout from a file
|
||||
/// </summary>
|
||||
/// <param name="layoutFile"> A XAML file that contains the layout of the keyboard</param>
|
||||
/// <returns>Task</returns>
|
||||
public async Task TryLoadLayoutAsync(StorageFile layoutFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
var xaml = await FileIO.ReadTextAsync(layoutFile);
|
||||
var xamlNode = XamlReader.Load(xaml) as FrameworkElement;
|
||||
|
||||
foreach (var button in xamlNode.FindDescendants().OfType<ButtonBase>())
|
||||
{
|
||||
button.Click += OnKeyboardButtonClick;
|
||||
}
|
||||
|
||||
_rootPage = new KeyboardPage(xamlNode, null);
|
||||
BuildPageHierarchy(_rootPage);
|
||||
|
||||
LayoutRoot.Children.Add(xamlNode);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private bool HandleVirtualKey(int vk)
|
||||
{
|
||||
if (vk < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var key = new InjectedInputKeyboardInfo();
|
||||
key.VirtualKey = (ushort)vk;
|
||||
_injector.InjectKeyboardInput(new[] { key });
|
||||
|
||||
UpdatePredictions();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandleVirtualKeyList(List<int> vkList)
|
||||
{
|
||||
var state = new Dictionary<int, bool>();
|
||||
var keys = new List<InjectedInputKeyboardInfo>();
|
||||
foreach (var vk in vkList)
|
||||
{
|
||||
var key = new InjectedInputKeyboardInfo();
|
||||
key.VirtualKey = (ushort)vk;
|
||||
if (state.ContainsKey(vk))
|
||||
{
|
||||
key.KeyOptions = InjectedInputKeyOptions.KeyUp;
|
||||
state.Remove(vk);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Add(vk, true);
|
||||
}
|
||||
|
||||
keys.Add(key);
|
||||
}
|
||||
|
||||
_injector.InjectKeyboardInput(keys);
|
||||
|
||||
UpdatePredictions();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandleUnicodeChar(string unicode)
|
||||
{
|
||||
var curContent = Clipboard.GetContent();
|
||||
Clipboard.Clear();
|
||||
var dp = new DataPackage();
|
||||
dp.SetText(unicode);
|
||||
Clipboard.SetContent(dp);
|
||||
|
||||
var keyList = new List<int>();
|
||||
keyList.Add((int)VirtualKey.Control);
|
||||
keyList.Add((int)VirtualKey.V);
|
||||
keyList.Add((int)VirtualKey.V);
|
||||
keyList.Add((int)VirtualKey.Control);
|
||||
|
||||
return HandleVirtualKeyList(keyList);
|
||||
}
|
||||
|
||||
private KeyboardPage FindContainer(KeyboardPage kbdPage, string containerName)
|
||||
{
|
||||
if (kbdPage.Page.Name == containerName)
|
||||
{
|
||||
return kbdPage;
|
||||
}
|
||||
|
||||
KeyboardPage containerPage = null;
|
||||
for (int i = 0; i < kbdPage.Children.Count; i++)
|
||||
{
|
||||
containerPage = FindContainer(kbdPage.Children[i], containerName);
|
||||
if (containerPage != null)
|
||||
{
|
||||
return containerPage;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void HandlePageChange(string containerName, ButtonBase sender)
|
||||
{
|
||||
var container = FindContainer(_rootPage, containerName);
|
||||
|
||||
var tempPage = GazeKeyboard.GetTemporaryPage(sender);
|
||||
var newPage = GazeKeyboard.GetNewPage(sender);
|
||||
string pageName;
|
||||
|
||||
pageName = (tempPage != null) ? tempPage : newPage;
|
||||
|
||||
// find the new page among its siblings
|
||||
var children = container.Children;
|
||||
for (int i = 0; i < children.Count; i++)
|
||||
{
|
||||
if (children[i].Page.Name == pageName)
|
||||
{
|
||||
// hide the current page
|
||||
container.CurrentChild.Page.Visibility = Visibility.Collapsed;
|
||||
container.Children[i].Page.Visibility = Visibility.Visible;
|
||||
if (tempPage != null)
|
||||
{
|
||||
container.PrevChild = container.CurrentChild;
|
||||
}
|
||||
|
||||
container.CurrentChild = container.Children[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RevertTempPage(ButtonBase button)
|
||||
{
|
||||
// This logic is based on the assumption that the button is placed in a grid or other container
|
||||
// which is the parent page. This is the temp page that has to be reverted back. So we navigate
|
||||
// to the grandparent of that page to identify the siblings of the parent page
|
||||
var page = button.Parent as FrameworkElement;
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var container = page.Parent as FrameworkElement;
|
||||
if (container == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var containerPage = FindContainer(_rootPage, container.Name);
|
||||
if ((containerPage == null) || (containerPage.PrevChild == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
containerPage.CurrentChild.Page.Visibility = Visibility.Collapsed;
|
||||
containerPage.PrevChild.Page.Visibility = Visibility.Visible;
|
||||
containerPage.CurrentChild = containerPage.PrevChild;
|
||||
containerPage.PrevChild = null;
|
||||
}
|
||||
|
||||
private async void OnKeyboardButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as ButtonBase;
|
||||
Target.Focus(FocusState.Programmatic);
|
||||
await Task.Delay(1);
|
||||
|
||||
string unicode;
|
||||
string container;
|
||||
int vk;
|
||||
List<int> vkList;
|
||||
bool injected = false;
|
||||
|
||||
if ((container = GazeKeyboard.GetPageContainer(button)) != null)
|
||||
{
|
||||
HandlePageChange(container, button);
|
||||
}
|
||||
else if ((vk = GazeKeyboard.GetVK(button)) != 0)
|
||||
{
|
||||
injected = HandleVirtualKey(vk);
|
||||
}
|
||||
else if (((vkList = GazeKeyboard.GetVKList(button)) != null) && (vkList.Count > 0))
|
||||
{
|
||||
injected = HandleVirtualKeyList(vkList);
|
||||
}
|
||||
else if ((unicode = GazeKeyboard.GetUnicode(button)) != null)
|
||||
{
|
||||
injected = HandleUnicodeChar(unicode);
|
||||
}
|
||||
else
|
||||
{
|
||||
var key = new InjectedInputKeyboardInfo();
|
||||
key.ScanCode = button.Content.ToString()[0];
|
||||
key.KeyOptions = InjectedInputKeyOptions.Unicode;
|
||||
_injector.InjectKeyboardInput(new[] { key });
|
||||
UpdatePredictions();
|
||||
injected = true;
|
||||
}
|
||||
|
||||
if (injected)
|
||||
{
|
||||
RevertTempPage(button);
|
||||
}
|
||||
}
|
||||
|
||||
private void InjectString(string str, bool addSpace)
|
||||
{
|
||||
if (addSpace)
|
||||
{
|
||||
str += " ";
|
||||
}
|
||||
|
||||
var keys = new List<InjectedInputKeyboardInfo>();
|
||||
foreach (var ch in str)
|
||||
{
|
||||
var key = new InjectedInputKeyboardInfo()
|
||||
{
|
||||
ScanCode = ch,
|
||||
KeyOptions = InjectedInputKeyOptions.Unicode
|
||||
};
|
||||
keys.Add(key);
|
||||
|
||||
key = new InjectedInputKeyboardInfo()
|
||||
{
|
||||
ScanCode = ch,
|
||||
KeyOptions = InjectedInputKeyOptions.Unicode | InjectedInputKeyOptions.KeyUp
|
||||
};
|
||||
|
||||
keys.Add(key);
|
||||
}
|
||||
|
||||
// Injecting too many keys at once can result in ArgumentException.
|
||||
// So inject a max of 8 keys at a time. 8 seems to work for now.
|
||||
for (int i = 0; i < keys.Count; )
|
||||
{
|
||||
var count = Math.Min(8, keys.Count - i);
|
||||
_injector.InjectKeyboardInput(keys.GetRange(i, count));
|
||||
i += count;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPredictionSelected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WordSegment replaceSegment = null;
|
||||
if (Target.SelectionStart < Target.Text.Length)
|
||||
{
|
||||
replaceSegment = _wordsSegmenter.GetTokenAt(Target.Text, (uint)Target.SelectionStart);
|
||||
}
|
||||
else if (Target.Text.Length > 0 && Target.Text[Target.Text.Length - 1] != ' ')
|
||||
{
|
||||
var tokens = _wordsSegmenter.GetTokens(Target.Text);
|
||||
if (tokens == null || tokens.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
replaceSegment = tokens[tokens.Count - 1];
|
||||
}
|
||||
|
||||
if (replaceSegment != null)
|
||||
{
|
||||
Target.Select((int)replaceSegment.SourceTextSegment.StartPosition, (int)replaceSegment.SourceTextSegment.Length);
|
||||
}
|
||||
|
||||
string prediction = (sender as Button).Content.ToString();
|
||||
var dataPackage = new DataPackage();
|
||||
dataPackage.SetText(prediction);
|
||||
Clipboard.SetContent(dataPackage);
|
||||
Target.PasteFromClipboard();
|
||||
UpdatePredictions();
|
||||
}
|
||||
|
||||
private List<string> GetPrevWords()
|
||||
{
|
||||
var segments = _wordsSegmenter.GetTokens(Target.Text);
|
||||
if ((segments == null) || (segments.Count == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
var words = new List<string>(segments.Count);
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
words.Add(segment.Text);
|
||||
i++;
|
||||
}
|
||||
|
||||
words.Reverse();
|
||||
return words;
|
||||
}
|
||||
|
||||
private async void UpdateNextWordPredictions()
|
||||
{
|
||||
var prevWords = GetPrevWords();
|
||||
var predictions = await _textPredictionGenerator.GetNextWordCandidatesAsync((uint)PredictionTargets.Length, prevWords);
|
||||
DisplayPredictions(predictions);
|
||||
}
|
||||
|
||||
private async void UpdatePredictions()
|
||||
{
|
||||
// IMPORTANT: Wait for the text box to be updated with the injected keys
|
||||
await Task.Delay(1);
|
||||
|
||||
if ((PredictionTargets == null) || (PredictionTargets.Length <= 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var prevWords = GetPrevWords();
|
||||
|
||||
if ((prevWords == null) || (prevWords.Count == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IReadOnlyList<string> predictions;
|
||||
var prevWordsExceptLast = prevWords.GetRange(1, prevWords.Count - 1);
|
||||
|
||||
// It looks like we need to send in a larger number than necessary to get good quality predictions.
|
||||
uint maxCandidates = (uint)PredictionTargets.Length * 2;
|
||||
predictions = await _textPredictionGenerator.GetCandidatesAsync(
|
||||
prevWords[0],
|
||||
maxCandidates,
|
||||
TextPredictionOptions.Corrections | TextPredictionOptions.Predictions,
|
||||
prevWordsExceptLast);
|
||||
|
||||
DisplayPredictions(predictions);
|
||||
}
|
||||
|
||||
private void DisplayPredictions(IReadOnlyList<string> predictions)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; (i < predictions.Count) && (i < PredictionTargets.Length); i++)
|
||||
{
|
||||
PredictionTargets[i].Content = predictions[i];
|
||||
}
|
||||
|
||||
for (; i < PredictionTargets.Length; i++)
|
||||
{
|
||||
PredictionTargets[i].Content = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<UserControl
|
||||
x:Class="CommunityToolkit.Labs.Uwp.GazeControls.GazeScrollBar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="600"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
<Setter Property="Width" Value="120" />
|
||||
<Setter Property="Height" Value="120" />
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1000" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid x:Name="VerticalScrollbar" Visibility="Collapsed" HorizontalAlignment="Right" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="120"/>
|
||||
<RowDefinition Height="120"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" BorderBrush="Black" BorderThickness="1,0,0,1">
|
||||
<Button Content="" Click="OnLineUpClicked"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="1,0,0,1">
|
||||
<Button Content="" Click="OnPageUpClicked"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="2" BorderBrush="Black" BorderThickness="1,0,0,1">
|
||||
<TextBlock Text="{x:Bind Mode=OneWay, Path=VerticalPosition}" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalTextAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="3" BorderBrush="Black" BorderThickness="1,0,0,1">
|
||||
<Button Content="" Click="OnPageDownClicked"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="4" BorderBrush="Black" BorderThickness="1,0,0,1">
|
||||
<Button Content="" Click="OnLineDownClicked"/>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
<Grid x:Name="HorizontalScrollbar" Visibility="Collapsed" VerticalAlignment="Bottom" HorizontalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0" BorderBrush="Black" BorderThickness="0,1,1,0">
|
||||
<Button Content="" Click="OnLineLeftClicked" />
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="1" BorderBrush="Black" BorderThickness="0,1,1,0">
|
||||
<Button Content="" Click="OnPageLeftClicked"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="2" BorderBrush="Black" BorderThickness="0,1,1,0" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{x:Bind Mode=OneWay, Path=HorizontalPosition}" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalTextAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="3" BorderBrush="Black" BorderThickness="0,1,1,0">
|
||||
<Button Content="" Click="OnPageRightClicked"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="4" BorderBrush="Black" BorderThickness="0,1,1,0">
|
||||
<Button Content="" Click="OnLineRightClicked"/>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,170 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Gaze optimized scrollbar
|
||||
/// </summary>
|
||||
public sealed partial class GazeScrollBar : UserControl
|
||||
{
|
||||
private ScrollViewer _scrollViewer;
|
||||
|
||||
/// <summary>
|
||||
/// Idetifies the Orientation dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty OrientationProperty =
|
||||
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(GazeScrollBar), null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Orientation of the gaze optimized scrollbar
|
||||
/// </summary>
|
||||
public Orientation Orientation
|
||||
{
|
||||
get { return (Orientation)GetValue(OrientationProperty); }
|
||||
set { SetValue(OrientationProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the HorizontalPosition dependency property
|
||||
/// </summary>
|
||||
private static readonly DependencyProperty HorizontalPositionProperty =
|
||||
DependencyProperty.Register("HorizontalPosition", typeof(string), typeof(GazeScrollBar), null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the percentage of the scrollable content that is to the left of the viewport
|
||||
/// </summary>
|
||||
private string HorizontalPosition
|
||||
{
|
||||
get { return (string)GetValue(HorizontalPositionProperty); }
|
||||
set { SetValue(HorizontalPositionProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the VerticalPosition dependency property
|
||||
/// </summary>
|
||||
private static readonly DependencyProperty VerticalPositionProperty =
|
||||
DependencyProperty.Register("VerticalPosition", typeof(string), typeof(GazeScrollBar), null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the percentage of the scrollable content that is to the left of the viewport
|
||||
/// </summary>
|
||||
private string VerticalPosition
|
||||
{
|
||||
get { return (string)GetValue(VerticalPositionProperty); }
|
||||
set { SetValue(VerticalPositionProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the line height for scrolling with the gaze optimized scrollbar
|
||||
/// </summary>
|
||||
public double LineHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the line width for scrolling with the gaze optimized scrollbar
|
||||
/// </summary>
|
||||
public double LineWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GazeScrollBar"/> class.
|
||||
/// </summary>
|
||||
public GazeScrollBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches this scrollbar to the given ScrollViewer and enables controlling the scroll viewer
|
||||
/// by clicking the buttons on this scrollbar
|
||||
/// </summary>
|
||||
/// <param name="scrollViewer">The ScrollViewer to attach to</param>
|
||||
public void AttachTo(ScrollViewer scrollViewer)
|
||||
{
|
||||
_scrollViewer = scrollViewer;
|
||||
_scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
|
||||
_scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
|
||||
_scrollViewer.ViewChanged += this.OnScrollViewerViewChanged;
|
||||
_scrollViewer.Loaded += OnScrollViewerLoaded;
|
||||
}
|
||||
|
||||
private void OnScrollViewerLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
HorizontalScrollbar.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
VerticalScrollbar.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
HorizontalPosition = "0%";
|
||||
VerticalPosition = "0%";
|
||||
}
|
||||
|
||||
private void OnScrollViewerViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
|
||||
{
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
HorizontalPosition = $"{(int)(_scrollViewer.HorizontalOffset / _scrollViewer.ExtentWidth * 100)}%";
|
||||
}
|
||||
else
|
||||
{
|
||||
VerticalPosition = $"{(int)(_scrollViewer.VerticalOffset / _scrollViewer.ExtentHeight * 100)}%";
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLineUpClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = LineHeight > 0 ? LineHeight : 1;
|
||||
_scrollViewer.ChangeView(null, _scrollViewer.VerticalOffset - delta, null);
|
||||
}
|
||||
|
||||
private void OnPageUpClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = _scrollViewer.ViewportHeight;
|
||||
_scrollViewer.ChangeView(null, _scrollViewer.VerticalOffset - delta, null);
|
||||
}
|
||||
|
||||
private void OnPageDownClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = _scrollViewer.ViewportHeight;
|
||||
_scrollViewer.ChangeView(null, _scrollViewer.VerticalOffset + delta, null);
|
||||
}
|
||||
|
||||
private void OnLineDownClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = LineHeight > 0 ? LineHeight : 1;
|
||||
_scrollViewer.ChangeView(null, _scrollViewer.VerticalOffset + delta, null);
|
||||
}
|
||||
|
||||
private void OnLineLeftClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = LineWidth > 0 ? LineWidth : 1;
|
||||
_scrollViewer.ChangeView(_scrollViewer.HorizontalOffset - delta, null, null);
|
||||
}
|
||||
|
||||
private void OnPageLeftClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = _scrollViewer.ViewportWidth;
|
||||
_scrollViewer.ChangeView(_scrollViewer.HorizontalOffset - delta, null, null);
|
||||
}
|
||||
|
||||
private void OnPageRightClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = _scrollViewer.ViewportWidth;
|
||||
_scrollViewer.ChangeView(_scrollViewer.HorizontalOffset + delta, null, null);
|
||||
}
|
||||
|
||||
private void OnLineRightClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var delta = LineWidth > 0 ? LineWidth : 1;
|
||||
_scrollViewer.ChangeView(_scrollViewer.HorizontalOffset + delta, null, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration for the type of key in the layout file.
|
||||
/// </summary>
|
||||
public enum KeyTypeValue
|
||||
{
|
||||
/// <summary>
|
||||
/// The key is a normal button that injects keys into its target
|
||||
/// </summary>
|
||||
Normal,
|
||||
|
||||
/// <summary>
|
||||
/// The key is a toggle button that is used to change the state of keyboard
|
||||
/// </summary>
|
||||
Toggle,
|
||||
|
||||
/// <summary>
|
||||
/// The key loads a different layout page
|
||||
/// </summary>
|
||||
Layout
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gaze optimized soft keyboard with support for custom layouts and predictions
|
||||
/// </summary>
|
||||
public sealed partial class GazeKeyboard : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// The KeyType property allows users to specify the type of a key in the layout file. <see cref="KeyTypeValue"/>
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty KeyTypeProperty =
|
||||
DependencyProperty.RegisterAttached("KeyType", typeof(KeyTypeValue), typeof(GazeKeyboard), new PropertyMetadata(KeyTypeValue.Normal));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key type
|
||||
/// </summary>
|
||||
/// <param name="obj"> DependencyObject</param>
|
||||
/// <returns>KeyTypeValue</returns>
|
||||
public static KeyTypeValue GetKeyType(DependencyObject obj)
|
||||
{
|
||||
return (KeyTypeValue)obj.GetValue(KeyTypeProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the key type
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">KeyTypeValue to set</param>
|
||||
public static void SetKeyType(DependencyObject obj, KeyTypeValue value)
|
||||
{
|
||||
obj.SetValue(KeyTypeProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The VK property specifies the virtual key to inject into the target when a key is pressed
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty VKProperty =
|
||||
DependencyProperty.RegisterAttached("VK", typeof(int), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the virtual key that will be injected
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>The virtual key as an integer</returns>
|
||||
public static int GetVK(DependencyObject obj)
|
||||
{
|
||||
return (int)obj.GetValue(VKProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the virtual key to be injected
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">The virtual key as an integer</param>
|
||||
public static void SetVK(DependencyObject obj, int value)
|
||||
{
|
||||
obj.SetValue(VKProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Unicode property indicates the unicode string that will be injected when a key is pressed
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty UnicodeProperty =
|
||||
DependencyProperty.RegisterAttached("Unicode", typeof(string), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unicode string that will be injected
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>The unicode value as a string</returns>
|
||||
public static string GetUnicode(DependencyObject obj)
|
||||
{
|
||||
return obj.GetValue(UnicodeProperty) as string;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the unicode string to be injected
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">The unicode value as a string</param>
|
||||
public static void SetUnicode(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(UnicodeProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The VKList property specifies a list of virtual keys to be injected when a key is pressed
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty VKListProperty =
|
||||
DependencyProperty.RegisterAttached("VKList", typeof(List<int>), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of virtual keys
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>A list of integers that represent virtual key codes</returns>
|
||||
public static List<int> GetVKList(DependencyObject obj)
|
||||
{
|
||||
var value = obj.GetValue(VKListProperty);
|
||||
var list = value as List<int>;
|
||||
if (list == null)
|
||||
{
|
||||
list = new List<int>();
|
||||
SetVKList(obj, list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the list of virtual key codes to be injected
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">List of virtual key codes</param>
|
||||
public static void SetVKList(DependencyObject obj, List<int> value)
|
||||
{
|
||||
obj.SetValue(VKListProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The PageList property specifies the list of pages in a keyboard layout
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty PageListProperty =
|
||||
DependencyProperty.RegisterAttached("PageList", typeof(List<string>), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of pages in a layout
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>List of pages</returns>
|
||||
public static List<string> GetPageList(DependencyObject obj)
|
||||
{
|
||||
var value = obj.GetValue(PageListProperty);
|
||||
var list = value as List<string>;
|
||||
if (list == null)
|
||||
{
|
||||
list = new List<string>();
|
||||
SetPageList(obj, list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the list of pages for a layout
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">List of pages</param>
|
||||
public static void SetPageList(DependencyObject obj, List<string> value)
|
||||
{
|
||||
obj.SetValue(PageListProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The PageContainer property specifies the container page for a layout
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty PageContainerProperty =
|
||||
DependencyProperty.RegisterAttached("PageContainer", typeof(string), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the container for a page in a layout
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>The container for a page</returns>
|
||||
public static string GetPageContainer(DependencyObject obj)
|
||||
{
|
||||
return obj.GetValue(PageContainerProperty) as string;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the container for a page in a layout
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">The container for a page</param>
|
||||
public static void SetPageContainer(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(PageContainerProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The TemporaryPage property specifies a temporary layout to be loaded. This layout is changed back
|
||||
/// as soon as a single key is presssed
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TemporaryPageProperty =
|
||||
DependencyProperty.RegisterAttached("TemporaryPage", typeof(string), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the temporary page to load
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>The temporary page to load</returns>
|
||||
public static string GetTemporaryPage(DependencyObject obj)
|
||||
{
|
||||
return obj.GetValue(TemporaryPageProperty) as string;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the temporary page to load
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">The temporary page to load</param>
|
||||
public static void SetTemporaryPage(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(TemporaryPageProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The NewPage property specifies a new layout to load when a key is a pressed
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty NewPageProperty =
|
||||
DependencyProperty.RegisterAttached("NewPage", typeof(string), typeof(GazeKeyboard), new PropertyMetadata(0));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new page to load
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <returns>The new page</returns>
|
||||
public static string GetNewPage(DependencyObject obj)
|
||||
{
|
||||
return obj.GetValue(NewPageProperty) as string;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the new page to load
|
||||
/// </summary>
|
||||
/// <param name="obj">DependencyObject</param>
|
||||
/// <param name="value">The new page</param>
|
||||
public static void SetNewPage(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(NewPageProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<Grid
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:k="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="Alpha" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="30"/>
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="g:GazeInput.RepeatDelayDuration" Value="0:0:0.8"/>
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Symbol" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="50"/>
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
<ColumnDefinition MinWidth="150" Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="0" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="1" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="2" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="3" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="4" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="5" />
|
||||
<Button Grid.Row="0" Grid.Column="6" Style="{StaticResource Alpha}" Content="6" />
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="7" />
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="8" />
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="9" />
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="!" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="@" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="#" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="$" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="%" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="^" />
|
||||
<Button Grid.Row="1" Grid.Column="6" Style="{StaticResource Alpha}" Content="~" />
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="-" />
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="_" />
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Alpha}" Content="." />
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="q" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="w" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="e" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="r" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="t" />
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="y" />
|
||||
<Button Grid.Row="2" Grid.Column="6" Style="{StaticResource Alpha}" Content="u" />
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="i" />
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="o" />
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Alpha}" Content="p" />
|
||||
|
||||
<Button Grid.Row="3" Grid.Column="0" Style="{StaticResource Alpha}" Content="a" />
|
||||
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource Alpha}" Content="s" />
|
||||
<Button Grid.Row="3" Grid.Column="2" Style="{StaticResource Alpha}" Content="d" />
|
||||
<Button Grid.Row="3" Grid.Column="3" Style="{StaticResource Alpha}" Content="f" />
|
||||
<Button Grid.Row="3" Grid.Column="4" Style="{StaticResource Alpha}" Content="g" />
|
||||
<Button Grid.Row="3" Grid.Column="5" Style="{StaticResource Alpha}" Content="h" />
|
||||
<Button Grid.Row="3" Grid.Column="6" Style="{StaticResource Alpha}" Content="j" />
|
||||
<Button Grid.Row="3" Grid.Column="7" Style="{StaticResource Alpha}" Content="k" />
|
||||
<Button Grid.Row="3" Grid.Column="8" Style="{StaticResource Alpha}" Content="l" />
|
||||
<Button Grid.Row="3" Grid.Column="9" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
|
||||
<Button Grid.Row="4" Grid.Column="0" Style="{StaticResource Alpha}" Content="z" />
|
||||
<Button Grid.Row="4" Grid.Column="1" Style="{StaticResource Alpha}" Content="x" />
|
||||
<Button Grid.Row="4" Grid.Column="2" Style="{StaticResource Alpha}" Content="c" />
|
||||
<Button Grid.Row="4" Grid.Column="3" Style="{StaticResource Alpha}" Content="v" />
|
||||
<Button Grid.Row="4" Grid.Column="4" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="2" k:GazeKeyboard.VK="32"/>
|
||||
<Button Grid.Row="4" Grid.Column="6" Style="{StaticResource Alpha}" Content="b" />
|
||||
<Button Grid.Row="4" Grid.Column="7" Style="{StaticResource Alpha}" Content="n" />
|
||||
<Button Grid.Row="4" Grid.Column="8" Style="{StaticResource Alpha}" Content="m" />
|
||||
<Button Grid.Row="4" Grid.Column="9" Style="{StaticResource Symbol}" Content="">
|
||||
<k:GazeKeyboard.VKList>
|
||||
<x:Int32>17</x:Int32> <!-- VK_CONTROL -->
|
||||
<x:Int32>65</x:Int32> <!-- VK_A -->
|
||||
<x:Int32>8</x:Int32> <!-- VK_BACK -->
|
||||
<x:Int32>8</x:Int32> <!-- VK_BACK -->
|
||||
<x:Int32>65</x:Int32> <!-- VK_A -->
|
||||
<x:Int32>17</x:Int32> <!-- VK_CONTROL -->
|
||||
</k:GazeKeyboard.VKList>
|
||||
</Button>
|
||||
</Grid>
|
|
@ -0,0 +1,400 @@
|
|||
<Grid
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:k="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
x:Name="FullKeyboard">
|
||||
|
||||
<k:GazeKeyboard.PageList>
|
||||
<x:String>MainPage</x:String>
|
||||
<x:String>UppercasePage</x:String>
|
||||
<x:String>NumbersPage</x:String>
|
||||
<x:String>EmojiPage</x:String>
|
||||
</k:GazeKeyboard.PageList>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="Alpha" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="30"/>
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="g:GazeInput.RepeatDelayDuration" Value="0:0:0.8"/>
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Symbol" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="50"/>
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid x:Name="MainPage">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="q" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="w" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="e" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="r" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="t" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="y" />
|
||||
<Button Grid.Row="0" Grid.Column="6" Style="{StaticResource Alpha}" Content="u" />
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="i" />
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="o" />
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="p" />
|
||||
<Button Grid.Row="0" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="a" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="s" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="d" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="f" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="g" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="h" />
|
||||
<Button Grid.Row="1" Grid.Column="6" Style="{StaticResource Alpha}" Content="j" />
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="k" />
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="l" />
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Alpha}" Content="'" />
|
||||
<Button Grid.Row="1" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="13"/>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.TemporaryPage="UppercasePage" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="z" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="x" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="c" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="v" />
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="b" />
|
||||
<Button Grid.Row="2" Grid.Column="6" Style="{StaticResource Alpha}" Content="n" />
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="m" />
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="," />
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Alpha}" Content="." />
|
||||
<Button Grid.Row="2" Grid.Column="10" Style="{StaticResource Symbol}" Content="">
|
||||
<k:GazeKeyboard.VKList>
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
</k:GazeKeyboard.VKList>
|
||||
</Button>
|
||||
<Button Grid.Row="3" Grid.Column="0" Style="{StaticResource Alpha}" Content="123" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="NumbersPage"/>
|
||||
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource Alpha}" Content="Ctrl" />
|
||||
<Button Grid.Row="3" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="EmojiPage"/>
|
||||
<Button Grid.Row="3" Grid.Column="3" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="4" k:GazeKeyboard.VK="32"/>
|
||||
<Button Grid.Row="3" Grid.Column="7" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="37" />
|
||||
<Button Grid.Row="3" Grid.Column="8" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="39" />
|
||||
<Button Grid.Row="3" Grid.Column="9" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="38" />
|
||||
<Button Grid.Row="3" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="40" />
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="UppercasePage" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="Q" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="W" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="E" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="R" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="T" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="Y" />
|
||||
<Button Grid.Row="0" Grid.Column="6" Style="{StaticResource Alpha}" Content="U" />
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="I" />
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="O" />
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="P" />
|
||||
<Button Grid.Row="0" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="A" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="S" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="D" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="F" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="G" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="H" />
|
||||
<Button Grid.Row="1" Grid.Column="6" Style="{StaticResource Alpha}" Content="J" />
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="K" />
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="L" />
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Alpha}" Content="'" />
|
||||
<Button Grid.Row="1" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="13"/>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="MainPage" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="Z" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="X" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="C" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="V" />
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="B" />
|
||||
<Button Grid.Row="2" Grid.Column="6" Style="{StaticResource Alpha}" Content="N" />
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="M" />
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="," />
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Alpha}" Content="." />
|
||||
<Button Grid.Row="2" Grid.Column="10" Style="{StaticResource Symbol}" Content="">
|
||||
<k:GazeKeyboard.VKList>
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
</k:GazeKeyboard.VKList>
|
||||
</Button>
|
||||
<Button Grid.Row="3" Grid.Column="0" Style="{StaticResource Alpha}" Content="123" />
|
||||
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource Alpha}" Content="Ctrl" />
|
||||
<Button Grid.Row="3" Grid.Column="2" Style="{StaticResource Symbol}" Content="" />
|
||||
<Button Grid.Row="3" Grid.Column="3" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="4" k:GazeKeyboard.VK="32"/>
|
||||
<Button Grid.Row="3" Grid.Column="7" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="37" />
|
||||
<Button Grid.Row="3" Grid.Column="8" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="39" />
|
||||
<Button Grid.Row="3" Grid.Column="9" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="38" />
|
||||
<Button Grid.Row="3" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="40" />
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="NumbersPage" Visibility="Collapsed">
|
||||
<k:GazeKeyboard.PageList>
|
||||
<x:String>SymbolsPage</x:String>
|
||||
</k:GazeKeyboard.PageList>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="Tab" k:GazeKeyboard.VK="9"/>
|
||||
<Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="6" x:Name="SymbolsPage">
|
||||
<k:GazeKeyboard.PageList>
|
||||
<x:String>SymbolsPage1</x:String>
|
||||
<x:String>SymbolsPage2</x:String>
|
||||
</k:GazeKeyboard.PageList>
|
||||
<Grid x:Name="SymbolsPage1" Visibility="Visible">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="!" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="@" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="#" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="$" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="%" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="&" />
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="(" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content=")" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="-" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="_" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="=" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="+" />
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="\" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content=";" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content=":" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content=""" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="*" />
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="/" />
|
||||
</Grid>
|
||||
<Grid x:Name="SymbolsPage2" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="•" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="©" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="€" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="£" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="µ" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="½" />
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="<" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content=">" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="[" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="]" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="{}{" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="}" />
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="|" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="¦" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="¶" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="°" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="~" />
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="^" />
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="SymbolsPage" k:GazeKeyboard.NewPage="SymbolsPage1"/>
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="SymbolsPage" k:GazeKeyboard.NewPage="SymbolsPage2"/>
|
||||
<Button Grid.Row="3" Grid.Column="0" Style="{StaticResource Alpha}" Content="abc" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource Alpha}" Content="Ctrl" />
|
||||
<Button Grid.Row="3" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="EmojiPage"/>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="1" />
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="2" />
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="3" />
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="4" />
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="5" />
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Alpha}" Content="6" />
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="7" />
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="8" />
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Alpha}" Content="9" />
|
||||
<Button Grid.Row="3" Grid.Column="7" Style="{StaticResource Alpha}" Content="0" Grid.ColumnSpan="2"/>
|
||||
<Button Grid.Row="3" Grid.Column="9" Style="{StaticResource Alpha}" Content="." />
|
||||
|
||||
<Button Grid.Row="3" Grid.Column="3" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="37" />
|
||||
<Button Grid.Row="3" Grid.Column="4" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="39" />
|
||||
<Button Grid.Row="3" Grid.Column="5" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="2" k:GazeKeyboard.VK="32"/>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
<Button Grid.Row="1" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="13" Grid.RowSpan="3"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="EmojiPage" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="😀" k:GazeKeyboard.Unicode="😀"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="😁" k:GazeKeyboard.Unicode="😁"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="😂" k:GazeKeyboard.Unicode="😂"/>
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="😃" k:GazeKeyboard.Unicode="😃"/>
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="😄" k:GazeKeyboard.Unicode="😄"/>
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="😅" k:GazeKeyboard.Unicode="😅"/>
|
||||
<Button Grid.Row="0" Grid.Column="6" Style="{StaticResource Alpha}" Content="😆" k:GazeKeyboard.Unicode="😆"/>
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="😇" k:GazeKeyboard.Unicode="😇"/>
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="😈" k:GazeKeyboard.Unicode="😈"/>
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="😉" k:GazeKeyboard.Unicode="😉"/>
|
||||
<Button Grid.Row="0" Grid.Column="10" Style="{StaticResource Alpha}" Content="😊" k:GazeKeyboard.Unicode="😊"/>
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="😋" k:GazeKeyboard.Unicode="😋"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="😌" k:GazeKeyboard.Unicode="😌"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="😍" k:GazeKeyboard.Unicode="😍"/>
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="😎" k:GazeKeyboard.Unicode="😎"/>
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="😏" k:GazeKeyboard.Unicode="😏"/>
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="😐" k:GazeKeyboard.Unicode="😐"/>
|
||||
<Button Grid.Row="1" Grid.Column="6" Style="{StaticResource Alpha}" Content="😑" k:GazeKeyboard.Unicode="😑"/>
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="😒" k:GazeKeyboard.Unicode="😒"/>
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="😓" k:GazeKeyboard.Unicode="😓"/>
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Alpha}" Content="😔" k:GazeKeyboard.Unicode="😔"/>
|
||||
<Button Grid.Row="1" Grid.Column="10" Style="{StaticResource Alpha}" Content="😕" k:GazeKeyboard.Unicode="😕"/>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="😖" k:GazeKeyboard.Unicode="😖"/>
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="😗" k:GazeKeyboard.Unicode="😗"/>
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="😘" k:GazeKeyboard.Unicode="😘"/>
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="😙" k:GazeKeyboard.Unicode="😙"/>
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Alpha}" Content="😚" k:GazeKeyboard.Unicode="😚"/>
|
||||
<Button Grid.Row="2" Grid.Column="5" Style="{StaticResource Alpha}" Content="😛" k:GazeKeyboard.Unicode="😛"/>
|
||||
<Button Grid.Row="2" Grid.Column="6" Style="{StaticResource Alpha}" Content="😜" k:GazeKeyboard.Unicode="😜"/>
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="😝" k:GazeKeyboard.Unicode="😝"/>
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="😞" k:GazeKeyboard.Unicode="😞"/>
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Alpha}" Content="😟" k:GazeKeyboard.Unicode="😟"/>
|
||||
<Button Grid.Row="2" Grid.Column="10" Style="{StaticResource Alpha}" Content="😠" k:GazeKeyboard.Unicode="😠"/>
|
||||
|
||||
<Button Grid.Row="3" Grid.Column="0" Style="{StaticResource Alpha}" Content="abc" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
<Button Grid.Row="3" Grid.Column="1" Style="{StaticResource Alpha}" Content="Ctrl" />
|
||||
<Button Grid.Row="3" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="FullKeyboard" k:GazeKeyboard.NewPage="EmojiPage"/>
|
||||
<Button Grid.Row="3" Grid.Column="3" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="4" k:GazeKeyboard.VK="32"/>
|
||||
<Button Grid.Row="3" Grid.Column="7" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="37" />
|
||||
<Button Grid.Row="3" Grid.Column="8" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="39" />
|
||||
<Button Grid.Row="3" Grid.Column="9" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="38" />
|
||||
<Button Grid.Row="3" Grid.Column="10" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="40" />
|
||||
</Grid>
|
||||
</Grid>
|
|
@ -0,0 +1,93 @@
|
|||
<Grid
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:k="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="Alpha" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="30"/>
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="g:GazeInput.RepeatDelayDuration" Value="0:0:0.8"/>
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Symbol" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="50"/>
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="q" />
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="w" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="e" />
|
||||
<Button Grid.Row="0" Grid.Column="3" Style="{StaticResource Alpha}" Content="r" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Style="{StaticResource Alpha}" Content="t" />
|
||||
<Button Grid.Row="0" Grid.Column="5" Style="{StaticResource Alpha}" Content="y" />
|
||||
<Button Grid.Row="0" Grid.Column="6" Style="{StaticResource Alpha}" Content="u" />
|
||||
<Button Grid.Row="0" Grid.Column="7" Style="{StaticResource Alpha}" Content="i" />
|
||||
<Button Grid.Row="0" Grid.Column="8" Style="{StaticResource Alpha}" Content="o" />
|
||||
<Button Grid.Row="0" Grid.Column="9" Style="{StaticResource Alpha}" Content="p" />
|
||||
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="a" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="s" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Alpha}" Content="d" />
|
||||
<Button Grid.Row="1" Grid.Column="3" Style="{StaticResource Alpha}" Content="f" />
|
||||
<Button Grid.Row="1" Grid.Column="4" Style="{StaticResource Alpha}" Content="g" />
|
||||
<Button Grid.Row="1" Grid.Column="5" Style="{StaticResource Alpha}" Content="h" />
|
||||
<Button Grid.Row="1" Grid.Column="6" Style="{StaticResource Alpha}" Content="j" />
|
||||
<Button Grid.Row="1" Grid.Column="7" Style="{StaticResource Alpha}" Content="k" />
|
||||
<Button Grid.Row="1" Grid.Column="8" Style="{StaticResource Alpha}" Content="l" />
|
||||
<Button Grid.Row="1" Grid.Column="9" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="z" />
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Alpha}" Content="x" />
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="c" />
|
||||
<Button Grid.Row="2" Grid.Column="3" Style="{StaticResource Alpha}" Content="v" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{StaticResource Symbol}" Content="" Grid.ColumnSpan="2" k:GazeKeyboard.VK="32"/>
|
||||
<Button Grid.Row="2" Grid.Column="6" Style="{StaticResource Alpha}" Content="b" />
|
||||
<Button Grid.Row="2" Grid.Column="7" Style="{StaticResource Alpha}" Content="n" />
|
||||
<Button Grid.Row="2" Grid.Column="8" Style="{StaticResource Alpha}" Content="m" />
|
||||
<Button Grid.Row="2" Grid.Column="9" Style="{StaticResource Symbol}" Content="">
|
||||
<k:GazeKeyboard.VKList>
|
||||
<x:Int32>17</x:Int32> <!-- VK_CONTROL -->
|
||||
<x:Int32>65</x:Int32> <!-- VK_A -->
|
||||
<x:Int32>8</x:Int32> <!-- VK_BACK -->
|
||||
<x:Int32>8</x:Int32> <!-- VK_BACK -->
|
||||
<x:Int32>65</x:Int32> <!-- VK_A -->
|
||||
<x:Int32>17</x:Int32> <!-- VK_CONTROL -->
|
||||
</k:GazeKeyboard.VKList>
|
||||
</Button>
|
||||
</Grid>
|
|
@ -0,0 +1,187 @@
|
|||
<Grid
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:k="using:CommunityToolkit.Labs.Uwp.GazeControls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
x:Name="TwoStageKeyboard">
|
||||
|
||||
<k:GazeKeyboard.PageList>
|
||||
<x:String>MainPage</x:String>
|
||||
<x:String>PageABCDE</x:String>
|
||||
<x:String>PageFGHIJ</x:String>
|
||||
<x:String>PageKLMNO</x:String>
|
||||
<x:String>PagePQRST</x:String>
|
||||
<x:String>PageUVWXY</x:String>
|
||||
<x:String>PageZPUNC</x:String>
|
||||
</k:GazeKeyboard.PageList>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="Alpha" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="30"/>
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="g:GazeInput.RepeatDelayDuration" Value="0:0:0.8"/>
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Symbol" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="50"/>
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid x:Name="MainPage" Visibility="Visible">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="[a b c d e]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PageABCDE"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="[f g h i j]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PageFGHIJ"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="[k l m n o]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PageKLMNO"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="[p q r s t]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PagePQRST"/>
|
||||
<Button Grid.Row="2" Grid.Column="0" Style="{StaticResource Alpha}" Content="[u v w x y]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PageUVWXY"/>
|
||||
<Button Grid.Row="2" Grid.Column="2" Style="{StaticResource Alpha}" Content="[z , ? 🙂 🙁]" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.TemporaryPage="PageZPUNC"/>
|
||||
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="8"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="">
|
||||
<k:GazeKeyboard.VKList>
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>8</x:Int32>
|
||||
<!-- VK_BACK -->
|
||||
<x:Int32>65</x:Int32>
|
||||
<!-- VK_A -->
|
||||
<x:Int32>17</x:Int32>
|
||||
<!-- VK_CONTROL -->
|
||||
</k:GazeKeyboard.VKList>
|
||||
</Button>
|
||||
<Button Grid.Row="2" Grid.Column="1" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.VK="32"/>
|
||||
|
||||
</Grid>
|
||||
<Grid x:Name="PageABCDE" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="a"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="b"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="c"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="d"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="e"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
<Grid x:Name="PageFGHIJ" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="f"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="g"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="h"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="i"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="j"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
<Grid x:Name="PageKLMNO" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="k"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="l"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="m"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="n"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="o "/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
<Grid x:Name="PagePQRST" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="p"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="q"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="r"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="s"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="t"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
<Grid x:Name="PageUVWXY" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="u"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content="v"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="w"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="x"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="y"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
<Grid x:Name="PageZPUNC" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Row="0" Grid.Column="0" Style="{StaticResource Alpha}" Content="z"/>
|
||||
<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource Alpha}" Content=","/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource Alpha}" Content="?"/>
|
||||
<Button Grid.Row="1" Grid.Column="0" Style="{StaticResource Alpha}" Content="🙂" k:GazeKeyboard.Unicode="🙂"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Style="{StaticResource Alpha}" Content="🙁" k:GazeKeyboard.Unicode="🙁"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource Symbol}" Content="" k:GazeKeyboard.PageContainer="TwoStageKeyboard" k:GazeKeyboard.NewPage="MainPage"/>
|
||||
</Grid>
|
||||
</Grid>
|
|
@ -0,0 +1,36 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
internal class KeyboardPage
|
||||
{
|
||||
public FrameworkElement Page { get; set; }
|
||||
|
||||
public KeyboardPage Parent { get; set; }
|
||||
|
||||
public List<string> ChildrenNames { get; set; }
|
||||
|
||||
public List<KeyboardPage> Children { get; set; }
|
||||
|
||||
public KeyboardPage CurrentChild { get; set; }
|
||||
|
||||
public KeyboardPage PrevChild { get; set; }
|
||||
|
||||
public KeyboardPage(FrameworkElement page, KeyboardPage parent)
|
||||
{
|
||||
Page = page;
|
||||
Parent = parent;
|
||||
ChildrenNames = new List<string>();
|
||||
Children = new List<KeyboardPage>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
internal class PathPart
|
||||
{
|
||||
public int Index { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.Toolkit.Uwp.UI;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom version of GridView to manage the scroll bar associated with the GridView
|
||||
/// </summary>
|
||||
public class ScrollGridView : GridView
|
||||
{
|
||||
private ScrollViewer _scrollViewer;
|
||||
|
||||
/// <summary>
|
||||
/// Overridden version of OnApplyTemplate
|
||||
/// </summary>
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_scrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
|
||||
|
||||
if (GazeScrollBar != null)
|
||||
{
|
||||
GazeScrollBar.AttachTo(_scrollViewer);
|
||||
}
|
||||
|
||||
_scrollViewer.ViewChanged += this.OnScrollViewerViewChanged;
|
||||
}
|
||||
|
||||
private void OnScrollViewerViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
|
||||
{
|
||||
var item = this.FindDescendant<GridViewItem>();
|
||||
GazeScrollBar.LineHeight = item != null ? item.ActualHeight : 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the gaze optimized vertical scrollbar
|
||||
/// </summary>
|
||||
public GazeScrollBar GazeScrollBar { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.FileProperties;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
|
||||
namespace CommunityToolkit.Labs.Uwp.GazeControls
|
||||
{
|
||||
internal class StorageItem : DependencyObject
|
||||
{
|
||||
public IStorageItem Item { get; }
|
||||
|
||||
public StorageItem(IStorageItem item)
|
||||
{
|
||||
Item = item;
|
||||
}
|
||||
|
||||
public bool IsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
return Item.IsOfType(StorageItemTypes.Folder);
|
||||
}
|
||||
}
|
||||
|
||||
public string TextIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsFolder ? "\uF12B" : "\uE7C3";
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return Item.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return Item.Path;
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapImage Thumbnail
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_thumbnail == null)
|
||||
{
|
||||
if (_storageThumbnail == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_thumbnail = new BitmapImage();
|
||||
_thumbnail.SetSource(_storageThumbnail);
|
||||
}
|
||||
|
||||
return _thumbnail;
|
||||
}
|
||||
}
|
||||
|
||||
private BitmapImage _thumbnail;
|
||||
|
||||
private StorageItemThumbnail _storageThumbnail;
|
||||
|
||||
public async Task GetThumbnailAsync()
|
||||
{
|
||||
var props = Item as IStorageItemProperties;
|
||||
_storageThumbnail = await props.GetThumbnailAsync(ThumbnailMode.DocumentsView);
|
||||
}
|
||||
|
||||
internal static readonly DependencyProperty StorageThumbnailProperty =
|
||||
DependencyProperty.Register(
|
||||
"StorageThumbnail",
|
||||
typeof(StorageItemThumbnail),
|
||||
typeof(StorageItem),
|
||||
null);
|
||||
|
||||
internal StorageItemThumbnail StorageThumbnail
|
||||
{
|
||||
get { return (StorageItemThumbnail)GetValue(StorageThumbnailProperty); }
|
||||
set { SetValue(StorageThumbnailProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="EnterFilename" xml:space="preserve">
|
||||
<value>Enter Filename...</value>
|
||||
</data>
|
||||
<data name="FileOpen.Title" xml:space="preserve">
|
||||
<value>Open File</value>
|
||||
</data>
|
||||
<data name="FileSave.Title" xml:space="preserve">
|
||||
<value>Save File</value>
|
||||
</data>
|
||||
<data name="NewFolder" xml:space="preserve">
|
||||
<value>New Folder...</value>
|
||||
</data>
|
||||
<data name="OK" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="Open" xml:space="preserve">
|
||||
<value>Open</value>
|
||||
</data>
|
||||
<data name="OverwriteWarning" xml:space="preserve">
|
||||
<value>"{0}" already exists.</value>
|
||||
</data>
|
||||
<data name="Save" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31424.327
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Labs.Uwp.GazeControls", "CommunityToolkit.Labs.Uwp.GazeControls\CommunityToolkit.Labs.Uwp.GazeControls.csproj", "{352191F5-8704-45A1-ACB3-CA47C6898A99}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{352191F5-8704-45A1-ACB3-CA47C6898A99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{352191F5-8704-45A1-ACB3-CA47C6898A99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{352191F5-8704-45A1-ACB3-CA47C6898A99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{352191F5-8704-45A1-ACB3-CA47C6898A99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7956E0E0-C673-4682-A631-F1AC12B65C17}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,7 @@
|
|||
<Application
|
||||
x:Class="GazeInputTest.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:GazeInputTest"
|
||||
RequestedTheme="Light">
|
||||
</Application>
|
|
@ -0,0 +1,100 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace GazeInputTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public sealed partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="App"/> class.
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
// TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
if (e.PrelaunchActivated == false)
|
||||
{
|
||||
if (rootFrame.Content == null)
|
||||
{
|
||||
// When the navigation stack isn't restored navigate to the first page,
|
||||
// configuring the new page by passing required information as a navigation
|
||||
// parameter
|
||||
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
||||
}
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
}
|
||||
|
||||
GazeInput.Interaction = Interaction.Enabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
|
||||
// TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 7.5 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 1.6 KiB |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 3.1 KiB |
|
@ -0,0 +1,164 @@
|
|||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{A122EA02-4DE7-413D-BFBF-AF7DFC668DD6}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>GazeInputTest</RootNamespace>
|
||||
<AssemblyName>GazeInputTest</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.19041.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<NoWarn>$(NoWarn);2008</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||
<OutputPath>bin\ARM64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.12</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Toolkit.Uwp.Input.GazeControls\Microsoft.Toolkit.Uwp.Input.GazeControls.csproj">
|
||||
<Project>{fa4682b6-26be-49a0-be97-96956724ae55}</Project>
|
||||
<Name>Microsoft.Toolkit.Uwp.Input.GazeControls</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.Toolkit.Uwp.Input.GazeInteraction\Microsoft.Toolkit.Uwp.Input.GazeInteraction.csproj">
|
||||
<Project>{5bf75694-798a-43a0-8150-415de195359c}</Project>
|
||||
<Name>Microsoft.Toolkit.Uwp.Input.GazeInteraction</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- No-op to avoid build error when packing solution from commandline -->
|
||||
<Target Name="Pack" />
|
||||
</Project>
|
|
@ -0,0 +1,108 @@
|
|||
<Page
|
||||
x:Class="GazeInputTest.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:GazeInputTest"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:g="using:Microsoft.Toolkit.Uwp.Input.GazeInteraction"
|
||||
xmlns:k="using:Microsoft.Toolkit.Uwp.Input.GazeControls"
|
||||
g:GazeInput.Interaction="Enabled"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Margin" Value="10" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
<Style TargetType="ToggleButton">
|
||||
<Setter Property="Margin" Value="10" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
<Style x:Key="Alpha" TargetType="ButtonBase">
|
||||
<Setter Property="FontSize" Value="30"/>
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="g:GazeInput.RepeatDelayDuration" Value="0:0:0.8"/>
|
||||
<Setter Property="g:GazeInput.MaxDwellRepeatCount" Value="1" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="10*"/>
|
||||
<ColumnDefinition Width="80*"/>
|
||||
<ColumnDefinition Width="10*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<ToggleButton Grid.Row="0" x:Name="ShowCursor" Checked="ShowCursor_Toggle" Unchecked="ShowCursor_Toggle" Content="Show Cursor"/>
|
||||
<Button Grid.Row="1" x:Name="Dwell" Click="Dwell_Click" Content="Eyes Here">
|
||||
<g:GazeInput.GazeElement>
|
||||
<g:GazeElement StateChanged="OnStateChanged"/>
|
||||
</g:GazeInput.GazeElement>
|
||||
</Button>
|
||||
<Button Grid.Row="2" x:Name="HowButton" Content="0: Idle" Click="OnLegacyInvoked" g:GazeInput.MaxDwellRepeatCount="4" >
|
||||
<g:GazeInput.GazeElement>
|
||||
<g:GazeElement Invoked="OnGazeInvoked"/>
|
||||
</g:GazeInput.GazeElement>
|
||||
</Button>
|
||||
<ToggleButton Grid.Row="3" Content="Click" g:GazeInput.DwellDuration="0:0:2" >
|
||||
<g:GazeInput.GazeElement>
|
||||
<g:GazeElement DwellProgressFeedback="OnInvokeProgress" />
|
||||
</g:GazeInput.GazeElement>
|
||||
</ToggleButton>
|
||||
<Button Grid.Row="4" Content="Open File" Click="OnOpenFile"/>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="15*"/>
|
||||
<RowDefinition Height="10*"/>
|
||||
<RowDefinition Height="75*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80*"/>
|
||||
<ColumnDefinition Width="20*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0" x:Name="TheTextBox" HorizontalAlignment="Stretch" FontSize="18"/>
|
||||
<Button Grid.Column="1" Content="Play" Click="OnPlay"/>
|
||||
</Grid>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
|
||||
<Button x:Name="Prediction0" Height="100" MinWidth="300" Style="{StaticResource Alpha}" />
|
||||
<Button x:Name="Prediction1" Height="100" MinWidth="300" Style="{StaticResource Alpha}" />
|
||||
<Button x:Name="Prediction2" Height="100" MinWidth="300" Style="{StaticResource Alpha}" />
|
||||
</StackPanel>
|
||||
<k:GazeKeyboard Grid.Row="2" x:Name="GazeKeyboard"/>
|
||||
</Grid>
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Vertical">
|
||||
<ProgressBar x:Name="ProgressShow" Maximum="100" />
|
||||
<TextBlock Grid.Column="0" x:Name="DeviceAvailable" Text="Device availability not yet detected"/>
|
||||
</StackPanel>
|
||||
<ToggleButton Grid.Row="1" Content="Pause/Resume" Click="OnPauseResume"/>
|
||||
<Button Grid.Row="2" Content="Spawn" Click="OnSpawnClicked"/>
|
||||
<Button Grid.Row="3" Content="Change Layout" Click="OnChangeLayout"/>
|
||||
<Button Grid.Row="4" Content="Save File" Click="OnSaveFile"/>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,181 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Toolkit.Uwp.Input.GazeControls;
|
||||
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Media.SpeechSynthesis;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace GazeInputTest
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
private StorageFolder _layoutsFolder;
|
||||
private MediaElement _mediaElement;
|
||||
private SpeechSynthesizer _speechSynthesizer;
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
ShowCursor.IsChecked = GazeInput.GetIsCursorVisible(this);
|
||||
|
||||
_mediaElement = new MediaElement();
|
||||
_speechSynthesizer = new SpeechSynthesizer();
|
||||
|
||||
GazeInput.IsDeviceAvailableChanged += GazeInput_IsDeviceAvailableChanged;
|
||||
GazeInput_IsDeviceAvailableChanged(null, null);
|
||||
Loaded += this.OnMainPageLoaded;
|
||||
}
|
||||
|
||||
private async void OnMainPageLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var uri = new Uri($"ms-appx:///Microsoft.Toolkit.Uwp.Input.GazeControls/KeyboardLayouts/MinAAC.xaml");
|
||||
var layoutFile = await StorageFile.GetFileFromApplicationUriAsync(uri);
|
||||
_layoutsFolder = await layoutFile.GetParentAsync();
|
||||
await GazeKeyboard.TryLoadLayoutAsync(layoutFile);
|
||||
GazeKeyboard.Target = TheTextBox;
|
||||
GazeKeyboard.PredictionTargets = new Button[] { Prediction0, Prediction1, Prediction2 };
|
||||
}
|
||||
|
||||
private void GazeInput_IsDeviceAvailableChanged(object sender, object e)
|
||||
{
|
||||
DeviceAvailable.Text = GazeInput.IsDeviceAvailable ? "Eye tracker device available" : "No eye tracker device available";
|
||||
}
|
||||
|
||||
private void OnStateChanged(object sender, StateChangedEventArgs ea)
|
||||
{
|
||||
Dwell.Content = ea.PointerState.ToString();
|
||||
}
|
||||
|
||||
private void Dwell_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Dwell.Content = "Clicked";
|
||||
}
|
||||
|
||||
private void ShowCursor_Toggle(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (ShowCursor.IsChecked.HasValue)
|
||||
{
|
||||
GazeInput.SetIsCursorVisible(this, ShowCursor.IsChecked.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private int _clickCount;
|
||||
|
||||
private void OnLegacyInvoked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_clickCount++;
|
||||
HowButton.Content = string.Format("{0}: Legacy click", _clickCount);
|
||||
}
|
||||
|
||||
private void OnGazeInvoked(object sender, DwellInvokedRoutedEventArgs e)
|
||||
{
|
||||
_clickCount++;
|
||||
HowButton.Content = string.Format("{0}: Accessible click", _clickCount);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnInvokeProgress(object sender, DwellProgressEventArgs e)
|
||||
{
|
||||
if (e.State == DwellProgressState.Progressing)
|
||||
{
|
||||
ProgressShow.Value = 100.0 * e.Progress;
|
||||
}
|
||||
|
||||
ProgressShow.IsIndeterminate = e.State == DwellProgressState.Complete;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private async void OnSpawnClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var newView = CoreApplication.CreateNewView();
|
||||
var newViewId = 0;
|
||||
|
||||
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
|
||||
{
|
||||
var frame = new Frame();
|
||||
frame.Navigate(typeof(MainPage), newViewId);
|
||||
Window.Current.Content = frame;
|
||||
|
||||
// In Windows 10 UWP we need to activate our view first.
|
||||
// Let's do it now so that we can use TryShow...() and SwitchAsync().
|
||||
Window.Current.Activate();
|
||||
|
||||
newViewId = ApplicationView.GetForCurrentView().Id;
|
||||
});
|
||||
|
||||
bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
|
||||
}
|
||||
|
||||
private async void OnChangeLayout(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var picker = new GazeFileOpenPicker();
|
||||
var library = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Documents);
|
||||
picker.Favorites = new List<StorageFolder>();
|
||||
picker.Favorites.Add(_layoutsFolder);
|
||||
picker.Favorites.Add(library.SaveFolder);
|
||||
picker.FileTypeFilter.Add(".xaml");
|
||||
picker.CurrentFolder = library.SaveFolder;
|
||||
await picker.ShowAsync();
|
||||
var file = picker.SelectedItem;
|
||||
if (file != null)
|
||||
{
|
||||
await GazeKeyboard.TryLoadLayoutAsync(file);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnOpenFile(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var picker = new GazeFileOpenPicker();
|
||||
var library = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Documents);
|
||||
picker.FileTypeFilter.Add(".txt");
|
||||
picker.CurrentFolder = library.SaveFolder;
|
||||
await picker.ShowAsync();
|
||||
var file = picker.SelectedItem;
|
||||
if (file != null)
|
||||
{
|
||||
TheTextBox.Text = await FileIO.ReadTextAsync(file);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnSaveFile(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var picker = new GazeFileSavePicker();
|
||||
var library = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Documents);
|
||||
picker.FileTypeFilter.Add(".txt");
|
||||
picker.CurrentFolder = library.SaveFolder;
|
||||
await picker.ShowAsync();
|
||||
var file = picker.SelectedItem;
|
||||
if (file != null)
|
||||
{
|
||||
await FileIO.WriteTextAsync(file, TheTextBox.Text);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnPlay(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var text = TheTextBox.Text.ToString();
|
||||
var stream = await _speechSynthesizer.SynthesizeTextToStreamAsync(text);
|
||||
_mediaElement.SetSource(stream, stream.ContentType);
|
||||
_mediaElement.AutoPlay = true;
|
||||
_mediaElement.Play();
|
||||
}
|
||||
|
||||
private void OnPauseResume(object sender, RoutedEventArgs e)
|
||||
{
|
||||
GazeKeyboard.IsEnabled = !GazeKeyboard.IsEnabled;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity
|
||||
Name="46799fa2-9a41-4ab8-817d-923ee9c0ceac"
|
||||
Publisher="CN=harishsk"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="46799fa2-9a41-4ab8-817d-923ee9c0ceac" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>GazeInputTest</DisplayName>
|
||||
<PublisherDisplayName>harishsk</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="GazeInputTest.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="GazeInputTest"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||
Description="GazeInputTest"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<uap:Capability Name="documentsLibrary"/>
|
||||
<uap:Capability Name="musicLibrary"/>
|
||||
<uap:Capability Name="picturesLibrary"/>
|
||||
<uap:Capability Name="videosLibrary"/>
|
||||
<rescap:Capability Name="inputInjectionBrokered" />
|
||||
<Capability Name="internetClient" />
|
||||
<DeviceCapability Name="gazeInput" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,32 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GazeInputTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("GazeInputTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
// [assembly: AssemblyVersion("1.0.0.0")]
|
||||
// [assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,26 @@
|
|||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
|
||||
-->
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
</Application>
|
||||
</Directives>
|