Skip to content

Commit

Permalink
Moved tools under categories, changed the title showed in Search box,…
Browse files Browse the repository at this point in the history
… added a page that show a group of tools, improved icons render (#107)
  • Loading branch information
veler committed Dec 11, 2021
1 parent 865c7b6 commit cad69e6
Show file tree
Hide file tree
Showing 165 changed files with 2,333 additions and 518 deletions.
26 changes: 21 additions & 5 deletions src/dev/impl/DevToys/Api/Tools/IToolProvider.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
#nullable enable

using System.ComponentModel;
using DevToys.Core.Threading;
using Windows.UI.Xaml.Controls;

namespace DevToys.Api.Tools
{
/// <summary>
/// Provides information about a tool and create an instance of it.
/// </summary>
public interface IToolProvider : INotifyPropertyChanged
public interface IToolProvider
{
/// <summary>
/// Gets the name of the tool. It will be displayed in the list of tools.
/// Gets the name of the tool that will be displayed in the main menu of the app.
/// </summary>
string DisplayName { get; }
string MenuDisplayName { get; }

/// <summary>
/// Gets the name of the tool that will be displayed in the search bar. Sometimes
/// it is needed to have a different one than the name showed in the menu to increase
/// result accuracy. For example, while <see cref="MenuDisplayName"/> could be "JSON"
/// for a tool that is under the Formatter category, <see cref="SearchDisplayName"/>
/// could be "JSON Formatter", which can be helpful to differentiate from other similar
/// tools like "JSON Converter".
/// </summary>
string? SearchDisplayName { get; }

/// <summary>
/// Gets the description of the tool that will be displayed in the tool grid view.
/// </summary>
string? Description { get; }

/// <summary>
/// Gets the name of the tool that will be told to the user when using screen reader.
Expand All @@ -22,7 +38,7 @@ public interface IToolProvider : INotifyPropertyChanged
/// <summary>
/// Gets an object type that has a width, height and image data. It can be an icon through a font, an SVG...etc.
/// </summary>
object IconSource { get; }
TaskCompletionNotifier<IconElement> IconSource { get; }

/// <summary>
/// Creates a new instance of the tool.
Expand Down
5 changes: 5 additions & 0 deletions src/dev/impl/DevToys/Api/Tools/IToolProviderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public interface IToolProviderFactory
/// </summary>
IEnumerable<MatchedToolProvider> GetAllTools();

/// <summary>
/// Gets a flat list of all the children and sub-children of a given tool provider.
/// </summary>
IEnumerable<IToolProvider> GetAllChildrenTools(IToolProvider toolProvider);

/// <summary>
/// Gets the list of tools available that have the <see cref="IsFooterItemAttribute"/>.
/// </summary>
Expand Down
46 changes: 37 additions & 9 deletions src/dev/impl/DevToys/Api/Tools/MatchedToolProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ public class MatchedToolProvider : INotifyPropertyChanged
{
private readonly List<MatchedToolProvider> _childrenTools = new();
private MatchSpan[] _matchedSpans = Array.Empty<MatchSpan>();
private bool _isBeingProgrammaticallySelected;

/// <summary>
/// Gets the tool provider.
/// </summary>
public IToolProvider ToolProvider { get; }

/// <summary>
/// Gets or sets the list of spans that matched the search in the <see cref="IToolProvider.DisplayName"/>.
/// Gets or sets the list of spans that matched the search in the <see cref="IToolProvider.SearchDisplayName"/>.
/// </summary>
public MatchSpan[] MatchedSpans
{
Expand All @@ -36,13 +37,15 @@ public MatchSpan[] MatchedSpans
_matchedSpans = value;
ThreadHelper.RunOnUIThreadAsync(() =>
{
RaisePropertyChanged(nameof(AnyMatchedSpan));
RaisePropertyChanged(nameof(MatchedSpans));
}).Forget();
}
}

public bool AnyMatchedSpan => MatchedSpans.Length > 0;
/// <summary>
/// Gets or sets the total amount of match in after a search (which can be different from <see cref="MatchedSpans"/>).
/// </summary>
public int TotalMatchCount { get; set; }

/// <summary>
/// Gets the metadata of the tool provider.
Expand Down Expand Up @@ -70,9 +73,11 @@ public IReadOnlyList<MatchedToolProvider> ChildrenTools
}
}

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

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

public event PropertyChangedEventHandler? PropertyChanged;

Expand Down Expand Up @@ -103,24 +108,47 @@ internal void AddChildTool(MatchedToolProvider child)

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

child.PropertyChanged += Child_PropertyChanged;
}

internal IDisposable ForceMenuItemShouldBeExpanded()
{
// Notify that parents menu item should be expanded if they're not yet.
_isBeingProgrammaticallySelected = true;
RaisePropertyChanged(nameof(MenuItemShouldBeExpanded));
return new SelectMenuItemProgrammaticallyResult(this);
}

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

protected void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

private class SelectMenuItemProgrammaticallyResult : IDisposable
{
private readonly MatchedToolProvider _matchedToolProvider;

public SelectMenuItemProgrammaticallyResult(MatchedToolProvider matchedToolProvider)
{
_matchedToolProvider = matchedToolProvider;
}

public void Dispose()
{
_matchedToolProvider._isBeingProgrammaticallySelected = false;
}
}
}
}
15 changes: 15 additions & 0 deletions src/dev/impl/DevToys/Assets/Icons/Base64.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/dev/impl/DevToys/Assets/Icons/Guid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/dev/impl/DevToys/Assets/Icons/HtmlEncoder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/dev/impl/DevToys/Assets/Icons/JWT.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/dev/impl/DevToys/Assets/Icons/JsonFormatter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit cad69e6

Please sign in to comment.