Skip to content
Open
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
41 changes: 29 additions & 12 deletions FluentFlyoutWPF/Pages/TaskbarWidgetPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,0,24">
<Border CornerRadius="10" ClipToBounds="True" Width="164" Height="98">
Expand Down Expand Up @@ -116,7 +117,23 @@
<ComboBoxItem Content="{DynamicResource PositionBottomRight}" />
</ComboBox>
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetSelectedMonitorTitleCard" Tag="Indexable" Grid.Row="5" Icon="{ui:SymbolIcon ProjectionScreen24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetLeftMarginTitleCard" Tag="Indexable" Grid.Row="5" Icon="{ui:SymbolIcon PaddingLeft24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetLeftMarginTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
<TextBlock Text="{DynamicResource TaskbarWidgetLeftMarginDescription}" FontSize="12" Opacity="0.5" />
</StackPanel>
</ui:CardControl.Header>
<StackPanel Orientation="Horizontal">
<ui:TextBox Width="60" ClearButtonEnabled="False" Text="{Binding TaskbarWidgetLeftMarginText, Mode=TwoWay}"
IsEnabled="{Binding TaskbarWidgetUseCustomLeftMargin}" />
<TextBlock Text="{DynamicResource PixelsUnit}" FontSize="14" FontWeight="Regular" Margin="10,0,0,0" VerticalAlignment="Center"
IsEnabled="{Binding TaskbarWidgetUseCustomLeftMargin}" />
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetUseCustomLeftMargin, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" Margin="16,0,0,0" />
</StackPanel>
</ui:CardControl>

<ui:CardControl x:Name="TaskbarWidgetSelectedMonitorTitleCard" Tag="Indexable" Grid.Row="6" Icon="{ui:SymbolIcon ProjectionScreen24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetSelectedMonitorTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -127,7 +144,7 @@
</ui:CardControl>

<!-- Padding settings -->
<ui:CardExpander x:Name="TaskbarWidgetPaddingSettingsCard" Tag="Indexable" Grid.Row="6" Icon="{ui:SymbolIcon Wrench24}" ContentPadding="0" Margin="0,0,0,12">
<ui:CardExpander x:Name="TaskbarWidgetPaddingSettingsCard" Tag="Indexable" Grid.Row="7" Icon="{ui:SymbolIcon Wrench24}" ContentPadding="0" Margin="0,0,0,12">
<ui:CardExpander.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetPaddingSettingsTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand Down Expand Up @@ -181,7 +198,7 @@
</StackPanel>
</ui:CardExpander>

<ui:CardControl x:Name="TaskbarWidgetBackgroundBlurTitleCard" Tag="Indexable" Grid.Row="7" Icon="{ui:SymbolIcon ColorBackground24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetBackgroundBlurTitleCard" Tag="Indexable" Grid.Row="8" Icon="{ui:SymbolIcon ColorBackground24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetBackgroundBlurTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -190,7 +207,7 @@
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetBackgroundBlur, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetHideCompletelyTitleCard" Tag="Indexable" Grid.Row="8" Icon="{ui:SymbolIcon EyeOff24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetHideCompletelyTitleCard" Tag="Indexable" Grid.Row="9" Icon="{ui:SymbolIcon EyeOff24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetHideCompletelyTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -199,7 +216,7 @@
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetHideCompletely, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetFixedWidthTitleCard" Tag="Indexable" Grid.Row="9" Icon="{ui:SymbolIcon ArrowAutofitWidth24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetFixedWidthTitleCard" Tag="Indexable" Grid.Row="10" Icon="{ui:SymbolIcon ArrowAutofitWidth24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
Expand All @@ -210,7 +227,7 @@
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetFixedWidth, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetAutoHideTitleCard" Tag="Indexable" Grid.Row="10" Icon="{ui:SymbolIcon EyeLines24}" Margin="0,0,0,12">
<ui:CardControl x:Name="TaskbarWidgetAutoHideTitleCard" Tag="Indexable" Grid.Row="11" Icon="{ui:SymbolIcon EyeLines24}" Margin="0,0,0,12">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetAutoHideTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -219,7 +236,7 @@
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetAutoHide, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetControlsTitleCard" Tag="Indexable" Grid.Row="11" Icon="{ui:SymbolIcon VideoPlayPause24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetControlsTitleCard" Tag="Indexable" Grid.Row="12" Icon="{ui:SymbolIcon VideoPlayPause24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetControlsTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -228,7 +245,7 @@
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetControlsEnabled, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>
<ui:CardControl x:Name="TaskbarWidgetControlsPositionTitleCard" Tag="Indexable" Grid.Row="12" Icon="{ui:SymbolIcon ArrowMove24}" Margin="0,0,0,12">
<ui:CardControl x:Name="TaskbarWidgetControlsPositionTitleCard" Tag="Indexable" Grid.Row="13" Icon="{ui:SymbolIcon ArrowMove24}" Margin="0,0,0,12">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetControlsPositionTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -241,7 +258,7 @@
</ComboBox>
</ui:CardControl>

<ui:CardControl x:Name="TaskbarWidgetScrollVolumeTitleCard" Tag="Indexable" Grid.Row="15" Icon="{ui:SymbolIcon Speaker224}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetScrollVolumeTitleCard" Tag="Indexable" Grid.Row="16" Icon="{ui:SymbolIcon Speaker224}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
Expand All @@ -258,7 +275,7 @@
</ComboBox>
</ui:CardControl>

<ui:CardExpander x:Name="TaskbarWidgetScrollingTextCard" Tag="Indexable" Grid.Row="14" Icon="{ui:SymbolIcon TextDirectionHorizontalRight24}" ContentPadding="0" Margin="0,0,0,12">
<ui:CardExpander x:Name="TaskbarWidgetScrollingTextCard" Tag="Indexable" Grid.Row="15" Icon="{ui:SymbolIcon TextDirectionHorizontalRight24}" ContentPadding="0" Margin="0,0,0,12">
<ui:CardExpander.Header>
<Grid ColumnDefinitions="*, Auto">
<StackPanel Orientation="Vertical">
Expand Down Expand Up @@ -295,7 +312,7 @@
</StackPanel>
</ui:CardExpander>

<ui:CardControl x:Name="TaskbarWidgetAnimatedTitleCard" Tag="Indexable" Grid.Row="13" Icon="{ui:SymbolIcon Wand24}" Margin="0,0,0,3">
<ui:CardControl x:Name="TaskbarWidgetAnimatedTitleCard" Tag="Indexable" Grid.Row="14" Icon="{ui:SymbolIcon Wand24}" Margin="0,0,0,3">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetAnimatedTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand All @@ -305,7 +322,7 @@
<ui:ToggleSwitch IsChecked="{Binding TaskbarWidgetAnimated, Mode=TwoWay}" IsEnabled="{Binding IsPremiumUnlocked}" />
</ui:CardControl>

<ui:CardControl x:Name="TaskbarWidgetShowPauseOverlayTitleCard" Tag="Indexable" Grid.Row="16" Icon="{ui:SymbolIcon Pause24}" Margin="0,0,0,76">
<ui:CardControl x:Name="TaskbarWidgetShowPauseOverlayTitleCard" Tag="Indexable" Grid.Row="17" Icon="{ui:SymbolIcon Pause24}" Margin="0,0,0,76">
<ui:CardControl.Header>
<StackPanel Orientation="Vertical">
<TextBlock Text="{DynamicResource TaskbarWidgetShowPauseOverlayTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
Expand Down
2 changes: 2 additions & 0 deletions FluentFlyoutWPF/Resources/Localization/Dictionary-en-US.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ hides repeat, shuffle and player info</System:String>
<System:String x:Key="TaskbarWidgetBackgroundBlurDescription">Add background blur effect to the taskbar widget</System:String>
<System:String x:Key="TaskbarWidgetHideCompletelyTitle">Hide Completely When No Media Is Present</System:String>
<System:String x:Key="TaskbarWidgetHideCompletelyDescription">Hides the entire widget when no media is available, instead of displaying a media icon</System:String>
<System:String x:Key="TaskbarWidgetLeftMarginTitle">Left Margin</System:String>
<System:String x:Key="TaskbarWidgetLeftMarginDescription">Distance from the left edge of the taskbar (top edge on a vertical taskbar). Overrides the position and automatic padding settings; the unit is device independent pixels</System:String>
<System:String x:Key="TaskbarWidgetFixedWidthTitle">Fixed Widget Width</System:String>
<System:String x:Key="TaskbarWidgetFixedWidthDescription">Keep the widget at a fixed width instead of resizing to fit the title and artist text</System:String>
<System:String x:Key="TaskbarWidgetAutoHideTitle">Autohide Widget</System:String>
Expand Down
52 changes: 52 additions & 0 deletions FluentFlyoutWPF/ViewModels/UserSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using FluentFlyout.Classes.Settings;
using FluentFlyout.Classes.Utils;
using FluentFlyout.Controls;
using FluentFlyout.Windows;
using FluentFlyoutWPF.Classes;
using FluentFlyoutWPF.Models;
using FluentFlyoutWPF.Windows;
Expand Down Expand Up @@ -434,6 +435,43 @@ public string TaskbarWidgetManualPaddingText
[ObservableProperty]
public partial bool TaskbarWidgetFixedWidth { get; set; }

/// <summary>
/// Gets or sets whether the widget is positioned by <see cref="TaskbarWidgetLeftMargin"/> instead of the
/// widget position / automatic padding settings (only used when the position is "near start").
/// </summary>
[ObservableProperty]
public partial bool TaskbarWidgetUseCustomLeftMargin { get; set; }

/// <summary>
/// Distance of the taskbar widget from the start of the taskbar (left edge, or top edge on a vertical
/// taskbar) in device independent pixels, used when <see cref="TaskbarWidgetUseCustomLeftMargin"/> is enabled.
/// </summary>
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(TaskbarWidgetLeftMarginText))]
public partial int TaskbarWidgetLeftMargin { get; set; }

/// <summary>
/// Text representation of <see cref="TaskbarWidgetLeftMargin"/> for the settings text box.
/// </summary>
[XmlIgnore]
public string TaskbarWidgetLeftMarginText
{
get => TaskbarWidgetLeftMargin.ToString();
set
{
if (int.TryParse(value, out var result))
{
TaskbarWidgetLeftMargin = Math.Clamp(result, TaskbarWindow.MinCustomLeftMargin, TaskbarWindow.MaxCustomLeftMargin);
}
else
{
TaskbarWidgetLeftMargin = 20;
}

OnPropertyChanged();
}
}

/// <summary>
/// Gets or sets a value indicating whether the pause icon overlay should be completely hidden from view.
/// </summary>
Expand Down Expand Up @@ -752,6 +790,8 @@ public UserSettings()
TaskbarWidgetBackgroundBlur = false;
TaskbarWidgetHideCompletely = false;
TaskbarWidgetFixedWidth = false;
TaskbarWidgetUseCustomLeftMargin = false;
TaskbarWidgetLeftMargin = 20;
TaskbarWidgetShowPauseOverlay = true;
TaskbarWidgetControlsEnabled = false;
TaskbarWidgetControlsPosition = 1;
Expand Down Expand Up @@ -926,6 +966,18 @@ partial void OnTaskbarWidgetFixedWidthChanged(bool oldValue, bool newValue)
UpdateTaskbar();
}

partial void OnTaskbarWidgetUseCustomLeftMarginChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue || _initializing) return;
UpdateTaskbar();
}

partial void OnTaskbarWidgetLeftMarginChanged(int oldValue, int newValue)
{
if (oldValue == newValue || _initializing) return;
UpdateTaskbar();
}

partial void OnTaskbarWidgetShowPauseOverlayChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue || _initializing) return;
Expand Down
20 changes: 20 additions & 0 deletions FluentFlyoutWPF/Windows/TaskbarWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public partial class TaskbarWindow : Window

private const double SmallTaskbarDetectionThreshold = 40;

// limits for TaskbarWidgetLeftMargin (device independent pixels)
public const int MinCustomLeftMargin = 0;
public const int MaxCustomLeftMargin = 2000;

private readonly DispatcherTimer _timer;
private readonly int _nativeWidgetsPadding = 216;
private readonly double _scale = 0.9;
Expand Down Expand Up @@ -486,6 +490,15 @@ private Rect PositionWidget(IntPtr taskbarHandle, RECT taskbarRect, double dpiSc
switch (SettingsManager.Current.TaskbarWidgetPosition)
{
case 0: // near start (left for horizontal, top for vertical)
// custom left margin: place the widget's left edge (top edge on a vertical taskbar)
// at exactly the configured distance from the start of the taskbar
if (SettingsManager.Current.TaskbarWidgetUseCustomLeftMargin)
{
primaryPos = (int)(Math.Clamp(SettingsManager.Current.TaskbarWidgetLeftMargin,
MinCustomLeftMargin, MaxCustomLeftMargin) * dpiScale);
break;
}

primaryPos = 20;

if (SettingsManager.Current.TaskbarVisualizerEnabled && SettingsManager.Current.TaskbarVisualizerPosition == 0)
Expand Down Expand Up @@ -684,6 +697,13 @@ private Rect PositionVisualizer(IntPtr taskbarHandle, RECT taskbarRect, double d
break;
}

// with a small custom left margin the visualizer would be pushed off the start of the taskbar,
// so keep it on screen by placing it after the widget instead
if (primaryPos < 0)
{
primaryPos = (int)(widgetPrimaryStart * dpiScale) + (int)(Widget.Width * dpiScale);
}

// Set visualizer position within canvas
// primaryPos → left (horizontal) or top (vertical); crossPos → top (horizontal) or left (vertical)
Canvas.SetLeft(TaskbarVisualizer, (isVertical ? crossPos : primaryPos) / dpiScale);
Expand Down
Loading