2026-09-26 14:41:04 +03:00
|
|
|
|
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
|
|
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
|
|
|
|
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
2026-09-27 15:24:51 +03:00
|
|
|
|
Title="SbLauncher" Width="1120" Height="790"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
WindowStyle="None" AllowsTransparency="False" Background="{DynamicResource Bg}"
|
|
|
|
|
|
ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
|
|
|
|
|
|
TextOptions.TextFormattingMode="Display"
|
|
|
|
|
|
FontFamily="Segoe UI" UseLayoutRounding="True" SnapsToDevicePixels="True">
|
|
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
|
ТЕМЫ.
|
|
|
|
|
|
Ниже два словаря — Theme.Dark и Theme.Light. Приложение при старте копирует
|
|
|
|
|
|
выбранный в Application.Resources, а весь интерфейс ссылается на токены
|
|
|
|
|
|
через {DynamicResource}. Поэтому смена темы происходит вживую.
|
|
|
|
|
|
|
|
|
|
|
|
ВАЖНО: именно DynamicResource, а не StaticResource — последний берёт
|
|
|
|
|
|
значение один раз при разборе XAML и на подмену палитры не реагирует.
|
|
|
|
|
|
|
|
|
|
|
|
Чтобы добавить цвет: заведите ключ в ОБОИХ словарях и ссылайтесь на него.
|
|
|
|
|
|
-->
|
|
|
|
|
|
<Window.Resources>
|
|
|
|
|
|
<ResourceDictionary>
|
|
|
|
|
|
|
|
|
|
|
|
<ResourceDictionary x:Key="Theme.Dark">
|
|
|
|
|
|
<LinearGradientBrush x:Key="Bg" StartPoint="0,0" EndPoint="1,1">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#101113" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#17191D" Offset="0.5"/>
|
|
|
|
|
|
<GradientStop Color="#1C1F25" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</LinearGradientBrush>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="Panel" Color="#DD1B1E23"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Card" Color="#C0252931"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="CardHover" Color="#D7333944"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="CardSel" Color="#D2354052"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Stroke" Color="#3AADB7C6"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="GlassEdge" Color="#45C3CFDF"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Text" Color="#F1F3F6"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Muted" Color="#A5AFBD"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Accent" Color="#78A9FF"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="AccentHover" Color="#98BEFF"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="AccentDim" Color="#5385DC"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="OnAccent" Color="#101820"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SoftBg" Color="#AA282D36"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SoftHover" Color="#CE353D49"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SwitchTrack" Color="#FF363C46"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SwitchThumb" Color="#F4F6FA"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="BadgeBg" Color="#FF303844"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="PingBg" Color="#A6191D24"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="LogBg" Color="#D214171C"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="LogText" Color="#BECBD9"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollTrack" Color="#182D3540"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollThumb" Color="#706A778B"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollThumbHover" Color="#ACA7B4C7"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="HeroRing" Color="#948BA4C9"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="HeroRingDim" Color="#3D93AACA"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<RadialGradientBrush x:Key="GlowA">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#28687890" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#00687890" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</RadialGradientBrush>
|
|
|
|
|
|
<RadialGradientBrush x:Key="GlowB">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#1C4B6F9C" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#004B6F9C" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</RadialGradientBrush>
|
|
|
|
|
|
<!-- смысловые цвета: их же читает код для статуса и пинга -->
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="Ok" Color="#6BDBAE"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Warn" Color="#E8BF78"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Bad" Color="#F28794"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Idle" Color="#A5AFBD"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Na" Color="#85918E"/>
|
|
|
|
|
|
<sys:Double x:Key="ShadowOpacity">0.35</sys:Double>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</ResourceDictionary>
|
|
|
|
|
|
|
|
|
|
|
|
<ResourceDictionary x:Key="Theme.Light">
|
|
|
|
|
|
<LinearGradientBrush x:Key="Bg" StartPoint="0,0" EndPoint="1,1">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#F3F4F6" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#E8EBEF" Offset="0.5"/>
|
|
|
|
|
|
<GradientStop Color="#EFF1F4" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</LinearGradientBrush>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="Panel" Color="#EBF8F9FB"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Card" Color="#FFFFFF"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="CardHover" Color="#F7F9FC"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="CardSel" Color="#E3EAF3"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Stroke" Color="#CDD3DC"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="GlassEdge" Color="#D5DAE2"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Text" Color="#242B35"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Muted" Color="#606C7B"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Accent" Color="#405B80"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="AccentHover" Color="#4E6D96"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="AccentDim" Color="#344C6E"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="OnAccent" Color="#FFFFFF"/>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="SoftBg" Color="#E9EDF2"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SoftHover" Color="#F6F8FB"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="SwitchTrack" Color="#C5CDD7"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="SwitchThumb" Color="#FFFFFF"/>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="BadgeBg" Color="#E0E6EE"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="PingBg" Color="#EDF1F5"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="LogBg" Color="#F8F9FB"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="LogText" Color="#49586B"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollTrack" Color="#18758499"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollThumb" Color="#8895A6"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="ScrollThumbHover" Color="#687A90"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="HeroRing" Color="#905F7591"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="HeroRingDim" Color="#407D8FA6"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<RadialGradientBrush x:Key="GlowA">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#127689A2" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#007689A2" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</RadialGradientBrush>
|
|
|
|
|
|
<RadialGradientBrush x:Key="GlowB">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<GradientStop Color="#108398B4" Offset="0"/>
|
|
|
|
|
|
<GradientStop Color="#008398B4" Offset="1"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</RadialGradientBrush>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<SolidColorBrush x:Key="Ok" Color="#207553"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Warn" Color="#95620D"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Bad" Color="#BD3848"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Idle" Color="#606C7B"/>
|
|
|
|
|
|
<SolidColorBrush x:Key="Na" Color="#606C7B"/>
|
|
|
|
|
|
<sys:Double x:Key="ShadowOpacity">0.10</sys:Double>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</ResourceDictionary>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Одинаковая прокрутка во всех ScrollViewer/ListBox/TextBox. -->
|
|
|
|
|
|
<Style x:Key="ScrollPageButton" TargetType="RepeatButton">
|
|
|
|
|
|
<Setter Property="Focusable" Value="False"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="RepeatButton">
|
|
|
|
|
|
<Border Background="Transparent"/>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<Style x:Key="ScrollGrip" TargetType="Thumb">
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Thumb">
|
|
|
|
|
|
<Border x:Name="Grip" Margin="2,1" CornerRadius="4"
|
|
|
|
|
|
Background="{DynamicResource ScrollThumb}"/>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="Grip" Property="Background" Value="{DynamicResource ScrollThumbHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
<Trigger Property="IsDragging" Value="True">
|
|
|
|
|
|
<Setter TargetName="Grip" Property="Background" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<ControlTemplate x:Key="VerticalScroll" TargetType="ScrollBar">
|
|
|
|
|
|
<Border Background="{DynamicResource ScrollTrack}" Width="10">
|
|
|
|
|
|
<Track x:Name="PART_Track" IsDirectionReversed="True"
|
|
|
|
|
|
Orientation="Vertical" ViewportSize="{TemplateBinding ViewportSize}"
|
|
|
|
|
|
Minimum="{TemplateBinding Minimum}" Maximum="{TemplateBinding Maximum}"
|
|
|
|
|
|
Value="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
|
|
|
|
|
|
<Track.DecreaseRepeatButton>
|
|
|
|
|
|
<RepeatButton Style="{StaticResource ScrollPageButton}" Command="ScrollBar.PageUpCommand"/>
|
|
|
|
|
|
</Track.DecreaseRepeatButton>
|
|
|
|
|
|
<Track.Thumb><Thumb Style="{StaticResource ScrollGrip}"/></Track.Thumb>
|
|
|
|
|
|
<Track.IncreaseRepeatButton>
|
|
|
|
|
|
<RepeatButton Style="{StaticResource ScrollPageButton}" Command="ScrollBar.PageDownCommand"/>
|
|
|
|
|
|
</Track.IncreaseRepeatButton>
|
|
|
|
|
|
</Track>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
|
|
|
|
|
|
<ControlTemplate x:Key="HorizontalScroll" TargetType="ScrollBar">
|
|
|
|
|
|
<Border Background="{DynamicResource ScrollTrack}" Height="10">
|
|
|
|
|
|
<Track x:Name="PART_Track" Orientation="Horizontal"
|
|
|
|
|
|
ViewportSize="{TemplateBinding ViewportSize}"
|
|
|
|
|
|
Minimum="{TemplateBinding Minimum}" Maximum="{TemplateBinding Maximum}"
|
|
|
|
|
|
Value="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
|
|
|
|
|
|
<Track.DecreaseRepeatButton>
|
|
|
|
|
|
<RepeatButton Style="{StaticResource ScrollPageButton}" Command="ScrollBar.PageLeftCommand"/>
|
|
|
|
|
|
</Track.DecreaseRepeatButton>
|
|
|
|
|
|
<Track.Thumb><Thumb Style="{StaticResource ScrollGrip}"/></Track.Thumb>
|
|
|
|
|
|
<Track.IncreaseRepeatButton>
|
|
|
|
|
|
<RepeatButton Style="{StaticResource ScrollPageButton}" Command="ScrollBar.PageRightCommand"/>
|
|
|
|
|
|
</Track.IncreaseRepeatButton>
|
|
|
|
|
|
</Track>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
|
|
|
|
|
|
<Style TargetType="ScrollBar">
|
|
|
|
|
|
<Setter Property="Width" Value="10"/>
|
|
|
|
|
|
<Setter Property="Template" Value="{StaticResource VerticalScroll}"/>
|
|
|
|
|
|
<Style.Triggers>
|
|
|
|
|
|
<Trigger Property="Orientation" Value="Horizontal">
|
|
|
|
|
|
<Setter Property="Width" Value="Auto"/>
|
|
|
|
|
|
<Setter Property="Height" Value="10"/>
|
|
|
|
|
|
<Setter Property="Template" Value="{StaticResource HorizontalScroll}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</Style.Triggers>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── кнопка-таблетка (основное действие) ────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="Pill" TargetType="Button">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource OnAccent}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="14"/>
|
|
|
|
|
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="24" Background="{DynamicResource Accent}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1"
|
|
|
|
|
|
Padding="30,13">
|
|
|
|
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource AccentHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
<Trigger Property="IsPressed" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource AccentDim}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── вторичная кнопка ───────────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="Soft" TargetType="Button">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Muted}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="12" Background="{DynamicResource SoftBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1" Padding="14,8">
|
|
|
|
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource SoftHover}"/>
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── кнопка опасного действия (удаление) ────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="SoftDanger" TargetType="Button">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Muted}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="12" Background="{DynamicResource SoftBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1" Padding="14,8">
|
|
|
|
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource SoftHover}"/>
|
|
|
|
|
|
<Setter TargetName="B" Property="BorderBrush" Value="{DynamicResource Bad}"/>
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Bad}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── контекстное меню ───────────────────────────────────────────── -->
|
|
|
|
|
|
<Style TargetType="ContextMenu">
|
|
|
|
|
|
<Setter Property="Background" Value="{DynamicResource Panel}"/>
|
|
|
|
|
|
<Setter Property="BorderBrush" Value="{DynamicResource Stroke}"/>
|
|
|
|
|
|
<Setter Property="BorderThickness" Value="1"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="ContextMenu">
|
|
|
|
|
|
<Border CornerRadius="8" Background="{DynamicResource Panel}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1" Padding="4">
|
|
|
|
|
|
<Border.Effect>
|
|
|
|
|
|
<DropShadowEffect BlurRadius="14" ShadowDepth="3" Direction="270"
|
|
|
|
|
|
Opacity="{DynamicResource ShadowOpacity}" Color="Black"/>
|
|
|
|
|
|
</Border.Effect>
|
|
|
|
|
|
<StackPanel IsItemsHost="True"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<Style TargetType="MenuItem">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="MenuItem">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="6" Background="Transparent" Padding="12,7">
|
|
|
|
|
|
<ContentPresenter ContentSource="Header" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsHighlighted" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource SoftHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── кнопки заголовка ───────────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="Chrome" TargetType="Button">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Muted}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="13"/>
|
|
|
|
|
|
<Setter Property="Width" Value="40"/>
|
|
|
|
|
|
<Setter Property="Height" Value="30"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="7" Background="Transparent">
|
|
|
|
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource SoftHover}"/>
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── переключатель ──────────────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="Switch" TargetType="ToggleButton">
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="ToggleButton">
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Grid Width="52" Height="30">
|
|
|
|
|
|
<Border CornerRadius="15" Background="{DynamicResource SwitchTrack}"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1"/>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Border x:Name="ActiveTrack" CornerRadius="15" Background="{DynamicResource Accent}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Accent}" BorderThickness="1" Opacity="0"/>
|
|
|
|
|
|
<Ellipse x:Name="Thumb" Width="22" Height="22" Fill="{DynamicResource SwitchThumb}"
|
|
|
|
|
|
HorizontalAlignment="Left" VerticalAlignment="Center" Margin="4,0,0,0">
|
|
|
|
|
|
<Ellipse.RenderTransform><TranslateTransform/></Ellipse.RenderTransform>
|
|
|
|
|
|
<Ellipse.Effect>
|
|
|
|
|
|
<DropShadowEffect Color="#50000000" BlurRadius="4" ShadowDepth="1" Opacity="0.35"/>
|
|
|
|
|
|
</Ellipse.Effect>
|
|
|
|
|
|
</Ellipse>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Grid>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Trigger Property="IsPressed" Value="True">
|
|
|
|
|
|
<Setter TargetName="Thumb" Property="Width" Value="26"/>
|
|
|
|
|
|
<Trigger.EnterActions>
|
|
|
|
|
|
<BeginStoryboard>
|
|
|
|
|
|
<Storyboard FillBehavior="Stop">
|
|
|
|
|
|
<DoubleAnimation Storyboard.TargetName="Thumb" Storyboard.TargetProperty="Width"
|
|
|
|
|
|
From="22" To="26" Duration="0:0:0.12"/>
|
|
|
|
|
|
</Storyboard>
|
|
|
|
|
|
</BeginStoryboard>
|
|
|
|
|
|
</Trigger.EnterActions>
|
|
|
|
|
|
<Trigger.ExitActions>
|
|
|
|
|
|
<BeginStoryboard>
|
|
|
|
|
|
<Storyboard FillBehavior="Stop">
|
|
|
|
|
|
<DoubleAnimation Storyboard.TargetName="Thumb" Storyboard.TargetProperty="Width"
|
|
|
|
|
|
From="26" To="22" Duration="0:0:0.18"/>
|
|
|
|
|
|
</Storyboard>
|
|
|
|
|
|
</BeginStoryboard>
|
|
|
|
|
|
</Trigger.ExitActions>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── карточка сервера ───────────────────────────────────────────── -->
|
|
|
|
|
|
<DataTemplate x:Key="ServerCard">
|
|
|
|
|
|
<Border x:Name="Card" CornerRadius="16" Background="{DynamicResource Card}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1" Margin="0,0,0,10">
|
|
|
|
|
|
<Border.ContextMenu>
|
|
|
|
|
|
<ContextMenu>
|
|
|
|
|
|
<MenuItem Header="Удалить сервер" Command="{Binding DeleteCommand}"/>
|
|
|
|
|
|
</ContextMenu>
|
|
|
|
|
|
</Border.ContextMenu>
|
|
|
|
|
|
<Button Command="{Binding SelectCommand}" CommandParameter="{Binding}"
|
|
|
|
|
|
Cursor="Hand" HorizontalContentAlignment="Stretch">
|
|
|
|
|
|
<Button.Template>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Border Background="Transparent" Padding="14,14">
|
|
|
|
|
|
<ContentPresenter/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Button.Template>
|
|
|
|
|
|
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="42"/>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- флаг страны; для незнакомого кода — текстовый бейдж -->
|
|
|
|
|
|
<Grid Grid.Column="0" Width="34" HorizontalAlignment="Left">
|
|
|
|
|
|
<Image Source="{Binding Flag}" Width="34" Height="23" Stretch="Fill"
|
|
|
|
|
|
RenderOptions.BitmapScalingMode="HighQuality"/>
|
|
|
|
|
|
<Border x:Name="TextBadge" Width="34" Height="34" CornerRadius="9"
|
|
|
|
|
|
Background="{DynamicResource BadgeBg}" Visibility="Collapsed">
|
|
|
|
|
|
<TextBlock Text="{Binding Badge}" Foreground="{DynamicResource Text}"
|
|
|
|
|
|
FontSize="12" FontWeight="Bold"
|
|
|
|
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="1" VerticalAlignment="Center" Margin="10,0,0,0">
|
|
|
|
|
|
<TextBlock Text="{Binding Title}" Foreground="{DynamicResource Text}"
|
|
|
|
|
|
FontSize="13.5" FontWeight="SemiBold"/>
|
|
|
|
|
|
<TextBlock Text="{Binding Subtitle}" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
FontSize="11" Margin="0,2,0,0" TextTrimming="CharacterEllipsis"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
|
|
<Border Grid.Column="2" CornerRadius="6" Padding="7,3"
|
|
|
|
|
|
Background="{DynamicResource PingBg}" VerticalAlignment="Center">
|
|
|
|
|
|
<TextBlock Text="{Binding PingText}" Foreground="{Binding PingBrush}"
|
|
|
|
|
|
FontSize="11" FontWeight="SemiBold"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
|
|
<DataTemplate.Triggers>
|
|
|
|
|
|
<DataTrigger Binding="{Binding Flag}" Value="{x:Null}">
|
|
|
|
|
|
<Setter TargetName="TextBadge" Property="Visibility" Value="Visible"/>
|
|
|
|
|
|
</DataTrigger>
|
|
|
|
|
|
<Trigger SourceName="Card" Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="Card" Property="Background" Value="{DynamicResource CardHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</DataTemplate.Triggers>
|
|
|
|
|
|
</DataTemplate>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── поле ввода ─────────────────────────────────────────────────
|
|
|
|
|
|
Consolas: значения здесь — base64-ключ и IP-адрес, в
|
|
|
|
|
|
моноширинном их глазом проверять заметно легче. -->
|
|
|
|
|
|
<Style x:Key="Field" TargetType="TextBox">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="CaretBrush" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="SelectionBrush" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
<Setter Property="FontFamily" Value="Consolas"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="TextBox">
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="8" Background="{DynamicResource SoftBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1"
|
|
|
|
|
|
Padding="10,7">
|
|
|
|
|
|
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Stretch"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource SoftHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
<Trigger Property="IsFocused" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="BorderBrush" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── элемент выпадающего списка ─────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="ComboItem" TargetType="ComboBoxItem">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="FontFamily" Value="Consolas"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="ComboBoxItem">
|
|
|
|
|
|
<Border x:Name="B" Background="Transparent" Padding="10,7" CornerRadius="6">
|
|
|
|
|
|
<ContentPresenter/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource CardHover}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
<Trigger Property="IsHighlighted" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="Background" Value="{DynamicResource CardSel}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── редактируемый выпадающий список ────────────────────────────
|
|
|
|
|
|
Шаблон целиком, а не только цвета: штатный ComboBox рисуется
|
|
|
|
|
|
темой Windows и в тёмной палитре выглядит белым пятном.
|
|
|
|
|
|
Обязательные части — PART_EditableTextBox и PART_Popup.
|
|
|
|
|
|
Редактируемый он намеренно: если адаптера нет в списке
|
|
|
|
|
|
(отключён, виртуальный), имя можно вписать руками. -->
|
|
|
|
|
|
<Style x:Key="FieldCombo" TargetType="ComboBox">
|
|
|
|
|
|
<Setter Property="IsEditable" Value="True"/>
|
|
|
|
|
|
<Setter Property="ItemContainerStyle" Value="{StaticResource ComboItem}"/>
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="FontFamily" Value="Consolas"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="ComboBox">
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Border x:Name="B" CornerRadius="8" Background="{DynamicResource SoftBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1"/>
|
|
|
|
|
|
<Grid Margin="1">
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
<ColumnDefinition Width="30"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBox x:Name="PART_EditableTextBox" Grid.Column="0"
|
|
|
|
|
|
Background="Transparent" BorderThickness="0"
|
|
|
|
|
|
Foreground="{DynamicResource Text}"
|
|
|
|
|
|
CaretBrush="{DynamicResource Text}"
|
|
|
|
|
|
SelectionBrush="{DynamicResource Accent}"
|
|
|
|
|
|
Padding="9,6" VerticalContentAlignment="Center"/>
|
|
|
|
|
|
|
|
|
|
|
|
<ToggleButton Grid.Column="1" Focusable="False" ClickMode="Press" Cursor="Hand"
|
|
|
|
|
|
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay,
|
|
|
|
|
|
RelativeSource={RelativeSource TemplatedParent}}">
|
|
|
|
|
|
<ToggleButton.Template>
|
|
|
|
|
|
<ControlTemplate TargetType="ToggleButton">
|
|
|
|
|
|
<Border Background="Transparent">
|
|
|
|
|
|
<Path Data="M 0,0 L 8,0 L 4,5 Z" Fill="{DynamicResource Muted}"
|
|
|
|
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</ToggleButton.Template>
|
|
|
|
|
|
</ToggleButton>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<Popup x:Name="PART_Popup" Placement="Bottom" AllowsTransparency="True"
|
|
|
|
|
|
IsOpen="{TemplateBinding IsDropDownOpen}" Focusable="False"
|
|
|
|
|
|
PopupAnimation="Fade">
|
|
|
|
|
|
<Border Background="{DynamicResource Panel}" CornerRadius="8"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1"
|
|
|
|
|
|
Margin="0,4,0,0" Padding="4"
|
|
|
|
|
|
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}">
|
|
|
|
|
|
<ScrollViewer MaxHeight="220" VerticalScrollBarVisibility="Auto">
|
|
|
|
|
|
<ItemsPresenter/>
|
|
|
|
|
|
</ScrollViewer>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Popup>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<Trigger Property="IsKeyboardFocusWithin" Value="True">
|
|
|
|
|
|
<Setter TargetName="B" Property="BorderBrush" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── переключатель вкладок «лог / настройки» ─────────────────
|
|
|
|
|
|
Цвет активной вкладки приходит из ViewModel ключом палитры,
|
|
|
|
|
|
поэтому переживает смену темы. -->
|
|
|
|
|
|
<Style x:Key="Tab" TargetType="Button">
|
|
|
|
|
|
<Setter Property="FontSize" Value="10.5"/>
|
|
|
|
|
|
<Setter Property="FontWeight" Value="Bold"/>
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Setter Property="Width" Value="112"/>
|
|
|
|
|
|
<Setter Property="Height" Value="32"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<Setter Property="Cursor" Value="Hand"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border Background="Transparent" CornerRadius="10">
|
|
|
|
|
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Border>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── подпись поля ───────────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="FieldLabel" TargetType="TextBlock">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Text}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="12"/>
|
|
|
|
|
|
<!-- Top, а не Center: под полем идёт подсказка, и по центру
|
|
|
|
|
|
всей колонки подпись уезжала бы ниже самого поля. -->
|
|
|
|
|
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
|
|
|
|
|
<Setter Property="Margin" Value="0,9,12,0"/>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── заголовок группы ───────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="GroupLabel" TargetType="TextBlock">
|
|
|
|
|
|
<Setter Property="Foreground" Value="{DynamicResource Muted}"/>
|
|
|
|
|
|
<Setter Property="FontSize" Value="10.5"/>
|
|
|
|
|
|
<Setter Property="FontWeight" Value="Bold"/>
|
|
|
|
|
|
<Setter Property="Margin" Value="0,0,0,10"/>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── подсказка под полем ────────────────────────────────────── -->
|
|
|
|
|
|
<Style x:Key="Hint" TargetType="TextBlock">
|
|
|
|
|
|
<Setter Property="FontSize" Value="10.5"/>
|
|
|
|
|
|
<Setter Property="Margin" Value="0,4,0,0"/>
|
|
|
|
|
|
<Setter Property="TextWrapping" Value="Wrap"/>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
|
|
|
|
|
|
</ResourceDictionary>
|
|
|
|
|
|
</Window.Resources>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
|
|
|
|
<Border Background="{DynamicResource Bg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource Stroke}" BorderThickness="1">
|
|
|
|
|
|
|
|
|
|
|
|
<Grid ClipToBounds="True">
|
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
|
<RowDefinition Height="62"/>
|
|
|
|
|
|
<RowDefinition Height="*"/>
|
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Цветовые пятна статичны: плавный «стеклянный» вид без дорогого blur. -->
|
|
|
|
|
|
<Canvas Grid.RowSpan="2" IsHitTestVisible="False" ClipToBounds="True">
|
|
|
|
|
|
<Ellipse Width="720" Height="720" Fill="{DynamicResource GlowA}"
|
|
|
|
|
|
Canvas.Left="-240" Canvas.Top="-320"/>
|
|
|
|
|
|
<Ellipse Width="740" Height="740" Fill="{DynamicResource GlowB}"
|
|
|
|
|
|
Canvas.Left="570" Canvas.Top="300"/>
|
|
|
|
|
|
</Canvas>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── заголовок ─────────────────────────────────────────────── -->
|
|
|
|
|
|
<Grid x:Name="TitleBar" Grid.Row="0" Background="Transparent">
|
|
|
|
|
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="23,0,0,0">
|
|
|
|
|
|
<Image x:Name="LogoImg" Width="31" Height="31" VerticalAlignment="Center"
|
|
|
|
|
|
RenderOptions.BitmapScalingMode="HighQuality"/>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<TextBlock Text="SbLauncher" Foreground="{DynamicResource Text}"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
FontSize="15" FontWeight="SemiBold" Margin="11,0,0,0"
|
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
|
<Border Background="{DynamicResource SoftBg}" BorderBrush="{DynamicResource Stroke}"
|
|
|
|
|
|
BorderThickness="1" CornerRadius="10" Margin="12,0,0,0" Padding="8,3">
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<TextBlock Text="{Binding VersionText}" Foreground="{DynamicResource Muted}"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
FontSize="10" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
|
|
|
|
|
|
VerticalAlignment="Center" Margin="0,0,12,0">
|
|
|
|
|
|
<Button x:Name="BtnTheme" Style="{StaticResource Chrome}"
|
|
|
|
|
|
FontFamily="Segoe MDL2 Assets" FontSize="14"
|
2026-10-10 14:58:04 +03:00
|
|
|
|
ToolTip="{Binding ThemeAction}" AutomationProperties.Name="{Binding ThemeAction}">
|
|
|
|
|
|
<Grid Width="22" Height="22" IsHitTestVisible="False">
|
|
|
|
|
|
<TextBlock x:Name="ThemeSun" Text="" HorizontalAlignment="Center"
|
|
|
|
|
|
VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
|
|
|
|
|
|
<TextBlock.RenderTransform>
|
|
|
|
|
|
<TransformGroup><ScaleTransform/><RotateTransform/></TransformGroup>
|
|
|
|
|
|
</TextBlock.RenderTransform>
|
|
|
|
|
|
</TextBlock>
|
|
|
|
|
|
<TextBlock x:Name="ThemeMoon" Text="" HorizontalAlignment="Center"
|
|
|
|
|
|
VerticalAlignment="Center" Opacity="0" RenderTransformOrigin="0.5,0.5">
|
|
|
|
|
|
<TextBlock.RenderTransform>
|
|
|
|
|
|
<TransformGroup><ScaleTransform ScaleX="0.4" ScaleY="0.4"/><RotateTransform Angle="90"/></TransformGroup>
|
|
|
|
|
|
</TextBlock.RenderTransform>
|
|
|
|
|
|
</TextBlock>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Button>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<Button x:Name="BtnMin" Style="{StaticResource Chrome}" Content="–"/>
|
|
|
|
|
|
<Button x:Name="BtnClose" Style="{StaticResource Chrome}" Content="✕"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ─── тело ──────────────────────────────────────────────────── -->
|
|
|
|
|
|
<Grid Grid.Row="1">
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="335"/>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- левая колонка: серверы -->
|
|
|
|
|
|
<Border Grid.Column="0" Background="{DynamicResource Panel}" CornerRadius="22"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1"
|
|
|
|
|
|
Margin="16,6,0,16">
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
|
<RowDefinition Height="*"/>
|
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<Grid Grid.Row="0" Margin="20,20,16,16">
|
|
|
|
|
|
<TextBlock Text="СЕРВЕРЫ" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
FontSize="11" FontWeight="Bold" VerticalAlignment="Center"/>
|
|
|
|
|
|
<Button Style="{StaticResource Soft}" Content="пинг"
|
|
|
|
|
|
Command="{Binding PingAllCommand}" HorizontalAlignment="Right"
|
|
|
|
|
|
Padding="10,4"/>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Grid x:Name="ServerListHost" Grid.Row="1" ClipToBounds="True">
|
|
|
|
|
|
<ListBox x:Name="ServerList" ItemsSource="{Binding Servers}"
|
|
|
|
|
|
SelectedItem="{Binding Selected, Mode=TwoWay}"
|
|
|
|
|
|
ItemTemplate="{StaticResource ServerCard}"
|
|
|
|
|
|
Background="Transparent" BorderThickness="0"
|
|
|
|
|
|
Margin="12,0,12,14" Padding="0,0,4,0"
|
|
|
|
|
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
|
|
|
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
|
|
|
|
|
ScrollViewer.CanContentScroll="True"
|
|
|
|
|
|
VirtualizingStackPanel.IsVirtualizing="True"
|
|
|
|
|
|
VirtualizingStackPanel.VirtualizationMode="Recycling">
|
|
|
|
|
|
<ListBox.ItemContainerStyle>
|
|
|
|
|
|
<Style TargetType="ListBoxItem">
|
|
|
|
|
|
<Setter Property="Padding" Value="0"/>
|
|
|
|
|
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
|
|
|
|
|
<Setter Property="Template">
|
|
|
|
|
|
<Setter.Value>
|
|
|
|
|
|
<ControlTemplate TargetType="ListBoxItem">
|
|
|
|
|
|
<ContentPresenter ContentSource="Content"
|
|
|
|
|
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Setter.Value>
|
|
|
|
|
|
</Setter>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
</ListBox.ItemContainerStyle>
|
|
|
|
|
|
</ListBox>
|
|
|
|
|
|
<Canvas IsHitTestVisible="False" ClipToBounds="True">
|
|
|
|
|
|
<Border x:Name="ServerSelectionWindow" Visibility="Collapsed"
|
|
|
|
|
|
CornerRadius="16" BorderBrush="{DynamicResource Accent}"
|
|
|
|
|
|
BorderThickness="1.5">
|
|
|
|
|
|
<Border CornerRadius="15" Background="{DynamicResource Accent}" Opacity="0.16"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Canvas>
|
|
|
|
|
|
</Grid>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Grid>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- правая колонка -->
|
|
|
|
|
|
<Grid Grid.Column="1" Margin="18,6,18,16">
|
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
|
<RowDefinition Height="Auto"/> <!-- статус -->
|
|
|
|
|
|
<RowDefinition Height="Auto"/> <!-- режим -->
|
|
|
|
|
|
<RowDefinition Height="Auto"/> <!-- вкладки -->
|
|
|
|
|
|
<RowDefinition Height="*"/> <!-- лог/настройки-->
|
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- статус -->
|
|
|
|
|
|
<Border Grid.Row="0" CornerRadius="24" Background="{DynamicResource Panel}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1" Padding="23,22">
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="78"/>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<Grid Grid.Column="0" Width="66" Height="66" VerticalAlignment="Center">
|
|
|
|
|
|
<Ellipse Fill="{DynamicResource SoftBg}" Stroke="{DynamicResource GlassEdge}"
|
|
|
|
|
|
StrokeThickness="1"/>
|
|
|
|
|
|
<Ellipse Width="62" Height="62" Stroke="{DynamicResource HeroRingDim}"
|
|
|
|
|
|
StrokeThickness="2" Margin="2"/>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<!-- Мягкое заполнение после подключения вместо резкой вспышки. -->
|
|
|
|
|
|
<Ellipse x:Name="ConnectionGlow" Width="58" Height="58" Fill="{DynamicResource Ok}"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
RenderTransformOrigin="0.5,0.5" IsHitTestVisible="False">
|
|
|
|
|
|
<Ellipse.RenderTransform><ScaleTransform/></Ellipse.RenderTransform>
|
|
|
|
|
|
<Ellipse.Style>
|
|
|
|
|
|
<Style TargetType="Ellipse">
|
|
|
|
|
|
<Setter Property="Opacity" Value="0"/>
|
|
|
|
|
|
<Style.Triggers>
|
|
|
|
|
|
<DataTrigger Binding="{Binding ConnectionPhase}" Value="connected">
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Setter Property="Opacity" Value="0.18"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<DataTrigger.EnterActions>
|
|
|
|
|
|
<BeginStoryboard>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Storyboard FillBehavior="Stop">
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="Opacity"
|
2026-09-27 15:24:51 +03:00
|
|
|
|
From="0" To="0.18" Duration="0:0:0.55"/>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
2026-09-27 15:24:51 +03:00
|
|
|
|
From="0.82" To="1" Duration="0:0:0.55">
|
|
|
|
|
|
<DoubleAnimation.EasingFunction>
|
|
|
|
|
|
<BackEase Amplitude="0.28" EasingMode="EaseOut"/>
|
|
|
|
|
|
</DoubleAnimation.EasingFunction>
|
|
|
|
|
|
</DoubleAnimation>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
2026-09-27 15:24:51 +03:00
|
|
|
|
From="0.82" To="1" Duration="0:0:0.55">
|
|
|
|
|
|
<DoubleAnimation.EasingFunction>
|
|
|
|
|
|
<BackEase Amplitude="0.28" EasingMode="EaseOut"/>
|
|
|
|
|
|
</DoubleAnimation.EasingFunction>
|
|
|
|
|
|
</DoubleAnimation>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Storyboard>
|
|
|
|
|
|
</BeginStoryboard>
|
|
|
|
|
|
</DataTrigger.EnterActions>
|
|
|
|
|
|
</DataTrigger>
|
|
|
|
|
|
</Style.Triggers>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
</Ellipse.Style>
|
|
|
|
|
|
</Ellipse>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<!-- Пока соединение меняется, ободок спокойно «дышит». -->
|
|
|
|
|
|
<Ellipse x:Name="ConnectionBreathRing" Width="58" Height="58" Stroke="{DynamicResource Accent}"
|
|
|
|
|
|
StrokeThickness="2.5" IsHitTestVisible="False"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
RenderTransformOrigin="0.5,0.5">
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Ellipse.RenderTransform><ScaleTransform/></Ellipse.RenderTransform>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<Ellipse.Style>
|
|
|
|
|
|
<Style TargetType="Ellipse">
|
|
|
|
|
|
<Setter Property="Opacity" Value="0"/>
|
|
|
|
|
|
<Style.Triggers>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<DataTrigger Binding="{Binding ConnectionInProgress}" Value="True">
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<DataTrigger.EnterActions>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<BeginStoryboard x:Name="ConnectionBreath">
|
|
|
|
|
|
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
|
|
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="Opacity"
|
|
|
|
|
|
From="0.25" To="0.72" Duration="0:0:0.9">
|
|
|
|
|
|
<DoubleAnimation.EasingFunction><SineEase EasingMode="EaseInOut"/></DoubleAnimation.EasingFunction>
|
|
|
|
|
|
</DoubleAnimation>
|
|
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
|
|
|
|
|
From="0.9" To="1.08" Duration="0:0:0.9">
|
|
|
|
|
|
<DoubleAnimation.EasingFunction><SineEase EasingMode="EaseInOut"/></DoubleAnimation.EasingFunction>
|
|
|
|
|
|
</DoubleAnimation>
|
|
|
|
|
|
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
|
|
|
|
|
From="0.9" To="1.08" Duration="0:0:0.9">
|
|
|
|
|
|
<DoubleAnimation.EasingFunction><SineEase EasingMode="EaseInOut"/></DoubleAnimation.EasingFunction>
|
|
|
|
|
|
</DoubleAnimation>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Storyboard>
|
|
|
|
|
|
</BeginStoryboard>
|
|
|
|
|
|
</DataTrigger.EnterActions>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<DataTrigger.ExitActions><StopStoryboard BeginStoryboardName="ConnectionBreath"/></DataTrigger.ExitActions>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</DataTrigger>
|
|
|
|
|
|
</Style.Triggers>
|
|
|
|
|
|
</Style>
|
|
|
|
|
|
</Ellipse.Style>
|
|
|
|
|
|
</Ellipse>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<Button x:Name="BtnPower" Width="66" Height="66"
|
|
|
|
|
|
Command="{Binding ConnectCommand}" Cursor="Hand"
|
|
|
|
|
|
ToolTip="{Binding ConnectText}"
|
|
|
|
|
|
AutomationProperties.Name="{Binding ConnectText}">
|
|
|
|
|
|
<Button.Template>
|
|
|
|
|
|
<ControlTemplate TargetType="Button">
|
|
|
|
|
|
<Grid Background="Transparent">
|
|
|
|
|
|
<Viewbox Width="32" Height="32">
|
|
|
|
|
|
<Canvas Width="32" Height="32">
|
|
|
|
|
|
<Path x:Name="PowerRing"
|
|
|
|
|
|
Data="M 9,8 C 5,10 4,14 4,17 C 4,24 9,29 16,29 C 23,29 28,24 28,17 C 28,14 27,10 23,8"
|
|
|
|
|
|
Stroke="{DynamicResource Text}" StrokeThickness="3"
|
|
|
|
|
|
StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
|
|
|
|
|
|
<Path x:Name="PowerStem" Data="M 16,3 L 16,17"
|
|
|
|
|
|
Stroke="{DynamicResource Text}" StrokeThickness="3"
|
|
|
|
|
|
StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
|
|
|
|
|
|
</Canvas>
|
|
|
|
|
|
</Viewbox>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
<ControlTemplate.Triggers>
|
|
|
|
|
|
<DataTrigger Binding="{Binding ConnectionPhase}" Value="connected">
|
|
|
|
|
|
<Setter TargetName="PowerRing" Property="Stroke" Value="{DynamicResource Ok}"/>
|
|
|
|
|
|
<Setter TargetName="PowerStem" Property="Stroke" Value="{DynamicResource Ok}"/>
|
|
|
|
|
|
</DataTrigger>
|
|
|
|
|
|
<DataTrigger Binding="{Binding ConnectionPhase}" Value="connecting">
|
|
|
|
|
|
<Setter TargetName="PowerRing" Property="Stroke" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
<Setter TargetName="PowerStem" Property="Stroke" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
</DataTrigger>
|
|
|
|
|
|
<Trigger Property="IsMouseOver" Value="True">
|
|
|
|
|
|
<Setter TargetName="PowerRing" Property="Stroke" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
<Setter TargetName="PowerStem" Property="Stroke" Value="{DynamicResource Accent}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
<Trigger Property="IsPressed" Value="True">
|
|
|
|
|
|
<Setter TargetName="PowerRing" Property="Stroke" Value="{DynamicResource AccentDim}"/>
|
|
|
|
|
|
<Setter TargetName="PowerStem" Property="Stroke" Value="{DynamicResource AccentDim}"/>
|
|
|
|
|
|
</Trigger>
|
|
|
|
|
|
</ControlTemplate.Triggers>
|
|
|
|
|
|
</ControlTemplate>
|
|
|
|
|
|
</Button.Template>
|
|
|
|
|
|
</Button>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="1" VerticalAlignment="Center" Margin="6,0,10,0">
|
|
|
|
|
|
<TextBlock Text="СОЕДИНЕНИЕ" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
FontSize="10" FontWeight="SemiBold" Margin="0,0,0,4"/>
|
|
|
|
|
|
<StackPanel Orientation="Horizontal">
|
|
|
|
|
|
<Ellipse Width="8" Height="8" Fill="{Binding StatusBrush}" VerticalAlignment="Center"/>
|
|
|
|
|
|
<TextBlock Text="{Binding StatusTitle}" Foreground="{DynamicResource Text}"
|
|
|
|
|
|
FontSize="23" FontWeight="Light" Margin="9,0,0,0"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
<TextBlock Text="{Binding StatusSub}" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
FontSize="11.5" Margin="0,5,0,0" TextTrimming="CharacterEllipsis"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
<Button Style="{StaticResource Pill}" Content="{Binding ConnectText}"
|
|
|
|
|
|
Command="{Binding ConnectCommand}"
|
|
|
|
|
|
Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- режим: через WireGuard или напрямую через адаптер -->
|
|
|
|
|
|
<Border Grid.Row="1" CornerRadius="21" Background="{DynamicResource Panel}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1"
|
|
|
|
|
|
Padding="24,18" Margin="0,13,0,0">
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<StackPanel VerticalAlignment="Center">
|
|
|
|
|
|
<TextBlock Text="WireGuard для .ru-трафика" Foreground="{DynamicResource Text}"
|
|
|
|
|
|
FontSize="13" FontWeight="SemiBold"/>
|
|
|
|
|
|
<TextBlock Foreground="{DynamicResource Muted}" FontSize="11" Margin="0,3,0,0"
|
|
|
|
|
|
Text="вкл — VLESS поверх WireGuard · выкл — напрямую через сетевой адаптер"/>
|
|
|
|
|
|
</StackPanel>
|
2026-09-27 15:24:51 +03:00
|
|
|
|
<ToggleButton x:Name="WireguardSwitch" Style="{StaticResource Switch}"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
IsChecked="{Binding WireguardOn, Mode=TwoWay}"
|
|
|
|
|
|
HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- вкладки -->
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border Grid.Row="2" Margin="0,12,0,10" Padding="3"
|
|
|
|
|
|
HorizontalAlignment="Left" CornerRadius="14"
|
|
|
|
|
|
Background="{DynamicResource SoftBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1">
|
|
|
|
|
|
<Grid x:Name="TabSelectorHost">
|
|
|
|
|
|
<Border x:Name="TabSelectionWindow" Width="112" HorizontalAlignment="Left"
|
|
|
|
|
|
CornerRadius="10" BorderBrush="{DynamicResource Accent}" BorderThickness="1">
|
|
|
|
|
|
<Border.RenderTransform><TranslateTransform/></Border.RenderTransform>
|
|
|
|
|
|
<Border CornerRadius="9" Background="{DynamicResource Accent}" Opacity="0.16"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
<StackPanel Orientation="Horizontal">
|
|
|
|
|
|
<Button x:Name="BtnTabLog" Style="{StaticResource Tab}" Content="ЛОГ"
|
|
|
|
|
|
Foreground="{Binding TabLogBrush}"/>
|
|
|
|
|
|
<Button x:Name="BtnTabSettings" Style="{StaticResource Tab}" Content="НАСТРОЙКИ"
|
|
|
|
|
|
Foreground="{Binding TabSettingsBrush}"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Border>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<!-- Панели скользят в пределах этой области и сохраняют своё содержимое. -->
|
|
|
|
|
|
<Grid x:Name="TabContentHost" Grid.Row="3" ClipToBounds="True">
|
2026-09-26 14:41:04 +03:00
|
|
|
|
|
|
|
|
|
|
<!-- ── лог ─────────────────────────────────────────────── -->
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border x:Name="LogPane"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
CornerRadius="21" Background="{DynamicResource LogBg}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1" Padding="4">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border.RenderTransform><TranslateTransform/></Border.RenderTransform>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<TextBox x:Name="LogBox" Text="{Binding LogText, Mode=OneWay}"
|
|
|
|
|
|
IsReadOnly="True" BorderThickness="0" Background="Transparent"
|
2026-09-26 21:49:44 +03:00
|
|
|
|
Foreground="{Binding LogBrush}" SelectionBrush="{DynamicResource Accent}"
|
|
|
|
|
|
IsInactiveSelectionHighlightEnabled="False"
|
|
|
|
|
|
FontFamily="Consolas" FontSize="11.5"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
Padding="14,10" TextWrapping="NoWrap"
|
|
|
|
|
|
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"/>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── настройки ───────────────────────────────────────── -->
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border x:Name="SettingsPane" Visibility="Hidden"
|
2026-09-26 14:41:04 +03:00
|
|
|
|
CornerRadius="21" Background="{DynamicResource Panel}"
|
|
|
|
|
|
BorderBrush="{DynamicResource GlassEdge}" BorderThickness="1" Padding="22,18">
|
2026-10-10 14:58:04 +03:00
|
|
|
|
<Border.RenderTransform><TranslateTransform/></Border.RenderTransform>
|
2026-09-26 14:41:04 +03:00
|
|
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0,0,6,0">
|
|
|
|
|
|
<StackPanel>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBlock Style="{StaticResource GroupLabel}" Text="WIREGUARD"/>
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="128"/>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBlock Grid.Row="0" Grid.Column="0" Style="{StaticResource FieldLabel}"
|
|
|
|
|
|
Text="Приватный ключ"/>
|
|
|
|
|
|
<StackPanel Grid.Row="0" Grid.Column="1">
|
|
|
|
|
|
<TextBox Style="{StaticResource Field}"
|
|
|
|
|
|
Text="{Binding PrivateKey, Mode=TwoWay}"/>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Text="{Binding PrivateKeyHint}"
|
|
|
|
|
|
Foreground="{Binding PrivateKeyHintBrush}"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBlock Grid.Row="1" Grid.Column="0" Style="{StaticResource FieldLabel}"
|
|
|
|
|
|
Text="Локальный IP" Margin="0,21,12,0"/>
|
|
|
|
|
|
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,12,0,0">
|
|
|
|
|
|
<TextBox Style="{StaticResource Field}"
|
|
|
|
|
|
Text="{Binding LocalAddress, Mode=TwoWay}"/>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Text="{Binding LocalAddressHint}"
|
|
|
|
|
|
Foreground="{Binding LocalAddressHintBrush}"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBlock Style="{StaticResource GroupLabel}" Text="СЕТЕВОЙ АДАПТЕР"
|
|
|
|
|
|
Margin="0,20,0,10"/>
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="128"/>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
<TextBlock Grid.Column="0" Style="{StaticResource FieldLabel}"
|
|
|
|
|
|
Text="Имя адаптера"/>
|
|
|
|
|
|
<StackPanel Grid.Column="1">
|
|
|
|
|
|
<ComboBox x:Name="AdapterBox" Style="{StaticResource FieldCombo}"
|
|
|
|
|
|
ItemsSource="{Binding AdapterNames}"
|
|
|
|
|
|
Text="{Binding Adapter, Mode=TwoWay}"/>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Text="{Binding AdapterHint}"
|
|
|
|
|
|
Foreground="{Binding AdapterHintBrush}"/>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
Text="нужен, только когда WireGuard выключен"/>
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
|
|
<TextBlock Style="{StaticResource GroupLabel}" Text="ДОБАВИТЬ СЕРВЕР"
|
|
|
|
|
|
Margin="0,20,0,10"/>
|
|
|
|
|
|
<Grid>
|
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
<TextBox x:Name="LinkBox" Grid.Column="0" Style="{StaticResource Field}"
|
|
|
|
|
|
Height="88" AcceptsReturn="True" TextWrapping="NoWrap"
|
|
|
|
|
|
VerticalScrollBarVisibility="Auto" MaxLength="2000000"/>
|
|
|
|
|
|
<Button x:Name="BtnAddLink" Grid.Column="1" Style="{StaticResource Soft}"
|
|
|
|
|
|
Content="импортировать" Margin="8,0,0,0" VerticalAlignment="Top"/>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
Text="Ссылки, текст/base64, URL подписки или sing-box JSON"/>
|
|
|
|
|
|
<TextBlock Style="{StaticResource Hint}" Foreground="{DynamicResource Muted}"
|
|
|
|
|
|
Text="{Binding ImportStatus}" TextWrapping="Wrap"/>
|
|
|
|
|
|
|
|
|
|
|
|
<WrapPanel Margin="0,20,0,0">
|
|
|
|
|
|
<Button Style="{StaticResource Soft}" Content="проверить конфиг"
|
|
|
|
|
|
Command="{Binding CheckConfigCommand}" Margin="0,0,8,8"/>
|
|
|
|
|
|
<Button Style="{StaticResource Soft}" Content="показать конфиг"
|
|
|
|
|
|
Command="{Binding OpenConfigCommand}" Margin="0,0,8,8"/>
|
|
|
|
|
|
<Button Style="{StaticResource Soft}" Content="папка"
|
|
|
|
|
|
Command="{Binding OpenFolderCommand}" Margin="0,0,8,8"/>
|
|
|
|
|
|
<Button Style="{StaticResource Soft}" Content="убить sb.exe"
|
|
|
|
|
|
Command="{Binding KillStrayCommand}" Margin="0,0,8,8"
|
|
|
|
|
|
ToolTip="Прибить зависшие процессы sb.exe, оставшиеся от прошлых запусков"/>
|
|
|
|
|
|
<Button Style="{StaticResource SoftDanger}" Content="удалить сервер"
|
|
|
|
|
|
Command="{Binding DeleteSelectedCommand}" Margin="0,0,8,8"
|
|
|
|
|
|
ToolTip="Удалить выбранный сервер из profiles.json"/>
|
|
|
|
|
|
</WrapPanel>
|
|
|
|
|
|
|
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
</ScrollViewer>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Border>
|
|
|
|
|
|
</Window>
|