Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions WinUIGallery/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ private async void EnsureWindow()
targetPageType = typeof(ItemPage);
}
}
// Handle JumpList launch arguments (passed as command-line args)
else if (eventArgs != null &&
eventArgs.Kind == ExtendedActivationKind.Launch &&
eventArgs.Data is ILaunchActivatedEventArgs launchArgs &&
!string.IsNullOrEmpty(launchArgs.Arguments))
{
string arg = launchArgs.Arguments.Trim();
targetPageArguments = arg;

if (ControlInfoDataSource.Instance.Groups.Any(g => g.UniqueId == arg))
{
targetPageType = typeof(SectionPage);
}
else if (ControlInfoDataSource.Instance.Groups.Any(g => g.Items.Any(i => i.UniqueId == arg)))
{
targetPageType = typeof(ItemPage);
}
}

MainWindow.Navigate(targetPageType, targetPageArguments);

Expand All @@ -149,6 +167,9 @@ private async void EnsureWindow()
navItem.IsSelected = true;
}

// Initialize the taskbar JumpList with fixed tasks and favorites.
await JumpListHelper.UpdateJumpListAsync();

// Activate the startup window.
MainWindow.Activate();
}
Expand Down
Binary file added WinUIGallery/Assets/ControlImages/JumpList.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 17 additions & 17 deletions WinUIGallery/Controls/PageHeader.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="using:WinUIGallery.Models"
xmlns:local="using:WinUIGallery.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:WinUIGallery.Models"
Loaded="UserControl_Loaded"
mc:Ignorable="d">

Expand All @@ -34,11 +34,11 @@
<StackPanel Orientation="Horizontal" Spacing="4">
<TextBlock
AutomationProperties.AutomationId="PageHeader"
AutomationProperties.HeadingLevel="Level1"
Style="{StaticResource TitleTextBlockStyle}"
Text="{x:Bind Item.Title}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"
AutomationProperties.HeadingLevel="Level1" />
TextWrapping="NoWrap" />
<Button
x:Name="APIDetailsBtn"
Margin="0,0,0,3"
Expand Down Expand Up @@ -153,10 +153,10 @@
Text="Control source code" />
<Button
Padding="6,5,6,6"
Style="{ThemeResource SubtleButtonStyle}"
ToolTipService.ToolTip="{x:Bind GetControlSourceInfoText(), Mode=OneWay}"
AutomationProperties.HelpText="{x:Bind GetControlSourceInfoText(), Mode=OneWay}"
AutomationProperties.Name="Info"
AutomationProperties.HelpText="{x:Bind GetControlSourceInfoText(), Mode=OneWay}">
Style="{ThemeResource SubtleButtonStyle}"
ToolTipService.ToolTip="{x:Bind GetControlSourceInfoText(), Mode=OneWay}">
<FontIcon
VerticalAlignment="Center"
FontSize="14"
Expand All @@ -174,7 +174,7 @@
</HyperlinkButton>
</StackPanel>

<MenuFlyoutSeparator Margin="-12" />
<MenuFlyoutSeparator x:Name="ControlSourceSeparator" Margin="-12" />

