source: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs@ 28895

Last change on this file since 28895 was 28895, checked in by davidb, 10 years ago

Base Kinect Project

File size: 10.1 KB
Line 
1// --------------------------------------------------------------------------------------------------------------------
2// <copyright file="KinectSensorChooserUI.xaml.cs" company="Microsoft">
3// Copyright (c) Microsoft Corporation. All rights reserved.
4// </copyright>
5// --------------------------------------------------------------------------------------------------------------------
6
7namespace Microsoft.Kinect.Toolkit
8{
9 using System;
10 using System.ComponentModel;
11 using System.Diagnostics;
12 using System.Globalization;
13 using System.Windows;
14 using System.Windows.Controls;
15 using System.Windows.Data;
16 using System.Windows.Documents;
17 using System.Windows.Input;
18 using System.Windows.Navigation;
19 using System.Windows.Threading;
20
21 /// <summary>
22 /// Interaction logic for KinectSensorChooserUI.xaml
23 /// </summary>
24 public partial class KinectSensorChooserUI : UserControl
25 {
26 /// <summary>
27 /// Set this to true when the application is listining for audio input from the sensor.
28 /// UI will show a microphone icon.
29 /// </summary>
30 public static readonly DependencyProperty IsListeningProperty = DependencyProperty.Register(
31 "IsListening", typeof(bool), typeof(KinectSensorChooserUI), new PropertyMetadata(false));
32
33 /// <summary>
34 /// The KinectSensorChooser whose status we are displaying.
35 /// </summary>
36 public static readonly DependencyProperty KinectSensorChooserProperty = DependencyProperty.Register(
37 "KinectSensorChooser", typeof(KinectSensorChooser), typeof(KinectSensorChooserUI), new PropertyMetadata(null));
38
39 /// <summary>
40 /// Used internally to transfer the visual state from the view model to the
41 /// VisualStateManager defined in XAML.
42 /// </summary>
43 public static readonly DependencyProperty VisualStateProperty = DependencyProperty.Register(
44 "VisualState",
45 typeof(string),
46 typeof(KinectSensorChooserUI),
47 new PropertyMetadata(null, (o, args) => ((KinectSensorChooserUI)o).OnVisualstateChanged((string)args.NewValue)));
48
49 /// <summary>
50 /// Timer used to check if the mouse is still in the popup when we activated
51 /// the popup with a mouse hover. We do this because the mouse may not be
52 /// in the popup when it comes up and we will never get a mouse leave event.
53 /// </summary>
54 private readonly DispatcherTimer popupCloseCheck;
55
56 private bool suppressPopupOnFocus;
57
58 private Window parentWindow;
59
60 /// <summary>
61 /// Initializes a new instance of the KinectSensorChooserUI class
62 /// </summary>
63 public KinectSensorChooserUI()
64 {
65 Loaded += OnLoaded;
66 Unloaded += OnUnloaded;
67
68 this.InitializeComponent();
69 this.popupCloseCheck = new DispatcherTimer(
70 TimeSpan.FromMilliseconds(1000), DispatcherPriority.Normal, this.OnPopupCloseCheckFired, this.Dispatcher);
71
72 var viewModel = new KinectSensorChooserUIViewModel();
73 this.layoutRoot.DataContext = viewModel;
74
75 var visualStateBinding = new Binding("VisualState") { Source = viewModel };
76 SetBinding(VisualStateProperty, visualStateBinding);
77
78 var sensorChooserBinding = new Binding("KinectSensorChooser") { Source = this };
79 BindingOperations.SetBinding(viewModel, KinectSensorChooserUIViewModel.KinectSensorChooserProperty, sensorChooserBinding);
80
81 var isListeningBinding = new Binding("IsListening") { Source = this };
82 BindingOperations.SetBinding(viewModel, KinectSensorChooserUIViewModel.IsListeningProperty, isListeningBinding);
83
84 this.expandedPopup.LayoutUpdated += this.ExpandedPopupOnLayoutUpdated;
85 }
86
87 /// <summary>
88 /// Set this to true when the application is listining for audio input from the sensor.
89 /// UI will show a microphone icon. Value is passed through to the view model.
90 /// </summary>
91 public bool IsListening
92 {
93 get
94 {
95 return (bool)this.GetValue(IsListeningProperty);
96 }
97
98 set
99 {
100 this.SetValue(IsListeningProperty, value);
101 }
102 }
103
104 /// <summary>
105 /// The KinectSensorChooser whose status we are displaying. Value is
106 /// passed through to the view model.
107 /// </summary>
108 public KinectSensorChooser KinectSensorChooser
109 {
110 get
111 {
112 return (KinectSensorChooser)this.GetValue(KinectSensorChooserProperty);
113 }
114
115 set
116 {
117 this.SetValue(KinectSensorChooserProperty, value);
118 }
119 }
120
121 /// <summary>
122 /// Used internally to transfer the visual state from the view model to the
123 /// VisualStateManager defined in XAML.
124 /// </summary>
125 public string VisualState
126 {
127 get
128 {
129 return (string)this.GetValue(VisualStateProperty);
130 }
131
132 set
133 {
134 this.SetValue(VisualStateProperty, value);
135 }
136 }
137
138 private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
139 {
140 this.parentWindow = Window.GetWindow(this);
141 if (parentWindow != null)
142 {
143 parentWindow.Deactivated += ParentWindowOnDeactivated;
144 }
145 }
146
147 private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
148 {
149 if (this.parentWindow != null)
150 {
151 parentWindow.Deactivated -= ParentWindowOnDeactivated;
152 }
153 }
154
155 private void ParentWindowOnDeactivated(object sender, EventArgs eventArgs)
156 {
157 this.ClosePopup();
158 }
159
160 private void ClosePopup()
161 {
162 this.expandedPopup.IsOpen = false;
163 }
164
165 private void OpenPopup()
166 {
167 this.expandedPopup.IsOpen = true;
168 }
169
170 private void OnRootGridGotKeyboardFocus(object sender, RoutedEventArgs e)
171 {
172 if (!this.suppressPopupOnFocus)
173 {
174 OpenPopup();
175 }
176 }
177
178 private void OnRootGridMouseEnter(object sender, MouseEventArgs e)
179 {
180 OpenPopup();
181 }
182
183 private void ExpandedPopupOnLayoutUpdated(object sender, EventArgs eventArgs)
184 {
185 // makes the popup top-aligned with its parent
186 this.expandedPopup.VerticalOffset = (this.popupGrid.ActualHeight - this.layoutRoot.ActualHeight - 1.0) / 2.0;
187 }
188
189 private void ExpandedPopupOnOpened(object sender, EventArgs eventArgs)
190 {
191 this.popupCloseCheck.Stop();
192
193 if (this.layoutRoot.IsKeyboardFocusWithin)
194 {
195 Keyboard.Focus(this.popupGrid);
196 }
197 else
198 {
199 this.popupCloseCheck.Start();
200 }
201 }
202
203 private void OnExpandedPopupMouseLeave(object sender, MouseEventArgs e)
204 {
205 this.ClosePopup();
206 }
207
208 private void OnPopupCloseCheckFired(object sender, EventArgs e)
209 {
210 this.popupCloseCheck.Stop();
211 if (this.expandedPopup.IsOpen && !this.popupGrid.IsMouseOver && !this.popupGrid.IsKeyboardFocusWithin)
212 {
213 this.ClosePopup();
214 }
215 }
216
217 private void OnPopupGridGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
218 {
219 var oldFocus = e.OldFocus as FrameworkElement;
220 var newFocus = e.NewFocus as FrameworkElement;
221
222 if (newFocus == this.popupGrid)
223 {
224 if (oldFocus != this.layoutRoot)
225 {
226 // Focus is returning to us after being tabbed around our children.
227 // That is our signal to quit the popup.
228 this.suppressPopupOnFocus = true;
229 this.layoutRoot.Focusable = false;
230 e.Handled = true;
231
232 // There doesn't seem to be an easy way to generically tell which way the user was
233 // navigating with the keyboard (tab or shift+tab) check if the shift key is pressed
234 FocusNavigationDirection direction = ((Keyboard.Modifiers & ModifierKeys.Shift) != 0)
235 ? FocusNavigationDirection.Previous
236 : FocusNavigationDirection.Next;
237
238 this.ClosePopup();
239 this.MoveFocus(new TraversalRequest(direction));
240 this.layoutRoot.Focusable = true;
241 this.suppressPopupOnFocus = false;
242 }
243 }
244 }
245
246 private void OnVisualstateChanged(string newState)
247 {
248 VisualStateManager.GoToState(this, newState, true);
249 }
250
251 private void TellMeMoreLinkRequestNavigate(object sender, RequestNavigateEventArgs e)
252 {
253 var hyperlink = e.OriginalSource as Hyperlink;
254 if (hyperlink != null)
255 {
256 try
257 {
258 // Careful - ensure that this NavigateUri comes from a trusted source, as in this sample, before launching a process using it.
259 Process.Start(new ProcessStartInfo(hyperlink.NavigateUri.ToString()));
260 }
261 catch (Win32Exception)
262 {
263 // No default browser was set to handle the http request or unable to launch the browser
264 MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Properties.Resources.NoDefaultBrowserAvailable, hyperlink.NavigateUri));
265 }
266
267 this.ClosePopup();
268 }
269
270 e.Handled = true;
271 }
272 }
273}
Note: See TracBrowser for help on using the repository browser.