mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
Add a new image provider for `MarkdownTextBlock` that allows loading
images from additional sources:
- **file scheme**
- Enables loading images using the `file:` scheme.
- Intentionally restricts file URIs to absolute paths to ensure correct
resolution when passed through the CmdPal extension/host boundary. (In
most cases, 3rd-party extensions will provide the paths, but the CmdPal
host performs the actual loading and would otherwise resolve paths
relative to itself.)
- **data scheme**
- Enables loading images from URIs with the `data:` scheme (both Base64
and URL-encoded forms).
- Note: the Markdown control itself cannot handle large input and may
hang before the code introduced in this PR is invoked.
- **ms-appx scheme**
- This scheme is now supported for loading images.
- However, since the Command Palette host performs the loading,
`ms-appx:` resolution applies to the host and not the extensions, which
limits its usefulness.
- **ms-appdata scheme**
- This scheme is now supported for loading images.
- Similar to `ms-appx:`, resolution applies to the host, not the
extensions, limiting its usefulness.
---
Additionally, this PR introduces the concept of **_image source
hints_**, implemented as query string parameters piggy-backed on the
original URI.
These hints allow users to influence the behavior of images within
Markdown content.
- `--x-cmdpal-fit`
- `none`: no automatic scaling, provides image as is (default)
- `fit`: scale to fit the available space
- `--x-cmdpal-upscale`
- `true`: allow upscaling
- `false`: downscale only (default)
- `--x-cmdpal-width`: desired width in pixels
- `--x-cmdpal-height`: desired height in pixels
- `--x-cmdpal-maxwidth`: max width in pixels
- `--x-cmdpal-maxheight`: max height in pixels
---
Since `MarkdownTextBlock` requires conforming to the `IImageProvider`
interface—which accepts only a raw URI and must return an `Image`
control—this PR also introduces a new class `RtbInlineImageFactory`.
The factory hooks into the root text block upon loading and listens for
events related to **layout** and **DPI changes**, ensuring that images
adapt correctly to the control’s environment.
```csharp
public interface IImageProvider
{
Task<Image> GetImage(string url);
bool ShouldUseThisProvider(string url);
}
```
---
Pictures? Videos!
Loading images from new schemes:
https://github.com/user-attachments/assets/e0f4308d-30b2-4c81-86db-353048c708c1
New image source scaling options:
https://github.com/user-attachments/assets/ec5b007d-3140-4f0a-b163-7b278233ad40
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #41752
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Michael Jolley <mike@baldbeardedbuilder.com>
126 lines
5.9 KiB
XML
126 lines
5.9 KiB
XML
<?xml version="1.0" encoding="utf-8" ?>
|
|
<Page
|
|
x:Class="Microsoft.CmdPal.UI.ContentPage"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
|
|
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
|
|
xmlns:cmdPalControls="using:Microsoft.CmdPal.UI.Controls"
|
|
xmlns:cmdpalUI="using:Microsoft.CmdPal.UI"
|
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
|
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
|
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:local="using:Microsoft.CmdPal.UI"
|
|
xmlns:markdownImageProviders="using:Microsoft.CmdPal.UI.Helpers.MarkdownImageProviders"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
|
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
|
Background="Transparent"
|
|
mc:Ignorable="d">
|
|
|
|
<Page.Resources>
|
|
<ResourceDictionary>
|
|
<tkcontrols:MarkdownThemes
|
|
x:Key="DefaultMarkdownThemeConfig"
|
|
H3FontSize="12"
|
|
H3FontWeight="Normal" />
|
|
<markdownImageProviders:ImageProvider x:Key="ImageProvider" />
|
|
<tkcontrols:MarkdownConfig
|
|
x:Key="DefaultMarkdownConfig"
|
|
ImageProvider="{StaticResource ImageProvider}"
|
|
Themes="{StaticResource DefaultMarkdownThemeConfig}" />
|
|
|
|
<StackLayout
|
|
x:Name="VerticalStackLayout"
|
|
Orientation="Vertical"
|
|
Spacing="8" />
|
|
|
|
<cmdpalUI:ContentTemplateSelector
|
|
x:Key="ContentTemplateSelector"
|
|
FormTemplate="{StaticResource FormContentTemplate}"
|
|
MarkdownTemplate="{StaticResource MarkdownContentTemplate}"
|
|
TreeTemplate="{StaticResource TreeContentTemplate}" />
|
|
<cmdpalUI:ContentTemplateSelector
|
|
x:Key="NestedContentTemplateSelector"
|
|
FormTemplate="{StaticResource NestedFormContentTemplate}"
|
|
MarkdownTemplate="{StaticResource NestedMarkdownContentTemplate}"
|
|
TreeTemplate="{StaticResource TreeContentTemplate}" />
|
|
|
|
<DataTemplate x:Key="FormContentTemplate" x:DataType="viewModels:ContentFormViewModel">
|
|
<Grid Margin="0,4,4,4" Padding="12,8,8,8">
|
|
<cmdPalControls:ContentFormControl ViewModel="{x:Bind}" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
|
|
<DataTemplate x:Key="MarkdownContentTemplate" x:DataType="viewModels:ContentMarkdownViewModel">
|
|
<Grid Margin="0,4,4,4" Padding="12,8,8,8">
|
|
<tkcontrols:MarkdownTextBlock
|
|
Config="{StaticResource DefaultMarkdownConfig}"
|
|
Text="{x:Bind Body, Mode=OneWay}"
|
|
UseEmphasisExtras="True"
|
|
UsePipeTables="True" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
|
|
<DataTemplate x:Key="NestedFormContentTemplate" x:DataType="viewModels:ContentFormViewModel">
|
|
<Grid>
|
|
<cmdPalControls:ContentFormControl ViewModel="{x:Bind}" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
|
|
<DataTemplate x:Key="NestedMarkdownContentTemplate" x:DataType="viewModels:ContentMarkdownViewModel">
|
|
<Grid>
|
|
<tkcontrols:MarkdownTextBlock Config="{StaticResource DefaultMarkdownConfig}" Text="{x:Bind Body, Mode=OneWay}" />
|
|
</Grid>
|
|
</DataTemplate>
|
|
|
|
<DataTemplate x:Key="TreeContentTemplate" x:DataType="viewModels:ContentTreeViewModel">
|
|
<StackPanel
|
|
Margin="0,4,4,4"
|
|
Padding="12,8,8,8"
|
|
Orientation="Vertical">
|
|
<ItemsRepeater
|
|
Margin="8"
|
|
VerticalAlignment="Stretch"
|
|
ItemsSource="{x:Bind Root, Mode=OneWay}"
|
|
Layout="{StaticResource VerticalStackLayout}">
|
|
<ItemsRepeater.ItemTemplate>
|
|
<cmdpalUI:ContentTemplateSelector
|
|
FormTemplate="{StaticResource NestedFormContentTemplate}"
|
|
MarkdownTemplate="{StaticResource NestedMarkdownContentTemplate}"
|
|
TreeTemplate="{StaticResource TreeContentTemplate}" />
|
|
</ItemsRepeater.ItemTemplate>
|
|
</ItemsRepeater>
|
|
|
|
<ItemsRepeater
|
|
Margin="8"
|
|
VerticalAlignment="Stretch"
|
|
ItemsSource="{x:Bind Children, Mode=OneWay}"
|
|
Layout="{StaticResource VerticalStackLayout}"
|
|
Visibility="{x:Bind HasChildren, Mode=OneWay}">
|
|
<ItemsRepeater.ItemTemplate>
|
|
<cmdpalUI:ContentTemplateSelector
|
|
FormTemplate="{StaticResource FormContentTemplate}"
|
|
MarkdownTemplate="{StaticResource MarkdownContentTemplate}"
|
|
TreeTemplate="{StaticResource TreeContentTemplate}" />
|
|
</ItemsRepeater.ItemTemplate>
|
|
</ItemsRepeater>
|
|
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
|
|
</ResourceDictionary>
|
|
</Page.Resources>
|
|
<Grid>
|
|
<ScrollView VerticalAlignment="Top" VerticalScrollMode="Enabled">
|
|
<ItemsRepeater
|
|
VerticalAlignment="Stretch"
|
|
ItemTemplate="{StaticResource ContentTemplateSelector}"
|
|
ItemsSource="{x:Bind ViewModel.Content, Mode=OneWay}"
|
|
Layout="{StaticResource VerticalStackLayout}" />
|
|
</ScrollView>
|
|
</Grid>
|
|
|
|
</Page>
|