Skip to content

Commit

Permalink
Changed the tool infrastructure to make the main menu supporting tree…
Browse files Browse the repository at this point in the history
… nodes. (#104)

* Changed the tool infrastructure to make the main menu supporting tree nodes.

* fixed localized text
  • Loading branch information
veler authored Dec 6, 2021
1 parent 4d77434 commit c70b117
Show file tree
Hide file tree
Showing 27 changed files with 1,316 additions and 284 deletions.
22 changes: 14 additions & 8 deletions src/dev/impl/DevToys/Api/Tools/IToolProviderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@ public interface IToolProviderFactory
IToolViewModel GetToolViewModel(IToolProvider provider);

/// <summary>
/// Gets the list of tools available.
/// Gets a flat list of tools that match the given query.
/// </summary>
/// <param name="searchQuery">If not null or empty, the method will return items that match the given search query and order them.</param>
/// <returns>
/// Returns a list of provider along with an array of parts that matched <paramref name="searchQuery"/>.
/// </returns>
IEnumerable<MatchedToolProvider> GetTools(string? searchQuery);
Task<IEnumerable<MatchedToolProvider>> SearchToolsAsync(string searchQuery);

/// <summary>
/// Gets a hierarchical list of available tools. This does not include footer tools.
/// </summary>
Task<IEnumerable<MatchedToolProvider>> GetToolsTreeAsync();

/// <summary>
/// Gets a flat list containing all the tools available.
/// </summary>
IEnumerable<MatchedToolProvider> GetAllTools();

/// <summary>
/// Gets the list of tools available that have the <see cref="IsFooterItemAttribute"/>.
/// </summary>
IEnumerable<MatchedToolProvider> GetFooterTools();
Task<IEnumerable<MatchedToolProvider>> GetFooterToolsAsync();

/// <summary>
/// Called when the app is shutting down. Asks ever tools to cleanup resources.
/// Called when the app is shutting down. Asks every tools to cleanup resources.
/// </summary>
Task CleanupAsync();
}
Expand Down
71 changes: 69 additions & 2 deletions src/dev/impl/DevToys/Api/Tools/MatchedToolProvider.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using DevToys.Shared.Core.Threading;
using DevToys.Core.Threading;
using DevToys.Shared.Core;
using Windows.UI.Xaml.Controls;
using System.Linq;

namespace DevToys.Api.Tools
{
Expand All @@ -11,6 +17,7 @@ namespace DevToys.Api.Tools
/// </summary>
public class MatchedToolProvider : INotifyPropertyChanged
{
private readonly List<MatchedToolProvider> _childrenTools = new();
private MatchSpan[] _matchedSpans = Array.Empty<MatchSpan>();

/// <summary>
Expand Down Expand Up @@ -39,13 +46,73 @@ public MatchSpan[] MatchedSpans
/// </summary>
public ToolProviderMetadata Metadata { get; }

/// <summary>
/// Gets whether the tool should be highlighted in the UI following a smart detection that the tool could be useful for the user.
/// </summary>
public bool IsRecommended { get; private set; }

public IReadOnlyList<MatchedToolProvider> ChildrenTools
{
get => _childrenTools;
set
{
_childrenTools.Clear();
if (value is not null)
{
foreach (MatchedToolProvider item in value)
{
AddChildTool(item);
}
}
}
}

public bool HasRecommandedChildrenTool => ChildrenTools.Any(item => item.IsRecommended || item.HasRecommandedChildrenTool);

internal TaskCompletionNotifier<IconElement> Icon => (TaskCompletionNotifier<IconElement>)ToolProvider.IconSource;

public event PropertyChangedEventHandler? PropertyChanged;

public MatchedToolProvider(ToolProviderMetadata metadata, IToolProvider toolProvider, MatchSpan[] matchedSpans)
public MatchedToolProvider(ToolProviderMetadata metadata, IToolProvider toolProvider, MatchSpan[]? matchedSpans = null)
{
Metadata = Arguments.NotNull(metadata, nameof(metadata));
ToolProvider = Arguments.NotNull(toolProvider, nameof(toolProvider));
MatchedSpans = Arguments.NotNull(matchedSpans, nameof(matchedSpans));
MatchedSpans = matchedSpans ?? Array.Empty<MatchSpan>();
}

internal async Task UpdateIsRecommendedAsync(string clipboardContent)
{
await TaskScheduler.Default;

IsRecommended = ToolProvider.CanBeTreatedByTool(clipboardContent);

ThreadHelper.RunOnUIThreadAsync(() =>
{
RaisePropertyChanged(nameof(IsRecommended));
}).Forget();
}

internal void AddChildTool(MatchedToolProvider child)
{
Arguments.NotNull(child, nameof(child));

_childrenTools.Add(child);

if (child.IsRecommended)
{
RaisePropertyChanged(nameof(HasRecommandedChildrenTool));
}

child.PropertyChanged += Child_PropertyChanged;
}

private void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if ((e.PropertyName == nameof(IsRecommended) || e.PropertyName == nameof(HasRecommandedChildrenTool))
&& HasRecommandedChildrenTool)
{
RaisePropertyChanged(nameof(HasRecommandedChildrenTool));
}
}

protected void RaisePropertyChanged(string propertyName)
Expand Down
23 changes: 23 additions & 0 deletions src/dev/impl/DevToys/Api/Tools/ParentAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#nullable enable

using System;
using System.Composition;

namespace DevToys.Api.Tools
{
/// <summary>
/// Indicates the parent tool of the current one.
/// The name should corresponds to an existing <see cref="NameAttribute.Name"/> value, or null if no parent.
/// </summary>
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class ParentAttribute : Attribute
{
public string Parent { get; set; }

public ParentAttribute(string? name)
{
Parent = name ?? string.Empty;
}
}
}
6 changes: 6 additions & 0 deletions src/dev/impl/DevToys/Api/Tools/ToolProviderMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ public sealed class ToolProviderMetadata
[DefaultValue("Unnamed")]
public string Name { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the internal non-localized name of the parent provider.
/// </summary>
[DefaultValue("")]
public string Parent { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the order in which this tool should appear.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#nullable enable

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using DevToys.Shared.Core;

namespace DevToys.Core.Collections
{
public class ExtendedObservableCollection<T> : ObservableCollection<T>
{
/// <summary>
/// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
/// </summary>
internal void AddRange(IEnumerable<T> collection)
{
Arguments.NotNull(collection, nameof(collection));

foreach (T item in collection)
{
Items.Add(item);
}

OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
}

This file was deleted.

Loading

0 comments on commit c70b117

Please sign in to comment.