Skip to content

Commit

Permalink
feat: ComboBox.IsEditable
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Oct 5, 2024
1 parent bb05811 commit f491c97
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 33 deletions.
16 changes: 16 additions & 0 deletions src/Uno.UI/DirectUI/XboxUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.System;

namespace DirectUI;

internal static class XboxUtility
{
internal static bool IsGamepadNavigationInput(VirtualKey key)
{
return (int)key >= (int)VirtualKey.GamepadA && (int)key <= (int)VirtualKey.GamepadRightThumbstickLeft;
}
}
10 changes: 2 additions & 8 deletions src/Uno.UI/UI/Xaml/Controls/ComboBox/ComboBox.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ public object Header
typeof(ComboBox),
new FrameworkPropertyMetadata(
defaultValue: null,
options: FrameworkPropertyMetadataOptions.None,
propertyChangedCallback: (s, e) => ((ComboBox)s)?.UpdateHeaderVisibility()
)
);
options: FrameworkPropertyMetadataOptions.None));

/// <summary>
/// Gets or sets the DataTemplate used to display the content of the control's header.
Expand All @@ -73,10 +70,7 @@ public DataTemplate HeaderTemplate
typeof(ComboBox),
new FrameworkPropertyMetadata(
defaultValue: null,
options: FrameworkPropertyMetadataOptions.ValueDoesNotInheritDataContext,
propertyChangedCallback: (s, e) => ((ComboBox)s)?.UpdateHeaderVisibility()
)
);
options: FrameworkPropertyMetadataOptions.ValueDoesNotInheritDataContext));

/// <summary>
/// Gets or sets a value that indicates whether the user can
Expand Down
2 changes: 0 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/ComboBox/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public partial class ComboBox : Selector
private int m_indexForcedToUnselectedVisual = -1;
private int m_indexForcedToSelectedVisual = -1;

private bool _wasPointerPressed;

/// <summary>
/// The 'inline' parent view of the selected item within the dropdown list. This is only set if SelectedItem is a view type.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ namespace Microsoft.UI.Xaml.Controls;

partial class ComboBox
{
private bool m_isInSearchingMode;
#pragma warning disable CS0649 // never assigned to, and will always have its default value false
#pragma warning disable CS0414 // never assigned to, and will always have its default value false
private bool m_handledGamepadOrRemoteKeyDown;
private bool m_ignoreCancelKeyDowns;
private bool m_isEditModeConfigured;
private bool m_isInSearchingMode;

// On pointer released we perform some actions depending on control. We decide to whether to perform them
// depending on some parameters including but not limited to whether released is followed by a pressed, which
Expand Down
56 changes: 34 additions & 22 deletions src/Uno.UI/UI/Xaml/Controls/ComboBox/ComboBox.partial.mux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

using System;
using System.Collections.Generic;
using System.Linq;
using DirectUI;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml.Controls.Primitives;
Expand Down Expand Up @@ -70,10 +69,10 @@ private void SetupEditableMode()
if (m_tpDropDownOverlayPart is not null)
{
m_tpDropDownOverlayPart.PointerEntered += OnDropDownOverlayPointerEntered;
m_spDropDownOverlayPointerEnteredHandler.Disposable = Disposable.Create(() => m_tpContentPresenterPart.PointerEntered -= OnDropDownOverlayPointerEntered);
m_spDropDownOverlayPointerEnteredHandler.Disposable = Disposable.Create(() => m_tpDropDownOverlayPart.PointerEntered -= OnDropDownOverlayPointerEntered);

m_tpDropDownOverlayPart.PointerExited += OnDropDownOverlayPointerExited;
m_spDropDownOverlayPointerExitedHandler.Disposable = Disposable.Create(() => m_tpContentPresenterPart.PointerExited -= OnDropDownOverlayPointerExited);
m_spDropDownOverlayPointerExitedHandler.Disposable = Disposable.Create(() => m_tpDropDownOverlayPart.PointerExited -= OnDropDownOverlayPointerExited);

m_tpDropDownOverlayPart.Visibility = Visibility.Visible;
}
Expand All @@ -86,13 +85,14 @@ private void SetupEditableMode()
ResetSearch();
ResetSearchString();

wrl::ComPtr<xaml_controls::IInputValidationContext> context;
get_ValidationContext(&context));
pEditableTextPartAsTextBox.ValidationContext(context.Get()));
// TODO Uno: Input validation support #4839
//wrl::ComPtr<xaml_controls::IInputValidationContext> context;
//get_ValidationContext(&context));
//pEditableTextPartAsTextBox.ValidationContext(context.Get()));

wrl::ComPtr<xaml_controls::IInputValidationCommand> command;
get_ValidationCommand(&command));
pEditableTextPartAsTextBox->put_ValidationCommand(command.Get()));
//wrl::ComPtr<xaml_controls::IInputValidationCommand> command;
//get_ValidationCommand(&command));
//pEditableTextPartAsTextBox->put_ValidationCommand(command.Get()));

