mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-04-03 05:56:25 +00:00
Add bubble hint to guide users to review the selected changes after clicking Default Mode button (#519)
This commit is contained in:
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -77,7 +77,7 @@ Win11Debloat/
|
|||||||
2. **Document Changes**: Update the `README.md` and other relevant documentation. Wiki documentation will be generated/updated based on the `Features.json` and `Apps.json` files.
|
2. **Document Changes**: Update the `README.md` and other relevant documentation. Wiki documentation will be generated/updated based on the `Features.json` and `Apps.json` files.
|
||||||
3. **Follow Existing Patterns**: Look at existing implementations for guidance.
|
3. **Follow Existing Patterns**: Look at existing implementations for guidance.
|
||||||
4. **Use Clear Naming**: Choose descriptive names for features, IDs, and registry files.
|
4. **Use Clear Naming**: Choose descriptive names for features, IDs, and registry files.
|
||||||
5. **Minimal Changes**: Registry files should only modify what's necessary.
|
5. **Minimal Changes**: Registry files should only modify what's necessary. Avoid using policies where possible.
|
||||||
6. **Comment Your Code**: Add comments explaining your reasoning for complex logic in PowerShell scripts.
|
6. **Comment Your Code**: Add comments explaining your reasoning for complex logic in PowerShell scripts.
|
||||||
7. **Version Constraints**: Use `MinVersion` and `MaxVersion` if a feature only applies to specific Windows versions.
|
7. **Version Constraints**: Use `MinVersion` and `MaxVersion` if a feature only applies to specific Windows versions.
|
||||||
8. **Limit pull requests to 1 feature**: Keep pull requests limited to just one feature, this makes it easier to review your changes.
|
8. **Limit pull requests to 1 feature**: Keep pull requests limited to just one feature, this makes it easier to review your changes.
|
||||||
|
|||||||
41
Schemas/BubbleHint.xaml
Normal file
41
Schemas/BubbleHint.xaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Name="BubblePanel"
|
||||||
|
SnapsToDevicePixels="True">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Border Name="BubbleBorder"
|
||||||
|
Grid.Row="0"
|
||||||
|
Background="{DynamicResource CardBgColor}"
|
||||||
|
BorderBrush="{DynamicResource ButtonBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="8"
|
||||||
|
Padding="10,7,10,7">
|
||||||
|
<TextBlock Name="BubbleText"
|
||||||
|
Text="View the selected changes here"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
MaxWidth="260"
|
||||||
|
Foreground="{DynamicResource FgColor}"/>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Grid Grid.Row="1"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,-1,0,0"
|
||||||
|
Width="12"
|
||||||
|
Height="8">
|
||||||
|
<Polygon Name="BubblePointer"
|
||||||
|
Points="0,0 12,0 6,7"
|
||||||
|
Fill="{DynamicResource CardBgColor}"
|
||||||
|
Stroke="{DynamicResource ButtonBorderColor}"
|
||||||
|
StrokeThickness="1"
|
||||||
|
Stretch="Fill"/>
|
||||||
|
|
||||||
|
<Rectangle VerticalAlignment="Top"
|
||||||
|
Height="2"
|
||||||
|
Margin="1,-1,1,0"
|
||||||
|
Fill="{DynamicResource CardBgColor}"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
@@ -988,7 +988,7 @@
|
|||||||
|
|
||||||
<!-- Review & Apply Section -->
|
<!-- Review & Apply Section -->
|
||||||
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" Background="{DynamicResource BgColor}">
|
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" Background="{DynamicResource BgColor}">
|
||||||
<Button x:Name="ReviewChangesBtn" Background="Transparent" BorderThickness="0" Cursor="Hand" HorizontalAlignment="Center" Margin="0,4,0,8" AutomationProperties.Name="Review selected changes">
|
<Button x:Name="ReviewChangesBtn" Background="Transparent" BorderThickness="0" Cursor="Hand" HorizontalAlignment="Center" Margin="0,4,0,10" AutomationProperties.Name="Review selected changes">
|
||||||
<Button.Template>
|
<Button.Template>
|
||||||
<ControlTemplate TargetType="Button">
|
<ControlTemplate TargetType="Button">
|
||||||
<TextBlock x:Name="LinkText" Text="Review selected changes" FontSize="14" Foreground="{DynamicResource ButtonBg}" FontWeight="SemiBold" HorizontalAlignment="Center"/>
|
<TextBlock x:Name="LinkText" Text="Review selected changes" FontSize="14" Foreground="{DynamicResource ButtonBg}" FontWeight="SemiBold" HorizontalAlignment="Center"/>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Title="MessageBox"
|
Title="MessageBox"
|
||||||
Width="440"
|
Width="440"
|
||||||
SizeToContent="Height"
|
SizeToContent="Height"
|
||||||
MaxHeight="500"
|
MaxHeight="501"
|
||||||
ResizeMode="NoResize"
|
ResizeMode="NoResize"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
WindowStyle="None"
|
WindowStyle="None"
|
||||||
|
|||||||
115
Scripts/GUI/Show-Bubble.ps1
Normal file
115
Scripts/GUI/Show-Bubble.ps1
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
function Hide-Bubble {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[switch]$Immediate
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($script:BubbleTimer) {
|
||||||
|
$script:BubbleTimer.Stop()
|
||||||
|
$script:BubbleTimer = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $script:BubblePopup) { return }
|
||||||
|
|
||||||
|
if ($Immediate -or -not $script:BubblePopup.Child) {
|
||||||
|
$script:BubblePopup.IsOpen = $false
|
||||||
|
$script:BubblePopup = $null
|
||||||
|
$script:BubbleIsClosing = $false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($script:BubbleIsClosing) { return }
|
||||||
|
$script:BubbleIsClosing = $true
|
||||||
|
|
||||||
|
$bubblePanel = $script:BubblePopup.Child
|
||||||
|
$fadeOut = New-Object System.Windows.Media.Animation.DoubleAnimation
|
||||||
|
$fadeOut.From = [double]$bubblePanel.Opacity
|
||||||
|
$fadeOut.To = 0
|
||||||
|
$fadeOut.Duration = [System.Windows.Duration]::new([TimeSpan]::FromMilliseconds(220))
|
||||||
|
$fadeOut.Add_Completed({
|
||||||
|
if ($script:BubblePopup) {
|
||||||
|
$script:BubblePopup.IsOpen = $false
|
||||||
|
$script:BubblePopup = $null
|
||||||
|
}
|
||||||
|
$script:BubbleIsClosing = $false
|
||||||
|
})
|
||||||
|
|
||||||
|
$bubblePanel.BeginAnimation([System.Windows.UIElement]::OpacityProperty, $fadeOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Show-Bubble {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[System.Windows.Controls.Control]$TargetControl,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$Message = 'View the selected changes here',
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[int]$DurationSeconds = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase | Out-Null
|
||||||
|
|
||||||
|
if (-not $TargetControl) { return }
|
||||||
|
|
||||||
|
Hide-Bubble -Immediate
|
||||||
|
|
||||||
|
$xaml = Get-Content -Path $script:BubbleHintSchema -Raw
|
||||||
|
$reader = [System.Xml.XmlReader]::Create([System.IO.StringReader]::new($xaml))
|
||||||
|
try {
|
||||||
|
$bubblePanel = [System.Windows.Markup.XamlReader]::Load($reader)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$reader.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
$bubbleText = $bubblePanel.FindName('BubbleText')
|
||||||
|
if ($bubbleText) {
|
||||||
|
$bubbleText.Text = $Message
|
||||||
|
}
|
||||||
|
|
||||||
|
$bubblePanel.BeginAnimation([System.Windows.UIElement]::OpacityProperty, $null)
|
||||||
|
$bubblePanel.Opacity = 0
|
||||||
|
|
||||||
|
$popup = New-Object System.Windows.Controls.Primitives.Popup
|
||||||
|
$popup.AllowsTransparency = $true
|
||||||
|
$popup.PopupAnimation = 'None'
|
||||||
|
$popup.StaysOpen = $true
|
||||||
|
$popup.PlacementTarget = $TargetControl
|
||||||
|
$popup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Top
|
||||||
|
$popup.VerticalOffset = -1
|
||||||
|
$popup.Child = $bubblePanel
|
||||||
|
|
||||||
|
$popup.Add_Opened({
|
||||||
|
param($sender, $e)
|
||||||
|
|
||||||
|
if (-not $sender) { return }
|
||||||
|
$panel = $sender.Child
|
||||||
|
$target = $sender.PlacementTarget
|
||||||
|
if (-not $panel -or -not $target) { return }
|
||||||
|
|
||||||
|
$panel.Measure([System.Windows.Size]::new([double]::PositiveInfinity, [double]::PositiveInfinity))
|
||||||
|
$bubbleWidth = $panel.DesiredSize.Width
|
||||||
|
$targetWidth = $target.ActualWidth
|
||||||
|
$sender.HorizontalOffset = ($targetWidth - $bubbleWidth) / 2
|
||||||
|
|
||||||
|
$fadeIn = New-Object System.Windows.Media.Animation.DoubleAnimation
|
||||||
|
$fadeIn.From = 0
|
||||||
|
$fadeIn.To = 1
|
||||||
|
$fadeIn.BeginTime = [TimeSpan]::FromMilliseconds(30)
|
||||||
|
$fadeIn.Duration = [System.Windows.Duration]::new([TimeSpan]::FromMilliseconds(320))
|
||||||
|
$panel.BeginAnimation([System.Windows.UIElement]::OpacityProperty, $fadeIn)
|
||||||
|
})
|
||||||
|
|
||||||
|
$script:BubbleIsClosing = $false
|
||||||
|
$script:BubblePopup = $popup
|
||||||
|
$script:BubblePopup.IsOpen = $true
|
||||||
|
|
||||||
|
$script:BubbleTimer = New-Object System.Windows.Threading.DispatcherTimer
|
||||||
|
$script:BubbleTimer.Interval = [TimeSpan]::FromSeconds([Math]::Max(1, $DurationSeconds))
|
||||||
|
$script:BubbleTimer.Add_Tick({
|
||||||
|
Hide-Bubble
|
||||||
|
})
|
||||||
|
$script:BubbleTimer.Start()
|
||||||
|
}
|
||||||
@@ -1208,6 +1208,7 @@ function Show-MainWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$previousBtn.Add_Click({
|
$previousBtn.Add_Click({
|
||||||
|
Hide-Bubble -Immediate
|
||||||
if ($tabControl.SelectedIndex -gt 0) {
|
if ($tabControl.SelectedIndex -gt 0) {
|
||||||
$tabControl.SelectedIndex--
|
$tabControl.SelectedIndex--
|
||||||
UpdateNavigationButtons
|
UpdateNavigationButtons
|
||||||
@@ -1249,11 +1250,17 @@ function Show-MainWindow {
|
|||||||
# Navigate directly to the Deployment Settings tab
|
# Navigate directly to the Deployment Settings tab
|
||||||
$tabControl.SelectedIndex = 3
|
$tabControl.SelectedIndex = 3
|
||||||
UpdateNavigationButtons
|
UpdateNavigationButtons
|
||||||
|
|
||||||
|
# Show contextual hint bubble for the Review Changes link
|
||||||
|
$window.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Loaded, [action]{
|
||||||
|
Show-Bubble -TargetControl $reviewChangesBtn -Message 'View the selected changes here'
|
||||||
|
}) | Out-Null
|
||||||
})
|
})
|
||||||
|
|
||||||
# Handle Review Changes link button
|
# Handle Review Changes link button
|
||||||
$reviewChangesBtn = $window.FindName('ReviewChangesBtn')
|
$reviewChangesBtn = $window.FindName('ReviewChangesBtn')
|
||||||
$reviewChangesBtn.Add_Click({
|
$reviewChangesBtn.Add_Click({
|
||||||
|
Hide-Bubble
|
||||||
ShowChangesOverview
|
ShowChangesOverview
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1265,6 +1272,8 @@ function Show-MainWindow {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hide-Bubble -Immediate
|
||||||
|
|
||||||
# App Removal - collect selected apps from integrated UI
|
# App Removal - collect selected apps from integrated UI
|
||||||
$selectedApps = @()
|
$selectedApps = @()
|
||||||
foreach ($child in $appsPanel.Children) {
|
foreach ($child in $appsPanel.Children) {
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ $script:MessageBoxSchema = "$PSScriptRoot/Schemas/MessageBoxWindow.xaml"
|
|||||||
$script:AboutWindowSchema = "$PSScriptRoot/Schemas/AboutWindow.xaml"
|
$script:AboutWindowSchema = "$PSScriptRoot/Schemas/AboutWindow.xaml"
|
||||||
$script:ApplyChangesWindowSchema = "$PSScriptRoot/Schemas/ApplyChangesWindow.xaml"
|
$script:ApplyChangesWindowSchema = "$PSScriptRoot/Schemas/ApplyChangesWindow.xaml"
|
||||||
$script:SharedStylesSchema = "$PSScriptRoot/Schemas/SharedStyles.xaml"
|
$script:SharedStylesSchema = "$PSScriptRoot/Schemas/SharedStyles.xaml"
|
||||||
|
$script:BubbleHintSchema = "$PSScriptRoot/Schemas/BubbleHint.xaml"
|
||||||
|
|
||||||
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
||||||
|
|
||||||
@@ -167,7 +168,7 @@ else {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check if script has all required files
|
# Check if script has all required files
|
||||||
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:BubbleHintSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
||||||
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
||||||
Write-Output ""
|
Write-Output ""
|
||||||
Write-Output "Press any key to exit..."
|
Write-Output "Press any key to exit..."
|
||||||
@@ -253,6 +254,7 @@ if (-not $script:WingetInstalled -and -not $Silent) {
|
|||||||
. "$PSScriptRoot/Scripts/GUI/Show-AppSelectionWindow.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-AppSelectionWindow.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-MainWindow.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-MainWindow.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-AboutDialog.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-AboutDialog.ps1"
|
||||||
|
. "$PSScriptRoot/Scripts/GUI/Show-Bubble.ps1"
|
||||||
|
|
||||||
# Load File I/O functions
|
# Load File I/O functions
|
||||||
. "$PSScriptRoot/Scripts/FileIO/LoadJsonFile.ps1"
|
. "$PSScriptRoot/Scripts/FileIO/LoadJsonFile.ps1"
|
||||||
|
|||||||
Reference in New Issue
Block a user