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
43 changes: 4 additions & 39 deletions AppControl Manager/CustomUIElements/InfoBarV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,6 @@ private void InitializeTransforms()
typeof(InfoBarV2),
new PropertyMetadata(1.0, OnScaleToChanged)); // DEFAULT: 1.0

// Default: True - animations enabled
private static readonly DependencyProperty EnableAnimationProperty =
DependencyProperty.Register(
nameof(EnableAnimation),
typeof(bool),
typeof(InfoBarV2),
new PropertyMetadata(true, OnEnableAnimationChanged)); // DEFAULT: True

// Default: Zero delay before animation starts
private static readonly DependencyProperty AnimationDelayProperty =
DependencyProperty.Register(
Expand Down Expand Up @@ -335,12 +327,6 @@ internal double ScaleTo
set => SetValue(ScaleToProperty, value);
}

internal bool EnableAnimation
{
get => (bool)GetValue(EnableAnimationProperty);
set => SetValue(EnableAnimationProperty, value);
}

internal TimeSpan AnimationDelay
{
get => (TimeSpan)GetValue(AnimationDelayProperty);
Expand Down Expand Up @@ -471,18 +457,6 @@ private static void OnScaleToChanged(DependencyObject d, DependencyPropertyChang
}
}

private static void OnEnableAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is InfoBarV2 infoBar && !infoBar._isDisposed && !infoBar._isUnloading)
{
// If animations are disabled, stop any running animations immediately
if (!(bool)e.NewValue)
{
infoBar.StopAllAnimations();
}
}
}

private static void OnAnimationDelayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is InfoBarV2 infoBar && !infoBar._isDisposed && !infoBar._isUnloading)
Expand Down Expand Up @@ -679,9 +653,9 @@ private void InfoBarV2_Closing(InfoBar sender, InfoBarClosingEventArgs args)
return;
}

// Only intercept the close if animations are enabled and we should handle close button clicks
// Only intercept the close if we should handle close button clicks
// The _isHandlingCloseButton flag prevents infinite loops when we set IsOpen=false after animation
if (EnableAnimation && InterceptCloseButton && !_isHandlingCloseButton)
if (InterceptCloseButton && !_isHandlingCloseButton)
{
// Cancel the default close behavior so we can show our custom animation first
args.Cancel = true;
Expand Down Expand Up @@ -722,7 +696,7 @@ private void InfoBarV2_Closed(InfoBar sender, InfoBarClosedEventArgs args)
}

