add a photo picker

This commit is contained in:
Mike Griese
2025-09-15 06:15:00 -05:00
parent bcc30fc85d
commit bd2dc3af05
3 changed files with 67 additions and 22 deletions

View File

@@ -13,6 +13,7 @@ using Windows.AI.Actions;
using Windows.AI.Actions.Hosting;
using Windows.ApplicationModel.Contacts;
using Windows.Storage;
using Windows.Storage.Pickers;
namespace Microsoft.CmdPal.Ext.Actions;
@@ -42,8 +43,8 @@ internal sealed partial class ActionsTestPage : ListPage
foreach (var action in actions)
{
var overloads = action.GetOverloads();
var overloadsTxt = string.Join("\n\t", overloads.Select(o => o.DescriptionTemplate));
actionsDebug += $"{action.Id}: {action.Description}\n\t{overloadsTxt}\n";
var overloadsTxt = string.Join("\n", overloads.Select(o => $" - {o.DescriptionTemplate}"));
actionsDebug += $"* `{action.Id}`: {action.Description}\n{overloadsTxt}\n";
}
Logger.LogDebug(actionsDebug);
@@ -118,20 +119,7 @@ public partial class DoActionPage : ParametersPage
var inputs = action.GetInputs();
foreach (var input in inputs)
{
IParameterRun param = input.Kind switch
{
ActionEntityKind.None => new LabelRun(input.Name),
ActionEntityKind.Document => new FilePickerParameterRun() { PlaceholderText = input.Name },
ActionEntityKind.File => new FilePickerParameterRun() { PlaceholderText = input.Name },
ActionEntityKind.Photo => new FilePickerParameterRun() { PlaceholderText = input.Name },
ActionEntityKind.Text => new StringParameterRun(input.Name),
// ActionEntityKind.StreamingText => new CommandParameter(input.Name, input.Required, ParameterType.StreamingText),
// ActionEntityKind.RemoteFile => new CommandParameter(input.Name, input.Required, ParameterType.RemoteFile),
// ActionEntityKind.Table => new CommandParameter(input.Name, input.Required, ParameterType.Table),
ActionEntityKind.Contact => new StringParameterRun(input.Name),
_ => throw new NotSupportedException($"Unsupported action entity kind: {input.Kind}"),
};
var param = GetParameter(input);
_parameters.Add(param);
if (param is ParameterValueRun p)
@@ -146,6 +134,25 @@ public partial class DoActionPage : ParametersPage
public override IListItem Command => new ListItem(_command) { Title = _overload.DescriptionTemplate };
public override IParameterRun[] Parameters => _parameters.ToArray();
internal static IParameterRun GetParameter(ActionEntityRegistrationInfo input)
{
IParameterRun param = input.Kind switch
{
ActionEntityKind.None => new LabelRun(input.Name),
ActionEntityKind.Document => new FilePickerParameterRun() { PlaceholderText = input.Name },
ActionEntityKind.File => new FilePickerParameterRun() { PlaceholderText = input.Name },
ActionEntityKind.Photo => new PhotoFilePicker() { PlaceholderText = input.Name },
ActionEntityKind.Text => new StringParameterRun(input.Name),
// ActionEntityKind.StreamingText => new CommandParameter(input.Name, input.Required, ParameterType.StreamingText),
// ActionEntityKind.RemoteFile => new CommandParameter(input.Name, input.Required, ParameterType.RemoteFile),
// ActionEntityKind.Table => new CommandParameter(input.Name, input.Required, ParameterType.Table),
ActionEntityKind.Contact => new StringParameterRun(input.Name),
_ => throw new NotSupportedException($"Unsupported action entity kind: {input.Kind}"),
};
return param;
}
}
public partial class DoActionCommand : InvokableCommand
@@ -232,7 +239,7 @@ public partial class DoActionCommand : InvokableCommand
_actionParams = parameters;
}
private ActionEntity CreateEntity(ActionEntityRegistrationInfo i, ActionEntityFactory f, object value)
private static ActionEntity CreateEntity(ActionEntityRegistrationInfo i, ActionEntityFactory f, object value)
{
var input = value switch
{
@@ -257,7 +264,7 @@ public partial class DoActionCommand : InvokableCommand
return v;
}
private ContactActionEntity CreateContact(string? text, ActionEntityFactory f)
private static ContactActionEntity CreateContact(string? text, ActionEntityFactory f)
{
var contact = new Contact();
var email = new ContactEmail();
@@ -267,6 +274,22 @@ public partial class DoActionCommand : InvokableCommand
}
}
internal sealed partial class PhotoFilePicker : FilePickerParameterRun
{
protected override void ConfigureFilePicker(object? sender, FileOpenPicker picker)
{
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".gif");
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".tiff");
picker.FileTypeFilter.Add(".webp");
}
}
// [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "meh")]
// public partial class ImageParameter : CommandParameter
// {