<StackPanel
Margin="0,8,0,0"
Expand All @@ -187,10 +187,10 @@
Text="Sample page source code" />
<Button
Padding="6,5,6,6"
Style="{ThemeResource SubtleButtonStyle}"
ToolTipService.ToolTip="{x:Bind GetSamplePageSourceInfoText(), Mode=OneWay}"
AutomationProperties.HelpText="{x:Bind GetSamplePageSourceInfoText(), Mode=OneWay}"
AutomationProperties.Name="Info"
AutomationProperties.HelpText="{x:Bind GetSamplePageSourceInfoText(), Mode=OneWay}">
Style="{ThemeResource SubtleButtonStyle}"
ToolTipService.ToolTip="{x:Bind GetSamplePageSourceInfoText(), Mode=OneWay}">
<FontIcon
VerticalAlignment="Center"
FontSize="14"
Expand Down Expand Up @@ -272,14 +272,14 @@
</Button.Content>
</Button>
<AppBarSeparator />
<ToggleButton x:Name="FavoriteButton"
Height="32"
Margin="4,0,0,0"
Click="FavoriteButton_Click"
AutomationProperties.Name="Favorite sample">
<ToggleButton
x:Name="FavoriteButton"
Height="32"
Margin="4,0,0,0"
AutomationProperties.Name="Favorite sample"
Click="FavoriteButton_Click">
<ToggleButton.Content>
<FontIcon FontSize="16"
Glyph="{x:Bind GetFavoriteGlyph(FavoriteButton.IsChecked), Mode=OneWay}" />
<FontIcon FontSize="16" Glyph="{x:Bind GetFavoriteGlyph(FavoriteButton.IsChecked), Mode=OneWay}" />
</ToggleButton.Content>
<ToolTipService.ToolTip>
<ToolTip Content="{x:Bind GetFavoriteToolTip(FavoriteButton.IsChecked), Mode=OneWay}" />
Expand Down
2 changes: 2 additions & 0 deletions WinUIGallery/Controls/PageHeader.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ public void SetControlSourceLink(string BaseUri, string SourceLink)
if (!string.IsNullOrEmpty(SourceLink))
{
ControlSourcePanel.Visibility = Visibility.Visible;
ControlSourceSeparator.Visibility = Visibility.Visible;
ControlSourceLink.NavigateUri = new Uri(BaseUri + SourceLink);
}
else
{
ControlSourcePanel.Visibility = Visibility.Collapsed;
ControlSourceSeparator.Visibility = Visibility.Collapsed;
}

}
Expand Down
74 changes: 74 additions & 0 deletions WinUIGallery/Helpers/JumpListHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI.StartScreen;
using WinUIGallery.Models;

namespace WinUIGallery.Helpers;

/// <summary>
/// Manages the app's taskbar JumpList, providing quick access to
/// recently visited items and user-favorited items.
/// </summary>
internal static class JumpListHelper
{
/// <summary>
/// Rebuilds the JumpList with recently visited items and the current set of favorite items.
/// Safe to call at any time; silently returns if JumpList is not supported.
/// </summary>
public static async Task UpdateJumpListAsync()
{
if (!NativeMethods.IsAppPackaged || !JumpList.IsSupported())
{
return;
}

try
{
JumpList jumpList = await JumpList.LoadCurrentAsync();
jumpList.Items.Clear();
jumpList.SystemGroupKind = JumpListSystemGroupKind.None;

// Dynamic group: Recent
var recentlyVisited = SettingsHelper.Current.RecentlyVisited;
foreach (string uniqueId in recentlyVisited)
{
AddItemTask(jumpList, uniqueId, groupName: "Recent");
}

// Dynamic group: Favorites
var favorites = SettingsHelper.Current.Favorites;
foreach (string uniqueId in favorites)
{
AddItemTask(jumpList, uniqueId, groupName: "Favorites");
}

await jumpList.SaveAsync();
}
catch
{
// JumpList updates are best-effort; don't crash the app.
}
}

private static void AddItemTask(JumpList jumpList, string uniqueId, string groupName)
{
ControlInfoDataItem? item = ControlInfoDataSource.Instance.Groups
.SelectMany(g => g.Items)
.FirstOrDefault(i => i.UniqueId == uniqueId);

if (item == null)
{
return;
}

JumpListItem task = JumpListItem.CreateWithArguments(uniqueId, item.Title);
task.GroupName = groupName;
task.Description = "Go to " + item.Title;
task.Logo = new Uri(item.ImagePath);
jumpList.Items.Add(task);
}
}
2 changes: 2 additions & 0 deletions WinUIGallery/Helpers/SettingsHelper/SettingsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ public void UpdateFavorites(Action<List<string>> updater)
var list = Favorites;
updater(list);
Favorites = list;
_ = JumpListHelper.UpdateJumpListAsync();
}
public void UpdateRecentlyVisited(Action<List<string>> updater)
{
var list = RecentlyVisited;
updater(list);
RecentlyVisited = list;
_ = JumpListHelper.UpdateJumpListAsync();
}
}
67 changes: 67 additions & 0 deletions WinUIGallery/Samples/ControlPages/JumpListPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="WinUIGallery.ControlPages.JumpListPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:controls="using:WinUIGallery.Controls"
mc:Ignorable="d">

<StackPanel>
<InfoBar Margin="0,10,0,0" IsOpen="True" IsClosable="False" Severity="Warning"
Title="JumpList is not available in unpackaged mode."
Message="This API requires the app to be running in packaged mode (MSIX)."/>