if (m_tpPopupPart is not null)
{
Expand Down Expand Up @@ -129,10 +129,8 @@ private void DisableEditableMode()

if (m_tpDropDownOverlayPart is not null)
{
var pDropDownOverlayPartAsI = iinspectable_cast(m_tpDropDownOverlayPart.Cast<Border>());

m_spDropDownOverlayPointerEnteredHandler.DetachEventHandler(pDropDownOverlayPartAsI));
m_spDropDownOverlayPointerExitedHandler.DetachEventHandler(pDropDownOverlayPartAsI));
m_spDropDownOverlayPointerEnteredHandler.Disposable = null;
m_spDropDownOverlayPointerExitedHandler.Disposable = null;

m_tpDropDownOverlayPart.Visibility = Visibility.Collapsed;
}
Expand Down Expand Up @@ -621,7 +619,7 @@ private void UpdateEditableContentPresenterTextBlock(object item)
}

EnsurePropertyPathListener();
var itemString = TryGetStringValue(item) //, m_spPropertyPathListener); TODO Uno: Missing PropertyPathListener support
var itemString = TryGetStringValue(item); //, m_spPropertyPathListener); TODO Uno: Missing PropertyPathListener support
UpdateEditableContentPresenterTextBlock(itemString);
}

Expand Down Expand Up @@ -699,17 +697,15 @@ private void CommitRevertEditableSearch(bool restoreValue)

if (m_customValueRef is not null)
{
wrl_wrappers::HString storedString;
IValueBoxer::UnboxValue(m_customValueRef.Get(), storedString.GetAddressOf());
var storedString = m_customValueRef as string;

// Prevent sending the event if the custom value is the same.
sendEvent = !AreStringsEqual(storedString, searchString);
}

if (sendEvent)
{
ctl::ComPtr<IInspectable> spInspectable;
PropertyValue::CreateFromString(searchString, &spInspectable));
var spInspectable = searchString;

bool isHandled = RaiseTextSubmittedEvent(searchString);

Expand Down Expand Up @@ -845,7 +841,6 @@ private void OnKeyDownPrivate(object pSender, KeyRoutedEventArgs pArgs)
m_handledGamepadOrRemoteKeyDown = eventHandled && XboxUtility.IsGamepadNavigationInput(originalKey);
}


private void OnTextBoxTextChanged(object sender, TextChangedEventArgs args)
{
//DEAD_CODE_REMOVAL
Expand Down Expand Up @@ -893,7 +888,7 @@ protected override void OnPointerEntered(PointerRoutedEventArgs e)

if (isEventSourceTarget)
{
m_isPointerOverMain = true;
m_IsPointerOverMain = true;
m_bIsPressed = false;
UpdateVisualState();
}
Expand Down Expand Up @@ -1434,7 +1429,7 @@ private bool StartsWithIgnoreLinguisticSemantics(string strSource, string strPre
return strSource.StartsWith(strPrefix, StringComparison.InvariantCultureIgnoreCase);
}

private bool AreStringsEqual(string str1, string str2) => string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);
private bool AreStringsEqual(string? str1, string? str2) => string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);

private bool IsSearchStringValid(string str)
{
Expand Down Expand Up @@ -1628,7 +1623,7 @@ private bool IsChildOfTarget(
return result;
}

private InputDeviceType GetInputDeviceTypeUsedToOpen() => m_inputDeviceTypeUsedToOpen;
internal InputDeviceType GetInputDeviceTypeUsedToOpen() => m_inputDeviceTypeUsedToOpen;

private void OverrideSelectedIndexForVisualStates(int selectedIndexOverride)
{
Expand Down Expand Up @@ -1736,4 +1731,21 @@ private void CreateEditableContentPresenterTextBlock()
m_tpEditableContentPresenterTextBlock = spTextBlock;
}
}


#if HAS_UNO // Not ported yet
private void SetContentPresenter(int value) { }

private void PopupKeyDown(KeyRoutedEventArgs args) { }

private void MainKeyDown(KeyRoutedEventArgs args) { }

private void ArrangePopup(bool value) { }

private void EnsurePresenterReadyForFullMode() { }

private void EnsurePresenterReadyForInlineMode() { }

private void ForceApplyInlineLayoutUpdate() { }
#endif
}
9 changes: 9 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Popup/Popup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,15 @@ public PopupPlacementMode DesiredPlacement
typeof(Popup),
new FrameworkPropertyMetadata(PopupPlacementMode.Auto, FrameworkPropertyMetadataOptions.AffectsArrange));

internal DependencyObject OverlayInputPassThroughElement
{
get => (DependencyObject)GetValue(OverlayInputPassThroughElementProperty);
set => SetValue(OverlayInputPassThroughElementProperty, value);
}

internal static DependencyProperty OverlayInputPassThroughElementProperty { get; } =
DependencyProperty.Register(nameof(OverlayInputPassThroughElement), typeof(DependencyObject), typeof(Popup), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.ValueDoesNotInheritDataContext));

/// <summary>
/// Gets the actual placement of the popup, in relation to its placement target.
/// </summary>
Expand Down

0 comments on commit f491c97

Please sign in to comment.