mirror of
https://github.com/MaxiFan/TunnelX.git
synced 2026-05-17 21:14:37 +03:00
Improve tab headers, theme styling, and tray notifications
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+27
-12
@@ -6,8 +6,8 @@
|
||||
xmlns:vm="clr-namespace:AppTunnel.ViewModels"
|
||||
xmlns:model="clr-namespace:AppTunnel.Models"
|
||||
Title="TunnelX — Split Traffic Per App"
|
||||
Width="580" Height="760"
|
||||
MinWidth="540" MinHeight="680"
|
||||
Width="620" Height="760"
|
||||
MinWidth="580" MinHeight="680"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowStyle="None"
|
||||
AllowsTransparency="True"
|
||||
@@ -169,30 +169,42 @@
|
||||
<TabControl Grid.Row="0" Style="{StaticResource ModernTabControl}" Margin="8,6,8,6">
|
||||
|
||||
<!-- ███ TAB 1: CONNECTION ███ -->
|
||||
<TabItem Style="{StaticResource ModernTabItem}">
|
||||
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="وضعیت اتصال VPN و کنترل اتصال">
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="⚡ اتصال"/>
|
||||
<StackPanel>
|
||||
<TextBlock Text="⚡" FontSize="13" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="اتصال VPN" FontSize="10" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<views:ConnectionTabView/>
|
||||
</TabItem>
|
||||
<TabItem Style="{StaticResource ModernTabItem}">
|
||||
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="انتخاب برنامههایی که باید از تونل عبور کنند">
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="📱 برنامهها"/>
|
||||
<StackPanel>
|
||||
<TextBlock Text="📱" FontSize="13" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="برنامهها" FontSize="10" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<views:AppsTabView/>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Style="{StaticResource ModernTabItem}">
|
||||
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="تنظیمات عمومی تونل و DNS">
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="⚙ تنظیمات"/>
|
||||
<StackPanel>
|
||||
<TextBlock Text="⚙" FontSize="13" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="تنظیمات" FontSize="10" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<views:SettingsTabView/>
|
||||
</TabItem>
|
||||
|
||||
<!-- ███ TAB 3: ROUTING RULES ███ -->
|
||||
<TabItem Style="{StaticResource ModernTabItem}">
|
||||
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="قوانین Include و Exclude مسیرها">
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="🧭 قوانین مسیر"/>
|
||||
<StackPanel>
|
||||
<TextBlock Text="🧭" FontSize="13" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="قوانین مسیر" FontSize="10" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0,12,0,0">
|
||||
@@ -424,9 +436,12 @@
|
||||
</TabItem>
|
||||
|
||||
<!-- ███ TAB 5: TRAFFIC MONITOR ███ -->
|
||||
<TabItem Style="{StaticResource ModernTabItem}">
|
||||
<TabItem Style="{StaticResource ModernTabItem}" ToolTip="نمایش ترافیک، تاریخچه و آمار اتصال">
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="📊 ترافیک"/>
|
||||
<StackPanel>
|
||||
<TextBlock Text="📊" FontSize="13" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="ترافیک/تاریخچه" FontSize="9.5" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0,12,0,0">
|
||||
|
||||
@@ -150,8 +150,8 @@ public partial class MainWindow : Window
|
||||
_trayIcon.Visible = true;
|
||||
_trayIcon.ShowBalloonTip(
|
||||
2000,
|
||||
"TunnelX",
|
||||
"برنامه در System Tray فعال است. برای نمایش دوبار کلیک کنید.",
|
||||
"TunnelX در پسزمینه فعال است",
|
||||
"برای باز کردن پنجره، روی آیکن کنار ساعت دوبار کلیک کنید.",
|
||||
System.Windows.Forms.ToolTipIcon.Info);
|
||||
}
|
||||
}
|
||||
@@ -167,15 +167,15 @@ public partial class MainWindow : Window
|
||||
switch (state)
|
||||
{
|
||||
case ConnectionState.Connected:
|
||||
ShowTrayNotification("TunnelX متصل شد", _viewModel.StatusText,
|
||||
ShowTrayNotification("تونل فعال شد", GetConnectedTrayMessage(),
|
||||
System.Windows.Forms.ToolTipIcon.Info);
|
||||
break;
|
||||
case ConnectionState.Disconnected:
|
||||
ShowTrayNotification("TunnelX قطع شد", _viewModel.StatusText,
|
||||
ShowTrayNotification("تونل خاموش شد", "ارتباط امن متوقف شده و ترافیک دیگر از TunnelX عبور نمیکند.",
|
||||
System.Windows.Forms.ToolTipIcon.Info);
|
||||
break;
|
||||
case ConnectionState.Error:
|
||||
ShowTrayNotification("خطا در اتصال TunnelX", _viewModel.StatusText,
|
||||
ShowTrayNotification("اتصال برقرار نشد", GetErrorTrayMessage(),
|
||||
System.Windows.Forms.ToolTipIcon.Warning);
|
||||
break;
|
||||
}
|
||||
@@ -187,11 +187,31 @@ public partial class MainWindow : Window
|
||||
return;
|
||||
|
||||
_updateNotificationShown = true;
|
||||
ShowTrayNotification("بروزرسانی TunnelX آماده است",
|
||||
_viewModel.UpdateStatusText,
|
||||
ShowTrayNotification("نسخه جدید آماده است",
|
||||
"از منوی System Tray یا بخش بروزرسانی، صفحه دانلود TunnelX را باز کنید.",
|
||||
System.Windows.Forms.ToolTipIcon.Info);
|
||||
}
|
||||
|
||||
private string GetConnectedTrayMessage()
|
||||
{
|
||||
var profileName = _viewModel.SelectedProfileName;
|
||||
if (!string.IsNullOrWhiteSpace(profileName))
|
||||
return $"پروفایل «{profileName}» فعال است و ترافیک انتخابشده از تونل عبور میکند.";
|
||||
|
||||
return "ترافیک انتخابشده از TunnelX عبور میکند.";
|
||||
}
|
||||
|
||||
private string GetErrorTrayMessage()
|
||||
{
|
||||
var status = _viewModel.StatusText?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(status) || status == "خطا")
|
||||
return "جزئیات خطا را در پنجره برنامه یا لاگها بررسی کنید.";
|
||||
|
||||
return status.StartsWith("خطا", StringComparison.Ordinal)
|
||||
? status
|
||||
: $"جزئیات: {status}";
|
||||
}
|
||||
|
||||
private void ShowTrayNotification(string title, string message, System.Windows.Forms.ToolTipIcon icon)
|
||||
{
|
||||
if (_trayIcon == null) return;
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
<!-- Tab header bar with bottom border -->
|
||||
<Border Grid.Row="0" Background="{StaticResource SurfaceBrush}"
|
||||
BorderBrush="{StaticResource BorderBrush}" BorderThickness="0,0,0,1"
|
||||
Padding="4,0">
|
||||
Padding="6,6,6,4">
|
||||
<TabPanel IsItemsHost="True" HorizontalAlignment="Center"/>
|
||||
</Border>
|
||||
<!-- Tab content -->
|
||||
@@ -282,16 +282,22 @@
|
||||
<Style x:Key="ModernTabItem" TargetType="TabItem">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource TextSecondaryBrush}"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="Padding" Value="14,10"/>
|
||||
<Setter Property="FontSize" Value="10"/>
|
||||
<Setter Property="FontWeight" Value="Normal"/>
|
||||
<Setter Property="Padding" Value="6,6"/>
|
||||
<Setter Property="Width" Value="104"/>
|
||||
<Setter Property="MinHeight" Value="50"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TabItem">
|
||||
<Border x:Name="border"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Margin="2,0">
|
||||
Margin="2,0,2,2">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
@@ -300,29 +306,33 @@
|
||||
<ContentPresenter Grid.Row="0" ContentSource="Header"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,4"/>
|
||||
Margin="0,0,0,5"/>
|
||||
<!-- Bottom indicator line -->
|
||||
<Border x:Name="indicator" Grid.Row="1"
|
||||
Height="2.5" CornerRadius="1.5"
|
||||
Height="3" CornerRadius="1.5"
|
||||
Background="Transparent"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="6,0"/>
|
||||
Margin="10,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter TargetName="border" Property="Background" Value="#1FE8803A"/>
|
||||
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource PrimaryBrush}"/>
|
||||
<Setter TargetName="indicator" Property="Background" Value="{StaticResource PrimaryBrush}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="border" Property="Background" Value="#0AFFFFFF"/>
|
||||
<Setter TargetName="border" Property="Background" Value="#10FFFFFF"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsSelected" Value="True"/>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter TargetName="border" Property="Background" Value="#0AFFFFFF"/>
|
||||
<Setter TargetName="border" Property="Background" Value="#29E8803A"/>
|
||||
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource PrimaryBrush}"/>
|
||||
</MultiTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
Reference in New Issue
Block a user