make things functional again pt. 2
MODIFY
WalletWasabi.Fluent/Controls/TagsBox.xaml.cs
WalletWasabi.Fluent/Controls/TagsBox.xaml.cs
-using System.Collections;
-using System.Linq;
-using Avalonia.Controls;
-using Avalonia;
-using Avalonia.Controls.Primitives;
using System;
-using System.Collections.Generic;
+using System.Collections;
using System.Globalization;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Threading;
-using Avalonia.Xaml.Interactivity;
+using ReactiveUI;
using WalletWasabi.Fluent.ViewModels.TagsBox;
+using System;
+using System.Collections;
+using System.Reactive.Linq;
+using DynamicData;
+using DynamicData.Binding;
+using ReactiveUI;
+using WalletWasabi.Gui.ViewModels;
namespace WalletWasabi.Fluent.Controls
{
@@ -21,35 +24,55 @@ namespace WalletWasabi.Fluent.Controls
/// </summary>
public class TagsBox : ItemsControl
{
- private IEnumerable _suggestionsEnumerable;
+ public static readonly StyledProperty<bool> RestrictInputToSuggestionsProperty =
+ AvaloniaProperty.Register<TagsBox, bool>(nameof(RestrictInputToSuggestions));
+
+ public static readonly StyledProperty<int> ItemCountLimitProperty =
+ AvaloniaProperty.Register<TagsBox, int>(nameof(ItemCountLimit));
+
+ public static readonly DirectProperty<TagsBox, IEnumerable> SuggestionsProperty =
+ AvaloniaProperty.RegisterDirect<TagsBox, IEnumerable>(
+ nameof(Suggestions),
+ o => o.Suggestions,
+ (o, v) => o.Suggestions = v);
+
private AutoCompleteBox? _autoCompleteBox;
- protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
- {
- base.OnApplyTemplate(e);
+ private bool _bs1;
+ private bool _bs2;
- Presenter.ApplyTemplate();
- _autoCompleteBox = (Presenter.Panel as ConcatenatingWrapPanel)?.ConcatenatedChildren
- .OfType<AutoCompleteBox>().FirstOrDefault();
+ private IDisposable? _disposable;
+ private bool _isInputEnabled = true;
+ private IEnumerable _suggestionsEnumerable;
- _autoCompleteBox.KeyUp += OnKeyUp;
- _autoCompleteBox.TextChanged += OnTextChanged;
- _autoCompleteBox.DropDownClosed += OnDropDownClosed;
+ public TagsBox()
+ {
+ this.WhenAnyValue(x => x.Items)
+ .Subscribe(RegisterIsInputEnabledListener);
- _disposable =
- _autoCompleteBox.AddDisposableHandler(InputElement.TextInputEvent, OnTextInput,
- RoutingStrategies.Tunnel);
- _autoCompleteBox?.Focus();
}
- public static readonly DirectProperty<TagsBox, IEnumerable> SuggestionsProperty =
- AvaloniaProperty.RegisterDirect<TagsBox, IEnumerable>(
- nameof(Suggestions),
- o => o.Suggestions,
- (o, v) => o.Suggestions = v);
+ private void RegisterIsInputEnabledListener(IEnumerable enumerable)
+ {
+ if(Items is null || ItemCountLimit == 0) return;
+
+ _isInputEnabled = Items.Cast<object>().Count() < ItemCountLimit;
+ }
+
+ public bool RestrictInputToSuggestions
+ {
+ get => GetValue(RestrictInputToSuggestionsProperty);
+ set => SetValue(RestrictInputToSuggestionsProperty, value);
+ }
+
+ public int ItemCountLimit
+ {
+ get => GetValue(ItemCountLimitProperty);
+ set => SetValue(ItemCountLimitProperty, value);
+ }
public IEnumerable Suggestions
{
@@ -57,40 +80,35 @@ namespace WalletWasabi.Fluent.Controls
set => SetAndRaise(SuggestionsProperty, ref _suggestionsEnumerable, value);
}
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
- private IDisposable? _disposable;
+ Presenter.ApplyTemplate();
- private bool _bs1;
- private bool _bs2;
+ _autoCompleteBox = (Presenter.Panel as ConcatenatingWrapPanel)?.ConcatenatedChildren
+ .OfType<AutoCompleteBox>().FirstOrDefault();
- public bool RestrictInputToSuggestions { get; set; }
+ if (_autoCompleteBox is null) return;
- public bool IsInputEnabled { get; set; } = true;
+ _autoCompleteBox.KeyUp += OnKeyUp;
+ _autoCompleteBox.TextChanged += OnTextChanged;
+ _autoCompleteBox.DropDownClosed += OnDropDownClosed;
+ _disposable =
+ _autoCompleteBox.AddDisposableHandler(TextInputEvent, OnTextInput,
+ RoutingStrategies.Tunnel);
- // public Action GrabFocusAction()
- // {
- // if (!_autoCompleteBox?.IsFocused ?? false) _autoCompleteBox?.Focus();
- // }
+ _autoCompleteBox?.Focus();
- // protected override void OnAttached()
- // {
- // // if (_autoCompleteBox is null) return;
- // //
- // //
- // // // Refocus because the old control is destroyed
- // // // when the tag list changes.
- // // DoGrabFocus();
- // //
- // // base.OnAttached();
- // }
- //
+
+ }
private void OnTextInput(object? sender, TextInputEventArgs e)
{
if (_autoCompleteBox is null) return;
- if (!IsInputEnabled)
+ if (!_isInputEnabled)
{
e.Handled = true;
return;
@@ -109,9 +127,7 @@ namespace WalletWasabi.Fluent.Controls
if (currentText.Length == 0 || !(_autoCompleteBox.SelectedItem is string selItem) || selItem.Length == 0 ||
currentText != selItem)
- {
return;
- }
AddTag(currentText.Trim());
_autoCompleteBox.ClearValue(AutoCompleteBox.SelectedItemProperty);
@@ -134,12 +150,12 @@ namespace WalletWasabi.Fluent.Controls
var currentText = _autoCompleteBox.Text ?? "";
var currentTextTrimmed = currentText.Trim();
- if (!IsInputEnabled ||
+ if (!_isInputEnabled ||
currentText.Length < 1 ||
string.IsNullOrEmpty(currentTextTrimmed) ||
!currentText.EndsWith(' ') ||
- (RestrictInputToSuggestions && !Suggestions.Cast<string>().Any(x => x.Equals(currentTextTrimmed,
- StringComparison.InvariantCultureIgnoreCase))))
+ RestrictInputToSuggestions && !Suggestions.Cast<string>().Any(x => x.Equals(currentTextTrimmed,
+ StringComparison.InvariantCultureIgnoreCase)))
return;
AddTag(currentTextTrimmed);
@@ -166,7 +182,7 @@ namespace WalletWasabi.Fluent.Controls
case Key.Back when _bs1 && _bs2:
RemoveTag();
break;
- case Key.Enter when IsInputEnabled && !string.IsNullOrEmpty(strTrimmed):
+ case Key.Enter when _isInputEnabled && !string.IsNullOrEmpty(strTrimmed):
if (RestrictInputToSuggestions && !Suggestions.Cast<string>().Any(x =>
x.Equals(strTrimmed, StringComparison.InvariantCultureIgnoreCase)))
break;
@@ -188,7 +204,8 @@ namespace WalletWasabi.Fluent.Controls
private void AddTag(string strTrimmed)
{
- Items = Items.Cast<object>().Concat(new[] {new TagViewModel((TagsBoxViewModel) this.DataContext,strTrimmed)});
+ Items = Items.Cast<object>()
+ .Concat(new[] {new TagViewModel((TagsBoxViewModel) DataContext, strTrimmed)});
}
// protected override void OnDetaching()

DELETE
WalletWasabi.Fluent/Controls/TagsBoxAutoCompleteBoxBehavior.cs
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
-using Avalonia.Threading;
-using Avalonia.Xaml.Interactivity;
-
-namespace WalletWasabi.Fluent.Controls
-{
- public class TagsBoxAutoCompleteBoxBehavior : Behavior<AutoCompleteBox>
- {
-
- }
-}
\ No newline at end of file

DELETE
WalletWasabi.Fluent/ViewModels/TagsBox/TagInputViewModel.cs
-using System;
-using System.Collections;
-using System.Reactive.Linq;
-using DynamicData;
-using DynamicData.Binding;
-using ReactiveUI;
-using WalletWasabi.Gui.ViewModels;
-
-namespace WalletWasabi.Fluent.ViewModels.TagsBox
-{
- public class TagInputViewModel : ViewModelBase
- {
- private readonly TagsBoxViewModel _parent;
- private readonly ObservableAsPropertyHelper<bool> _restrictInputToSuggestions;
- private readonly ObservableAsPropertyHelper<IEnumerable> _suggestions;
-
- private Action _backspaceAndEmptyTextAction;
- private Action<string> _commitTextAction;
- private Action _grabFocusAction;
- private readonly ObservableAsPropertyHelper<bool> _isInputEnabled;
-
- public TagInputViewModel(TagsBoxViewModel parent)
- {
- _parent = parent;
- _suggestions = _parent.WhenAnyValue(x => x.Suggestions)
- .ToProperty(this, x => x.Suggestions);
-
- _restrictInputToSuggestions = _parent.WhenAnyValue(x => x.RestrictInputToSuggestions)
- .ToProperty(this, x => x.RestrictInputToSuggestions);
-
- _isInputEnabled = _parent.Tags
- .ToObservableChangeSet()
- .ToCollection()
- .Where(x => _parent.TagCountLimit > 0)
- .Select(x => x.Count < _parent.TagCountLimit)
- .ToProperty(this, x => x.IsInputEnabled, true);
-
- CommitTextAction += OnCommitTextAction;
- BackspaceAndEmptyTextAction += OnBackspaceAndEmptyTextAction;
- }
-
- public IEnumerable Suggestions => _suggestions.Value;
- public bool RestrictInputToSuggestions => _restrictInputToSuggestions.Value;
- public bool IsInputEnabled => _isInputEnabled.Value;
-
- public Action<string> CommitTextAction
- {
- get => _commitTextAction;
- set => this.RaiseAndSetIfChanged(ref _commitTextAction, value);
- }
-
- public Action BackspaceAndEmptyTextAction
- {
- get => _backspaceAndEmptyTextAction;
- set => this.RaiseAndSetIfChanged(ref _backspaceAndEmptyTextAction, value);
- }
-
- public Action GrabFocusAction
- {
- get => _grabFocusAction;
- set => this.RaiseAndSetIfChanged(ref _grabFocusAction, value);
- }
-
-
- private void OnBackspaceAndEmptyTextAction()
- {
- _parent.RemoveTag();
- }
-
- private void OnCommitTextAction(string tagString)
- {
- _parent.AddTag(tagString);
- }
- }
-}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/ViewModels/TagsBox/TagsBoxViewModel.cs
WalletWasabi.Fluent/ViewModels/TagsBox/TagsBoxViewModel.cs
@@ -29,27 +29,8 @@ namespace WalletWasabi.Fluent.ViewModels.TagsBox
public TagsBoxViewModel()
{
_tags = new ObservableCollection<TagViewModel>();
-
- TagInput = new TagInputViewModel(this);
-
- var list = new SourceList<object>();
- list.Add(TagInput);
-
- GrabFocusCommand = ReactiveCommand.Create((object x) =>
- {
- TagInput?.GrabFocusAction?.Invoke();
- return new object();
- });
-
- AddTag("Test1");
- AddTag("Test2");
- AddTag("Test3");
- AddTag("Test4");
- AddTag("Test5");
}
- public TagInputViewModel TagInput { get; }
-
public bool RestrictInputToSuggestions
{
get => _restrictInputToSuggestions;
@@ -83,20 +64,5 @@ namespace WalletWasabi.Fluent.ViewModels.TagsBox
get => _tags;
set => this.RaiseAndSetIfChanged(ref _tags, value);
}
-
- public ReactiveCommand<object, object> GrabFocusCommand { get; }
-
- public void AddTag(string tagString)
- {
- Tags.Add(new TagViewModel(this, tagString));
- }
-
- public void RemoveTag()
- {
- if (Tags.Any())
- {
- Tags.Remove(Tags.Last());
- }
- }
}
}
\ No newline at end of file

MODIFY
WalletWasabi.Fluent/Views/RecoveryPageView.axaml
WalletWasabi.Fluent/Views/RecoveryPageView.axaml
Margin="44 0">
<Grid RowDefinitions="Auto,20,Auto" VerticalAlignment="Top" >
<Label Classes="h7 bold" Content="_Type in your recovery words here:" Target="seedTagsBox"/>
- <c:TagsBox x:Name="seedTagsBox" Grid.Row="2"
+ <c:TagsBox x:Name="seedTagsBox" Grid.Row="2" ItemCountLimit="7"
DataContext="{Binding RecoveryWordsTagsBox}"
Items="{Binding Tags}"
Suggestions="{Binding Suggestions, Mode=TwoWay}"

DELETE
WalletWasabi.Fluent/Views/TagsBox/TagInputView.xaml
-<UserControl xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:vm="clr-namespace:WalletWasabi.Fluent.ViewModels.TagsBox"
- mc:Ignorable="d"
- xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
- xmlns:behaviors="clr-namespace:WalletWasabi.Fluent.Behaviors;assembly=WalletWasabi.Fluent"
- x:Class="WalletWasabi.Fluent.Views.TagsBox.TagInputView">
- <AutoCompleteBox x:DataType="vm:TagInputViewModel" IsTextCompletionEnabled="True" Items="{CompiledBinding Suggestions}">
-
- </AutoCompleteBox>
-</UserControl>
\ No newline at end of file

DELETE
WalletWasabi.Fluent/Views/TagsBox/TagInputView.xaml.cs
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-namespace WalletWasabi.Fluent.Views.TagsBox
-{
- public class TagInputView : UserControl
- {
- public TagInputView()
- {
- InitializeComponent();
- }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
- }
-}
\ No newline at end of file

make things functional again pt. 2