<TextBlock Margin="0,12,0,0" TextWrapping="Wrap" Style="{StaticResource BodyTextBlockStyle}"
Text="WinUI Gallery populates its jump list with your recently visited and favorited items. Restarting the app will restore these entries after any changes made on this page." />

<controls:ControlExample HeaderText="Adding tasks to the jump list">
<StackPanel Spacing="8">
<TextBlock TextWrapping="Wrap"
Text="Tasks are items with an empty GroupName. They appear in the built-in 'Tasks' section at the bottom of the jump list. Use tasks for common app-wide actions that are always relevant, such as composing a new message or opening settings. Each task launches the app with a specific argument string that your app can handle on startup." />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Add sample tasks"
Style="{StaticResource AccentButtonStyle}"
Click="AddTasksButton_Click" />
<Button Content="Clear all items"
Click="ClearTasksButton_Click" />
</StackPanel>
</StackPanel>
<controls:ControlExample.CSharp>
<x:String xml:space="preserve">
var jumpList = await JumpList.LoadCurrentAsync();

var task = JumpListItem.CreateWithArguments("/compose", "New Message");
task.Description = "Compose a new message";
task.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

jumpList.Items.Add(task);
await jumpList.SaveAsync();
</x:String>
</controls:ControlExample.CSharp>
</controls:ControlExample>

<controls:ControlExample HeaderText="Adding items to a custom group">
<StackPanel Spacing="8">
<TextBlock TextWrapping="Wrap"
Text="Custom groups let you organize jump list items into named sections. Set the GroupName property to a non-empty string and all items sharing the same GroupName will appear together under that heading. This is useful for grouping related items like recent projects, pinned documents, or user-defined categories." />
<Button Content="Add custom group items"
Click="AddCustomGroupButton_Click" />
</StackPanel>
<controls:ControlExample.CSharp>
<x:String xml:space="preserve">
var jumpList = await JumpList.LoadCurrentAsync();

var item = JumpListItem.CreateWithArguments("/project-alpha", "Project Alpha");
item.GroupName = "Projects";
item.Description = "Open Project Alpha";
item.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

jumpList.Items.Add(item);
await jumpList.SaveAsync();
</x:String>
</controls:ControlExample.CSharp>
</controls:ControlExample>
</StackPanel>
</Page>
78 changes: 78 additions & 0 deletions WinUIGallery/Samples/ControlPages/JumpListPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using Windows.UI.StartScreen;
using WinUIGallery.Helpers;

namespace WinUIGallery.ControlPages;

public sealed partial class JumpListPage : Page
{
public JumpListPage()
{
this.InitializeComponent();
}

private async void AddTasksButton_Click(object sender, RoutedEventArgs e)
{
if (!NativeMethods.IsAppPackaged)
{
return;
}

JumpList jumpList = await JumpList.LoadCurrentAsync();

JumpListItem composeTask = JumpListItem.CreateWithArguments("/compose", "New Message");
composeTask.Description = "Compose a new message";
composeTask.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

JumpListItem searchTask = JumpListItem.CreateWithArguments("/search", "Search");
searchTask.Description = "Search for items";
searchTask.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

jumpList.Items.Add(composeTask);
jumpList.Items.Add(searchTask);

await jumpList.SaveAsync();
}

private async void ClearTasksButton_Click(object sender, RoutedEventArgs e)
{
if (!NativeMethods.IsAppPackaged)
{
return;
}

JumpList jumpList = await JumpList.LoadCurrentAsync();
jumpList.Items.Clear();
await jumpList.SaveAsync();
}

private async void AddCustomGroupButton_Click(object sender, RoutedEventArgs e)
{
if (!NativeMethods.IsAppPackaged)
{
return;
}

JumpList jumpList = await JumpList.LoadCurrentAsync();

JumpListItem item1 = JumpListItem.CreateWithArguments("/project-alpha", "Project Alpha");
item1.GroupName = "Projects";
item1.Description = "Open Project Alpha";
item1.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

JumpListItem item2 = JumpListItem.CreateWithArguments("/project-beta", "Project Beta");
item2.GroupName = "Projects";
item2.Description = "Open Project Beta";
item2.Logo = new Uri("ms-appx:///Assets/Tiles/AppList.targetsize-48.png");

jumpList.Items.Add(item1);
jumpList.Items.Add(item2);

await jumpList.SaveAsync();
}
}
Loading