View File

@@ -195,7 +195,7 @@ public partial class CommandParameterRun : ParameterValueRun, ICommandParameterR
}
}
internal sealed partial class FilePickerParameterRun : CommandParameterRun
public partial class FilePickerParameterRun : CommandParameterRun
{
public StorageFile? File { get; private set; }
@@ -203,6 +203,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
public override string? DisplayText { get => File != null ? File.DisplayName : "Select a file"; }
public Action<FileOpenPicker>? SetupFilePicker { get; set; }
public FilePickerParameterRun()
{
var command = new FilePickerCommand();
@@ -215,6 +217,7 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
OnPropertyChanged(nameof(NeedsValue));
OnPropertyChanged(nameof(DisplayText));
};
command.RequestCustomizePicker += ConfigureFilePicker;
PlaceholderText = "Select a file";
Icon = new IconInfo("\uE710"); // Add
Command = command;
@@ -233,6 +236,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
public event EventHandler<StorageFile?>? FileSelected;
public event EventHandler<FileOpenPicker>? RequestCustomizePicker;
private nint _hostHwnd;
public void SetHostHwnd(nint hostHwnd)
@@ -249,7 +254,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
private async void PickFileAsync()
{
var picker = new FileOpenPicker() { };
picker.FileTypeFilter.Add("*");
RequestCustomizePicker?.Invoke(this, picker);
// You need to initialize the picker with a window handle in WinUI 3 desktop apps
// See https://learn.microsoft.com/en-us/windows/apps/design/controls/file-open-picker
@@ -259,6 +265,11 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
FileSelected?.Invoke(this, file);
}
}
protected virtual void ConfigureFilePicker(object? sender, FileOpenPicker picker)
{
picker.FileTypeFilter.Add("*");
}
}
public partial class SelectParameterCommand<T> : InvokableCommand

View File

@@ -195,7 +195,7 @@ public partial class CommandParameterRun : ParameterValueRun, ICommandParameterR
}
}
internal sealed partial class FilePickerParameterRun : CommandParameterRun
public partial class FilePickerParameterRun : CommandParameterRun
{
public StorageFile? File { get; private set; }
@@ -203,6 +203,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
public override string? DisplayText { get => File != null ? File.DisplayName : "Select a file"; }
public Action<FileOpenPicker>? SetupFilePicker { get; set; }
public FilePickerParameterRun()
{
var command = new FilePickerCommand();
@@ -215,6 +217,7 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
OnPropertyChanged(nameof(NeedsValue));
OnPropertyChanged(nameof(DisplayText));
};
command.RequestCustomizePicker += ConfigureFilePicker;
PlaceholderText = "Select a file";
Icon = new IconInfo("\uE710"); // Add
Command = command;
@@ -233,6 +236,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
public event EventHandler<StorageFile?>? FileSelected;
public event EventHandler<FileOpenPicker>? RequestCustomizePicker;
private nint _hostHwnd;
public void SetHostHwnd(nint hostHwnd)
@@ -249,7 +254,8 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
private async void PickFileAsync()
{
var picker = new FileOpenPicker() { };
picker.FileTypeFilter.Add("*");
RequestCustomizePicker?.Invoke(this, picker);
// You need to initialize the picker with a window handle in WinUI 3 desktop apps
// See https://learn.microsoft.com/en-us/windows/apps/design/controls/file-open-picker
@@ -259,6 +265,11 @@ internal sealed partial class FilePickerParameterRun : CommandParameterRun
FileSelected?.Invoke(this, file);
}
}
protected virtual void ConfigureFilePicker(object? sender, FileOpenPicker picker)
{
picker.FileTypeFilter.Add("*");
}
}
public partial class SelectParameterCommand<T> : InvokableCommand