// Update state tracking if InfoBar was closed without my custom animation
if (!_isClosingViaButton && EnableAnimation && !IsOpen && _lastKnownIsOpenState)
if (!_isClosingViaButton && !IsOpen && _lastKnownIsOpenState)
{
_lastKnownIsOpenState = false;
}
Expand Down Expand Up @@ -837,15 +811,6 @@ private void OnIsOpenPropertyChanged(DependencyObject sender, DependencyProperty
bool oldState = _lastKnownIsOpenState;
_lastKnownIsOpenState = newIsOpenValue;

// If animations are disabled, use default InfoBar behavior
if (!EnableAnimation)
{
Visibility = IsOpen ? Visibility.Visible : Visibility.Collapsed;
Opacity = IsOpen ? 1.0 : 0.0;
ResetTransforms();
return;
}

// Enhanced conflict handling: if there's an opposite animation in progress, interrupt it
if (_animationInProgress)
{
Expand Down Expand Up @@ -977,7 +942,7 @@ private void AnimateInfoBarState(bool shouldOpen)
}

/// <summary>
/// Fallback method when animations cannot be created or are disabled.
/// Fallback method when animations cannot be created.
/// Ensures InfoBar still functions correctly without animations.
/// </summary>
private void FallbackToNonAnimatedBehavior(bool shouldOpen)
Expand Down
128 changes: 128 additions & 0 deletions AppControl Manager/CustomUIElements/OpenPortsDialog.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<customUI:ContentDialogV2
x:Class="AppControlManager.CustomUIElements.OpenPortsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppControlManager.CustomUIElements"
xmlns:customUI="using:AppControlManager.CustomUIElements"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
Title="Open Network Ports"
PrimaryButtonText="Close"
DefaultButton="Primary"
Closed="{x:Bind OpenPortsDialog_Closed}">

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Top Bar Controls -->
<controls:WrapPanel Grid.Row="0"
Orientation="Horizontal"
Margin="0,0,0,10"
HorizontalSpacing="8"
VerticalSpacing="5"
HorizontalAlignment="Center"
VerticalAlignment="Top">

<!-- Counts card -->
<Border CornerRadius="8"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Padding="10,6"
BorderThickness="1"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
<StackPanel Orientation="Horizontal" Spacing="6" VerticalAlignment="Center">
<FontIcon Glyph="&#xE8A9;" Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" />
<TextBlock VerticalAlignment="Center">
<Run x:Uid="TotalText" />
<Run Text="{x:Bind DisplayedPorts.Count, Mode=OneWay}" FontWeight="SemiBold" />
</TextBlock>
</StackPanel>
</Border>

<!-- Search Box -->
<TextBox x:Name="SearchBox"
HorizontalAlignment="Center"
Header="Search"
PlaceholderText="Search ports, IPs, states, or protocols..."
TextChanged="{x:Bind ApplyFilterAndSort}"
VerticalAlignment="Center"/>

<!-- Refresh Interval -->
<NumberBox HorizontalAlignment="Center"
Header="Refresh Interval (s)"
Value="5"
Minimum="1"
Maximum="60"
SpinButtonPlacementMode="Inline"
VerticalAlignment="Center"
ValueChanged="{x:Bind RefreshIntervalBox_ValueChanged}"/>

<!-- Auto Refresh Toggle -->
<ToggleSwitch x:Name="AutoRefreshToggle"
HorizontalAlignment="Center"
Header="Auto Refresh"
IsOn="True"
VerticalAlignment="Center"
Toggled="{x:Bind AutoRefreshToggle_Toggled}"/>

</controls:WrapPanel>

<ListView Grid.Row="1"
ItemsSource="{x:Bind DisplayedPorts}"
SelectionMode="None"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.IsHorizontalRailEnabled="True"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ShowsScrollingPlaceholders="True"
ScrollViewer.VerticalScrollBarVisibility="Visible">

<ListView.Header>
<Border CornerRadius="5" Background="Black" customUI:StickyHeaderBehaviorV2.IsEnabled="True">
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="160" />
<ColumnDefinition Width="180" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>

<!-- Sortable Headers -->
<Button Content="Port" Tag="Port" Grid.Column="0" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
<Button Content="Protocol" Tag="Protocol" Grid.Column="1" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
<Button Content="Local Address" Tag="LocalAddress" Grid.Column="2" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
<Button Content="Remote Address" Tag="RemoteAddressAndPort" Grid.Column="3" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
<Button Content="State" Tag="State" Grid.Column="4" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
<Button Content="Process" Tag="Process" Grid.Column="5" Background="Transparent" Foreground="LightGray" FontWeight="Bold" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" BorderThickness="0" Click="HeaderSortingButton_Click" />
</Grid>
</Border>
</ListView.Header>

<ListView.ItemTemplate>
<DataTemplate x:DataType="local:OpenPortItem">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="160" />
<ColumnDefinition Width="180" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>

<TextBlock Text="{x:Bind Port}" Grid.Column="0" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True"/>
<TextBlock Text="{x:Bind Protocol}" Grid.Column="1" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True"/>
<TextBlock Text="{x:Bind LocalAddress}" Grid.Column="2" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind LocalAddress}"/>
<TextBlock Text="{x:Bind RemoteAddressAndPort}" Grid.Column="3" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind RemoteAddressAndPort}"/>
<TextBlock Text="{x:Bind State}" Grid.Column="4" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True"/>
<TextBlock Text="{x:Bind ProcessName}" Grid.Column="5" VerticalAlignment="Center" Margin="5,10,5,10" IsTextSelectionEnabled="True" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind ProcessName}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</customUI:ContentDialogV2>
Loading
Loading