Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 13ecbb2

Browse files
Pulling the AutoCompleteBox from the original GitHub Desktop for Windows
1 parent 5722b18 commit 13ecbb2

22 files changed

+3992
-0
lines changed

src/GitHub.UI/Controls/AutoCompleteBox/AutoCompleteBox.cs

Lines changed: 1586 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
// (c) Copyright Microsoft Corporation.
2+
// This source is subject to the Microsoft Public License (Ms-PL).
3+
// Please see http://go.microsoft.com/fwlink/?LinkID=131993] for details.
4+
// All other rights reserved.
5+
6+
using System.Collections.Generic;
7+
using System.Diagnostics.CodeAnalysis;
8+
using System.Windows;
9+
using System.Windows.Automation;
10+
using System.Windows.Automation.Peers;
11+
using System.Windows.Automation.Provider;
12+
13+
namespace GitHub.UI
14+
{
15+
/// <summary>
16+
/// Exposes AutoCompleteBox types to UI Automation.
17+
/// </summary>
18+
/// <QualityBand>Stable</QualityBand>
19+
public sealed class AutoCompleteBoxAutomationPeer : FrameworkElementAutomationPeer, IValueProvider, IExpandCollapseProvider, ISelectionProvider
20+
{
21+
/// <summary>
22+
/// The name reported as the core class name.
23+
/// </summary>
24+
private const string autoCompleteBoxClassNameCore = "AutoCompleteBox";
25+
26+
/// <summary>
27+
/// Gets the AutoCompleteBox that owns this
28+
/// AutoCompleteBoxAutomationPeer.
29+
/// </summary>
30+
private AutoCompleteBox OwnerAutoCompleteBox
31+
{
32+
get { return (AutoCompleteBox)Owner; }
33+
}
34+
35+
/// <summary>
36+
/// Gets a value indicating whether the UI automation provider allows
37+
/// more than one child element to be selected concurrently.
38+
/// </summary>
39+
/// <remarks>
40+
/// This API supports the .NET Framework infrastructure and is not
41+
/// intended to be used directly from your code.
42+
/// </remarks>
43+
/// <value>True if multiple selection is allowed; otherwise, false.</value>
44+
bool ISelectionProvider.CanSelectMultiple
45+
{
46+
get { return false; }
47+
}
48+
49+
/// <summary>
50+
/// Gets a value indicating whether the UI automation provider
51+
/// requires at least one child element to be selected.
52+
/// </summary>
53+
/// <remarks>
54+
/// This API supports the .NET Framework infrastructure and is not
55+
/// intended to be used directly from your code.
56+
/// </remarks>
57+
/// <value>True if selection is required; otherwise, false.</value>
58+
bool ISelectionProvider.IsSelectionRequired
59+
{
60+
get { return false; }
61+
}
62+
63+
/// <summary>
64+
/// Initializes a new instance of the AutoCompleteBoxAutomationPeer
65+
/// class.
66+
/// </summary>
67+
/// <param name="owner">
68+
/// The AutoCompleteBox that is associated with this
69+
/// AutoCompleteBoxAutomationPeer.
70+
/// </param>
71+
public AutoCompleteBoxAutomationPeer(AutoCompleteBox owner)
72+
: base(owner)
73+
{
74+
}
75+
76+
/// <summary>
77+
/// Gets the control type for the AutoCompleteBox that is associated
78+
/// with this AutoCompleteBoxAutomationPeer. This method is called by
79+
/// GetAutomationControlType.
80+
/// </summary>
81+
/// <returns>ComboBox AutomationControlType.</returns>
82+
protected override AutomationControlType GetAutomationControlTypeCore()
83+
{
84+
return AutomationControlType.ComboBox;
85+
}
86+
87+
/// <summary>
88+
/// Gets the name of the AutoCompleteBox that is associated with this
89+
/// AutoCompleteBoxAutomationPeer. This method is called by
90+
/// GetClassName.
91+
/// </summary>
92+
/// <returns>The name AutoCompleteBox.</returns>
93+
protected override string GetClassNameCore()
94+
{
95+
return autoCompleteBoxClassNameCore;
96+
}
97+
98+
/// <summary>
99+
/// Gets the control pattern for the AutoCompleteBox that is associated
100+
/// with this AutoCompleteBoxAutomationPeer.
101+
/// </summary>
102+
/// <param name="patternInterface">The desired PatternInterface.</param>
103+
/// <returns>The desired AutomationPeer or null.</returns>
104+
public override object GetPattern(PatternInterface patternInterface)
105+
{
106+
object iface = null;
107+
var owner = OwnerAutoCompleteBox;
108+
109+
if (patternInterface == PatternInterface.Value)
110+
{
111+
iface = this;
112+
}
113+
else if (patternInterface == PatternInterface.ExpandCollapse)
114+
{
115+
iface = this;
116+
}
117+
else if (owner.SelectionAdapter != null)
118+
{
119+
var peer = owner.SelectionAdapter.CreateAutomationPeer();
120+
if (peer != null)
121+
{
122+
iface = peer.GetPattern(patternInterface);
123+
}
124+
}
125+
126+
return iface ?? base.GetPattern(patternInterface);
127+
}
128+
129+
/// <summary>
130+
/// Blocking method that returns after the element has been expanded.
131+
/// </summary>
132+
/// <remarks>
133+
/// This API supports the .NET Framework infrastructure and is not
134+
/// intended to be used directly from your code.
135+
/// </remarks>
136+
void IExpandCollapseProvider.Expand()
137+
{
138+
if (!IsEnabled())
139+
{
140+
throw new ElementNotEnabledException();
141+
}
142+
143+
OwnerAutoCompleteBox.IsDropDownOpen = true;
144+
}
145+
146+
/// <summary>
147+
/// Blocking method that returns after the element has been collapsed.
148+
/// </summary>
149+
/// <remarks>
150+
/// This API supports the .NET Framework infrastructure and is not
151+
/// intended to be used directly from your code.
152+
/// </remarks>
153+
void IExpandCollapseProvider.Collapse()
154+
{
155+
if (!IsEnabled())
156+
{
157+
throw new ElementNotEnabledException();
158+
}
159+
160+
OwnerAutoCompleteBox.IsDropDownOpen = false;
161+
}
162+
163+
/// <summary>
164+
/// Gets an element's current Collapsed or Expanded state.
165+
/// </summary>
166+
/// <remarks>
167+
/// This API supports the .NET Framework infrastructure and is not
168+
/// intended to be used directly from your code.
169+
/// </remarks>
170+
ExpandCollapseState IExpandCollapseProvider.ExpandCollapseState
171+
{
172+
get
173+
{
174+
return OwnerAutoCompleteBox.IsDropDownOpen ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;
175+
}
176+
}
177+
178+
/// <summary>
179+
/// Raises the ExpandCollapse automation event.
180+
/// </summary>
181+
/// <param name="oldValue">The old value.</param>
182+
/// <param name="newValue">The new value.</param>
183+
internal void RaiseExpandCollapseAutomationEvent(bool oldValue, bool newValue)
184+
{
185+
RaisePropertyChangedEvent(
186+
ExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty,
187+
oldValue ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed,
188+
newValue ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed);
189+
}
190+
191+
/// <summary>
192+
/// Sets the value of a control.
193+
/// </summary>
194+
/// <param name="value">The value to set. The provider is responsible
195+
/// for converting the value to the appropriate data type.</param>
196+
void IValueProvider.SetValue(string value)
197+
{
198+
OwnerAutoCompleteBox.Text = value;
199+
}
200+
201+
/// <summary>
202+
/// Gets a value indicating whether the value of a control is
203+
/// read-only.
204+
/// </summary>
205+
/// <value>True if the value is read-only; false if it can be modified.</value>
206+
bool IValueProvider.IsReadOnly
207+
{
208+
get
209+
{
210+
return !OwnerAutoCompleteBox.IsEnabled;
211+
}
212+
}
213+
214+
/// <summary>
215+
/// Gets the value of the control.
216+
/// </summary>
217+
/// <value>The value of the control.</value>
218+
string IValueProvider.Value
219+
{
220+
get
221+
{
222+
return OwnerAutoCompleteBox.Text ?? string.Empty;
223+
}
224+
}
225+
226+
/// <summary>
227+
/// Gets the collection of child elements of the AutoCompleteBox that
228+
/// are associated with this AutoCompleteBoxAutomationPeer. This method
229+
/// is called by GetChildren.
230+
/// </summary>
231+
/// <returns>
232+
/// A collection of automation peer elements, or an empty collection
233+
/// if there are no child elements.
234+
/// </returns>
235+
[SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Justification = "Required by automation")]
236+
protected override List<AutomationPeer> GetChildrenCore()
237+
{
238+
var children = new List<AutomationPeer>();
239+
var owner = OwnerAutoCompleteBox;
240+
241+
// TextBox part.
242+
var textBox = owner.TextBox;
243+
if (textBox != null)
244+
{
245+
var peer = CreatePeerForElement(textBox.Control);
246+
if (peer != null)
247+
{
248+
children.Insert(0, peer);
249+
}
250+
}
251+
252+
// Include SelectionAdapter's children.
253+
if (owner.SelectionAdapter != null)
254+
{
255+
var selectionAdapterPeer = owner.SelectionAdapter.CreateAutomationPeer();
256+
if (selectionAdapterPeer != null)
257+
{
258+
var listChildren = selectionAdapterPeer.GetChildren();
259+
if (listChildren != null)
260+
{
261+
children.AddRange(listChildren);
262+
}
263+
}
264+
}
265+
266+
return children;
267+
}
268+
269+
/// <summary>
270+
/// Retrieves a UI automation provider for each child element that is
271+
/// selected.
272+
/// </summary>
273+
/// <returns>An array of UI automation providers.</returns>
274+
/// <remarks>
275+
/// This API supports the .NET Framework infrastructure and is not
276+
/// intended to be used directly from your code.
277+
/// </remarks>
278+
IRawElementProviderSimple[] ISelectionProvider.GetSelection()
279+
{
280+
if (OwnerAutoCompleteBox.SelectionAdapter != null)
281+
{
282+
var selectedItem = OwnerAutoCompleteBox.SelectionAdapter.SelectedItem;
283+
if (selectedItem != null)
284+
{
285+
var uie = selectedItem as UIElement;
286+
if (uie != null)
287+
{
288+
var peer = CreatePeerForElement(uie);
289+
if (peer != null)
290+
{
291+
return new[] { ProviderFromPeer(peer) };
292+
}
293+
}
294+
}
295+
}
296+
297+
return new IRawElementProviderSimple[] { };
298+
}
299+
}
300+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Collections.Generic;
2+
3+
namespace GitHub.UI
4+
{
5+
public class AutoCompleteResult
6+
{
7+
public static AutoCompleteResult Empty = new AutoCompleteResult(0, new AutoCompleteSuggestion[] {});
8+
9+
public AutoCompleteResult(int offset, IReadOnlyList<AutoCompleteSuggestion> suggestions)
10+
{
11+
Offset = offset;
12+
Suggestions = suggestions;
13+
}
14+
15+
public int Offset { get; private set; }
16+
public IReadOnlyList<AutoCompleteSuggestion> Suggestions { get; private set; }
17+
}
18+
}

0 commit comments

Comments
 (0)