fix(ui): consolidate mainwindow corner/clip fixes
This commit is contained in:
@@ -8,3 +8,4 @@
|
|||||||
4. Relevante Änderungen sind immer tageweise in `Changelog.md` zu dokumentieren.
|
4. Relevante Änderungen sind immer tageweise in `Changelog.md` zu dokumentieren.
|
||||||
5. Korrekturschleifen oder reine Nachbesserungen dürfen nicht als eigene Changelog-Einträge auftauchen.
|
5. Korrekturschleifen oder reine Nachbesserungen dürfen nicht als eigene Changelog-Einträge auftauchen.
|
||||||
6. `Releasenotes.md` ist vor Veröffentlichung oder auf explizite Anforderung aus dem `Changelog.md` zu synchronisieren.
|
6. `Releasenotes.md` ist vor Veröffentlichung oder auf explizite Anforderung aus dem `Changelog.md` zu synchronisieren.
|
||||||
|
7. Für Pushes ist standardmäßig `git pushr` (Retry/Backoff) zu verwenden; falls nicht verfügbar, ist `git push` mit manuellen Wiederholungen durchzuführen.
|
||||||
|
|||||||
@@ -5,7 +5,13 @@
|
|||||||
- Komplettes visuelles Redesign der Hauptoberfläche mit modernerem Layout und konsistenter Typografie.
|
- Komplettes visuelles Redesign der Hauptoberfläche mit modernerem Layout und konsistenter Typografie.
|
||||||
- Navigation, Content und Header farblich auf dynamische Konfigurationsfarben umgestellt.
|
- Navigation, Content und Header farblich auf dynamische Konfigurationsfarben umgestellt.
|
||||||
- Einheitliche Button-Optik für Primary-Actions, Top-Bar-Actions und dialogbezogene Aktionen.
|
- Einheitliche Button-Optik für Primary-Actions, Top-Bar-Actions und dialogbezogene Aktionen.
|
||||||
- Außenrahmen der Haupt-GUI als durchgehender Outline-Rahmen umgesetzt, damit die Kontur auch über die Rundungen konsistent sichtbar bleibt.
|
- Außenrahmen der Haupt-GUI als durchgehende Border auf der Hauptfläche umgesetzt, damit die Kontur über alle Rundungen konsistent bleibt.
|
||||||
|
- Eckradius von WindowChrome, Hauptfläche und innerem Inhalts-Clip abgestimmt, damit Inhalte in allen vier Ecken innerhalb des Rahmens bleiben.
|
||||||
|
- Hauptlayout von festen `Window.ActualWidth`-Bindings entkoppelt, damit Header/Content nicht über die gerundete Innenfläche hinausragen.
|
||||||
|
- Feste Hauptlayout-Höhen (Navigation/Content) auf die verfügbare Innenhöhe abgestimmt und Clipping im Dock-Bereich aktiviert, damit keine Inhalte in die Rundungsbereiche überlaufen.
|
||||||
|
- Initialisierung des Rounded-Clips auf den finalen Layout-Zeitpunkt erweitert (Loaded/Render), damit die Rundungsbegrenzung stabil greift.
|
||||||
|
- MainWindow-Ecküberstände beseitigt: Navigation-Rail unten links an den Fensterradius angepasst, Content-Bereich im `DockPanel` als Fill-Element geführt, zusätzlicher Surface-Clip auf Radius `20` gesetzt, den gesamten `MainWindowContentRoot` als konstanten `1px`-Inset innerhalb des Rahmens geführt, den Body-Host per Geometrie mit zum Innenradius passenden gerundeten unteren Ecken begrenzt, eine On-Top-Corner-Maske (`Rectangle - RoundedRectangle`) ergänzt, eine explizite On-Top-Rahmenkontur als `Path` ergänzt, die linke Rail-Kante ohne eigene Außenlinie geführt (kein Doppelrahmen links) und zusätzlich per Win32-Window-Region (`SetWindowRgn`) die Fensterkontur selbst auf Rundung begrenzt (WPF-Typen für Geometriepunkte/-größen explizit qualifiziert, um Mehrdeutigkeiten mit `System.Drawing` zu vermeiden).
|
||||||
|
- Sichtbarkeit des Main-Contents wiederhergestellt: Navigations-/Content-Host auf feste Breitenaufteilung (`75 + 425`) umgestellt, damit das Inhaltspanel nicht mehr durch einen Zero-Width-Viewport abgeschnitten wird.
|
||||||
|
|
||||||
### Navigation und Interaktion
|
### Navigation und Interaktion
|
||||||
- Navigation-Buttons neu ausgerichtet (horizontal/vertikal), Icons vergrößert und Zustände vereinheitlicht.
|
- Navigation-Buttons neu ausgerichtet (horizontal/vertikal), Icons vergrößert und Zustände vereinheitlicht.
|
||||||
@@ -49,6 +55,7 @@
|
|||||||
- Mehrdeutigkeitsfehler (`Brushes`) behoben.
|
- Mehrdeutigkeitsfehler (`Brushes`) behoben.
|
||||||
- Vor erfolgreichem Konfig-Ladevorgang wird die Oberfläche analog Offline-Zustand eingeschränkt (nur Info-Navigation und Info-Panel sichtbar).
|
- Vor erfolgreichem Konfig-Ladevorgang wird die Oberfläche analog Offline-Zustand eingeschränkt (nur Info-Navigation und Info-Panel sichtbar).
|
||||||
- Header-Verbindungsindikator für Offline/Verbindungsaufbau als größerer farbiger Status-Badge (rot/orange) sichtbarer umgesetzt, mit Tooltip versehen und so positioniert, dass er nicht von Action-Buttons überdeckt wird.
|
- Header-Verbindungsindikator für Offline/Verbindungsaufbau als größerer farbiger Status-Badge (rot/orange) sichtbarer umgesetzt, mit Tooltip versehen und so positioniert, dass er nicht von Action-Buttons überdeckt wird.
|
||||||
|
- AGENTS-Prozessregel ergänzt: Pushes standardmäßig über `git pushr` mit Retry/Backoff ausführen (Fallback: manuelle Wiederholungen mit `git push`).
|
||||||
|
|
||||||
### Lokalisierung
|
### Lokalisierung
|
||||||
- DE/EN-Ressourcen sprachlich bereinigt und vereinheitlicht.
|
- DE/EN-Ressourcen sprachlich bereinigt und vereinheitlicht.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
WindowStyle="None"
|
WindowStyle="None"
|
||||||
AllowsTransparency="False"
|
AllowsTransparency="False"
|
||||||
ResizeMode="NoResize"
|
ResizeMode="NoResize"
|
||||||
Background="Transparent"
|
Background="{DynamicResource backgroundColor}"
|
||||||
Loaded="Window_Loaded"
|
Loaded="Window_Loaded"
|
||||||
Icon="Resources/icons/logo_CustomerPanel.ico"
|
Icon="Resources/icons/logo_CustomerPanel.ico"
|
||||||
KeyDown="App_KeyDown"
|
KeyDown="App_KeyDown"
|
||||||
@@ -346,27 +346,28 @@
|
|||||||
</Window.TaskbarItemInfo>
|
</Window.TaskbarItemInfo>
|
||||||
<shell:WindowChrome.WindowChrome>
|
<shell:WindowChrome.WindowChrome>
|
||||||
<shell:WindowChrome CaptionHeight="72"
|
<shell:WindowChrome CaptionHeight="72"
|
||||||
CornerRadius="18"
|
CornerRadius="20"
|
||||||
GlassFrameThickness="0"
|
GlassFrameThickness="0"
|
||||||
ResizeBorderThickness="0"
|
ResizeBorderThickness="0"
|
||||||
UseAeroCaptionButtons="False" />
|
UseAeroCaptionButtons="False" />
|
||||||
</shell:WindowChrome.WindowChrome>
|
</shell:WindowChrome.WindowChrome>
|
||||||
|
|
||||||
<Grid x:Name="MainGrid"
|
<Grid x:Name="MainGrid"
|
||||||
Background="{DynamicResource backgroundColor}">
|
Background="Transparent">
|
||||||
<Border x:Name="MainWindowSurface"
|
<Border x:Name="MainWindowSurface"
|
||||||
CornerRadius="18"
|
CornerRadius="20"
|
||||||
BorderThickness="0"
|
BorderThickness="1"
|
||||||
|
BorderBrush="Transparent"
|
||||||
Background="{DynamicResource backgroundColor}"
|
Background="{DynamicResource backgroundColor}"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
ClipToBounds="True">
|
ClipToBounds="True">
|
||||||
<Grid>
|
<Grid x:Name="MainWindowContentRoot"
|
||||||
<DockPanel Width="{Binding ActualWidth, ElementName=Window, Mode=OneWay}"
|
Margin="1">
|
||||||
x:Name="MainDock"
|
<DockPanel x:Name="MainDock"
|
||||||
Background="{DynamicResource headerColor}">
|
Background="{DynamicResource headerColor}">
|
||||||
<Grid DockPanel.Dock="Top"
|
<Grid DockPanel.Dock="Top"
|
||||||
x:Name="GridTop"
|
x:Name="GridTop"
|
||||||
Width="{Binding ActualWidth, ElementName=Window, Mode=OneWay}"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalAlignment="Left"
|
|
||||||
Margin="0"
|
Margin="0"
|
||||||
Background="{DynamicResource headerColor}"
|
Background="{DynamicResource headerColor}"
|
||||||
Height="72"
|
Height="72"
|
||||||
@@ -485,32 +486,36 @@
|
|||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
BorderBrush="Gray"
|
BorderBrush="Gray"
|
||||||
CornerRadius="0,0,14,14"
|
CornerRadius="0,0,14,14"
|
||||||
Width="{Binding ActualWidth, ElementName=Window, Mode=OneWay}">
|
HorizontalAlignment="Stretch">
|
||||||
<Border.Background>
|
<Border.Background>
|
||||||
<ImageBrush ImageSource="Resources/top_cp.png"
|
<ImageBrush ImageSource="Resources/top_cp.png"
|
||||||
Stretch="UniformToFill" />
|
Stretch="UniformToFill" />
|
||||||
</Border.Background>
|
</Border.Background>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel Orientation="Horizontal"
|
<Grid Width="500"
|
||||||
Width="75"
|
Height="576"
|
||||||
DockPanel.Dock="Top"
|
ClipToBounds="True"
|
||||||
ClipToBounds="false"
|
x:Name="btnSP"
|
||||||
x:Name="btnSP"
|
HorizontalAlignment="Left">
|
||||||
HorizontalAlignment="Left">
|
<Grid.ColumnDefinitions>
|
||||||
<Canvas ClipToBounds="false"
|
<ColumnDefinition Width="75" />
|
||||||
|
<ColumnDefinition Width="425" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Canvas Grid.Column="0"
|
||||||
|
ClipToBounds="True"
|
||||||
Panel.ZIndex="1000"
|
Panel.ZIndex="1000"
|
||||||
Margin="0,0,0,0"
|
Margin="0,0,0,0"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Height="590"
|
Height="576"
|
||||||
Width="75">
|
Width="75">
|
||||||
<Border Canvas.Left="0"
|
<Border Canvas.Left="0"
|
||||||
Canvas.Top="8"
|
Canvas.Top="8"
|
||||||
Width="75"
|
Width="75"
|
||||||
Height="580"
|
Height="568"
|
||||||
CornerRadius="20,0,0,0"
|
CornerRadius="20,0,0,20"
|
||||||
BorderThickness="1"
|
BorderThickness="0,1,1,1"
|
||||||
BorderBrush="{DynamicResource navigationRailBorderColor}"
|
BorderBrush="{DynamicResource navigationRailBorderColor}"
|
||||||
Background="{DynamicResource navigationRailColor}" />
|
Background="{DynamicResource navigationRailColor}" />
|
||||||
<Button Visibility="Hidden"
|
<Button Visibility="Hidden"
|
||||||
@@ -938,21 +943,24 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
<Canvas Margin="0,0,0,0"
|
<Canvas Grid.Column="1"
|
||||||
|
Margin="0,0,0,0"
|
||||||
Panel.ZIndex="1"
|
Panel.ZIndex="1"
|
||||||
ClipToBounds="False"
|
ClipToBounds="True"
|
||||||
|
Height="576"
|
||||||
|
Width="425"
|
||||||
>
|
>
|
||||||
<Border Canvas.Left="-75"
|
<Border Canvas.Left="-75"
|
||||||
Canvas.Top="8"
|
Canvas.Top="8"
|
||||||
Width="500"
|
Width="500"
|
||||||
Height="580"
|
Height="568"
|
||||||
CornerRadius="20"
|
CornerRadius="20"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
BorderBrush="{DynamicResource panelBorderColor}"
|
BorderBrush="{DynamicResource panelBorderColor}"
|
||||||
Background="{DynamicResource panelBackgroundColor}" />
|
Background="{DynamicResource panelBackgroundColor}" />
|
||||||
<Canvas x:Name="StPaMain"
|
<Canvas x:Name="StPaMain"
|
||||||
Panel.ZIndex="1000"
|
Panel.ZIndex="1000"
|
||||||
Height="590"
|
Height="576"
|
||||||
Width="500"
|
Width="500"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
Canvas.Left="-75">
|
Canvas.Left="-75">
|
||||||
@@ -986,7 +994,7 @@
|
|||||||
</Canvas>
|
</Canvas>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
</StackPanel>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
<Image Source="Resources/United-Kingdom-Flag-icon.png"
|
<Image Source="Resources/United-Kingdom-Flag-icon.png"
|
||||||
Panel.ZIndex="1001"
|
Panel.ZIndex="1001"
|
||||||
@@ -996,14 +1004,22 @@
|
|||||||
Margin="80,0,0,140" />
|
Margin="80,0,0,140" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border x:Name="MainWindowOutline"
|
<Path x:Name="MainWindowCornerMaskOverlay"
|
||||||
CornerRadius="18"
|
Panel.ZIndex="3000"
|
||||||
BorderThickness="1"
|
HorizontalAlignment="Left"
|
||||||
BorderBrush="{DynamicResource panelBorderColor}"
|
VerticalAlignment="Top"
|
||||||
Background="Transparent"
|
Fill="{DynamicResource backgroundColor}"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
SnapsToDevicePixels="True"
|
SnapsToDevicePixels="True" />
|
||||||
Panel.ZIndex="3000" />
|
<Path x:Name="MainWindowFrameOverlay"
|
||||||
|
Panel.ZIndex="3001"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Fill="Transparent"
|
||||||
|
Stroke="{DynamicResource panelBorderColor}"
|
||||||
|
StrokeThickness="1"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
SnapsToDevicePixels="True" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ using System.Linq;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Shell;
|
using System.Windows.Shell;
|
||||||
@@ -74,8 +76,18 @@ namespace C4IT_CustomerPanel
|
|||||||
private TimeSpan _lastAdHocInterval;
|
private TimeSpan _lastAdHocInterval;
|
||||||
private TimeSpan _lastRegularInterval;
|
private TimeSpan _lastRegularInterval;
|
||||||
private bool _allowApplicationShutdown = false;
|
private bool _allowApplicationShutdown = false;
|
||||||
|
private bool _mainSurfaceClipInitialized = false;
|
||||||
internal DateTime lastUpdate;
|
internal DateTime lastUpdate;
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
private static extern bool DeleteObject(IntPtr hObject);
|
||||||
|
|
||||||
//private Dictionary<announcementType, List<Guid>> announcementIDCollection = new Dictionary<announcementType, List<Guid>>();
|
//private Dictionary<announcementType, List<Guid>> announcementIDCollection = new Dictionary<announcementType, List<Guid>>();
|
||||||
public bool _userIsAuthenticated = false;
|
public bool _userIsAuthenticated = false;
|
||||||
public enumOnlineState OnlineState = enumOnlineState.Initializing;
|
public enumOnlineState OnlineState = enumOnlineState.Initializing;
|
||||||
@@ -144,6 +156,7 @@ namespace C4IT_CustomerPanel
|
|||||||
FormHelper.GetLocation((int)this.Width, (int)this.Height, (double)ConfigSettings.local_currentDPI / 96);
|
FormHelper.GetLocation((int)this.Width, (int)this.Height, (double)ConfigSettings.local_currentDPI / 96);
|
||||||
|
|
||||||
SetAppearance(true);
|
SetAppearance(true);
|
||||||
|
UpdateMainSurfaceClip();
|
||||||
|
|
||||||
SetLocation();
|
SetLocation();
|
||||||
CustomerPanelSecurePassword.Init();
|
CustomerPanelSecurePassword.Init();
|
||||||
@@ -231,6 +244,16 @@ namespace C4IT_CustomerPanel
|
|||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
ComputerInfoCtrl.FillMainInfoGrid();
|
ComputerInfoCtrl.FillMainInfoGrid();
|
||||||
|
UpdateMainSurfaceClip();
|
||||||
|
ApplyRoundedWindowRegion();
|
||||||
|
|
||||||
|
if (!_mainSurfaceClipInitialized)
|
||||||
|
{
|
||||||
|
Dispatcher.BeginInvoke(new Action(UpdateMainSurfaceClip), DispatcherPriority.Loaded);
|
||||||
|
Dispatcher.BeginInvoke(new Action(UpdateMainSurfaceClip), DispatcherPriority.Render);
|
||||||
|
Dispatcher.BeginInvoke(new Action(ApplyRoundedWindowRegion), DispatcherPriority.Loaded);
|
||||||
|
Dispatcher.BeginInvoke(new Action(ApplyRoundedWindowRegion), DispatcherPriority.Render);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(AddressChangedCallback);
|
NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(AddressChangedCallback);
|
||||||
}
|
}
|
||||||
@@ -2157,9 +2180,139 @@ namespace C4IT_CustomerPanel
|
|||||||
|
|
||||||
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
|
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
UpdateMainSurfaceClip();
|
||||||
|
ApplyRoundedWindowRegion();
|
||||||
SetLocation();
|
SetLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateMainSurfaceClip()
|
||||||
|
{
|
||||||
|
if (MainWindowSurface == null || MainWindowContentRoot == null || MainGrid == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double surfaceWidth = MainWindowSurface.ActualWidth;
|
||||||
|
double surfaceHeight = MainWindowSurface.ActualHeight;
|
||||||
|
double contentWidth = MainWindowContentRoot.ActualWidth;
|
||||||
|
double contentHeight = MainWindowContentRoot.ActualHeight;
|
||||||
|
if (surfaceWidth <= 0 || surfaceHeight <= 0 || contentWidth <= 0 || contentHeight <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const double surfaceRadius = 20d;
|
||||||
|
const double contentRadius = 19d;
|
||||||
|
|
||||||
|
MainGrid.Clip = null;
|
||||||
|
this.Clip = null;
|
||||||
|
|
||||||
|
MainWindowSurface.Clip = new RectangleGeometry(new Rect(0d, 0d, surfaceWidth, surfaceHeight), surfaceRadius, surfaceRadius);
|
||||||
|
MainWindowContentRoot.Clip = new RectangleGeometry(new Rect(0d, 0d, contentWidth, contentHeight), contentRadius, contentRadius);
|
||||||
|
|
||||||
|
if (MainWindowCornerMaskOverlay != null)
|
||||||
|
{
|
||||||
|
MainWindowCornerMaskOverlay.Data = CreateCornerOverflowMaskGeometry(surfaceWidth, surfaceHeight, surfaceRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MainWindowFrameOverlay != null)
|
||||||
|
{
|
||||||
|
MainWindowFrameOverlay.Data = CreateFrameOverlayGeometry(surfaceWidth, surfaceHeight, surfaceRadius, 1d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btnSP != null && btnSP.ActualWidth > 0d && btnSP.ActualHeight > 0d)
|
||||||
|
{
|
||||||
|
btnSP.Clip = CreateBottomRoundedRectGeometry(btnSP.ActualWidth, btnSP.ActualHeight, contentRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainSurfaceClipInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Geometry CreateBottomRoundedRectGeometry(double width, double height, double radius)
|
||||||
|
{
|
||||||
|
if (width <= 0d || height <= 0d)
|
||||||
|
return Geometry.Empty;
|
||||||
|
|
||||||
|
double r = Math.Max(0d, Math.Min(radius, Math.Min(width / 2d, height / 2d)));
|
||||||
|
if (r <= 0d)
|
||||||
|
return new RectangleGeometry(new Rect(0d, 0d, width, height));
|
||||||
|
|
||||||
|
var geometry = new StreamGeometry();
|
||||||
|
using (var context = geometry.Open())
|
||||||
|
{
|
||||||
|
context.BeginFigure(new System.Windows.Point(0d, 0d), true, true);
|
||||||
|
context.LineTo(new System.Windows.Point(width, 0d), true, false);
|
||||||
|
context.LineTo(new System.Windows.Point(width, height - r), true, false);
|
||||||
|
context.ArcTo(new System.Windows.Point(width - r, height), new System.Windows.Size(r, r), 0d, false, SweepDirection.Clockwise, true, false);
|
||||||
|
context.LineTo(new System.Windows.Point(r, height), true, false);
|
||||||
|
context.ArcTo(new System.Windows.Point(0d, height - r), new System.Windows.Size(r, r), 0d, false, SweepDirection.Clockwise, true, false);
|
||||||
|
context.LineTo(new System.Windows.Point(0d, 0d), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry.Freeze();
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Geometry CreateCornerOverflowMaskGeometry(double width, double height, double radius)
|
||||||
|
{
|
||||||
|
if (width <= 0d || height <= 0d)
|
||||||
|
return Geometry.Empty;
|
||||||
|
|
||||||
|
double r = Math.Max(0d, Math.Min(radius, Math.Min(width / 2d, height / 2d)));
|
||||||
|
if (r <= 0d)
|
||||||
|
return Geometry.Empty;
|
||||||
|
|
||||||
|
var fullRect = new RectangleGeometry(new Rect(0d, 0d, width, height));
|
||||||
|
var roundedRect = new RectangleGeometry(new Rect(0d, 0d, width, height), r, r);
|
||||||
|
var mask = new CombinedGeometry(GeometryCombineMode.Exclude, fullRect, roundedRect);
|
||||||
|
mask.Freeze();
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Geometry CreateFrameOverlayGeometry(double width, double height, double radius, double strokeThickness)
|
||||||
|
{
|
||||||
|
if (width <= 0d || height <= 0d)
|
||||||
|
return Geometry.Empty;
|
||||||
|
|
||||||
|
double inset = Math.Max(0d, strokeThickness / 2d);
|
||||||
|
double frameWidth = Math.Max(0d, width - strokeThickness);
|
||||||
|
double frameHeight = Math.Max(0d, height - strokeThickness);
|
||||||
|
if (frameWidth <= 0d || frameHeight <= 0d)
|
||||||
|
return Geometry.Empty;
|
||||||
|
|
||||||
|
double frameRadius = Math.Max(0d, Math.Min(radius - inset, Math.Min(frameWidth / 2d, frameHeight / 2d)));
|
||||||
|
var frame = new RectangleGeometry(new Rect(inset, inset, frameWidth, frameHeight), frameRadius, frameRadius);
|
||||||
|
frame.Freeze();
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyRoundedWindowRegion()
|
||||||
|
{
|
||||||
|
if (!IsLoaded || WindowState == WindowState.Minimized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IntPtr hwnd = new WindowInteropHelper(this).Handle;
|
||||||
|
if (hwnd == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PresentationSource source = PresentationSource.FromVisual(this);
|
||||||
|
if (source?.CompositionTarget == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Matrix toDevice = source.CompositionTarget.TransformToDevice;
|
||||||
|
int pxWidth = Math.Max(1, (int)Math.Ceiling(ActualWidth * toDevice.M11));
|
||||||
|
int pxHeight = Math.Max(1, (int)Math.Ceiling(ActualHeight * toDevice.M22));
|
||||||
|
|
||||||
|
const double radiusDip = 20d;
|
||||||
|
int ellipseWidth = Math.Max(2, (int)Math.Ceiling(radiusDip * 2d * toDevice.M11));
|
||||||
|
int ellipseHeight = Math.Max(2, (int)Math.Ceiling(radiusDip * 2d * toDevice.M22));
|
||||||
|
|
||||||
|
IntPtr hRgn = CreateRoundRectRgn(0, 0, pxWidth + 1, pxHeight + 1, ellipseWidth, ellipseHeight);
|
||||||
|
if (hRgn == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SetWindowRgn(hwnd, hRgn, true) == 0)
|
||||||
|
{
|
||||||
|
DeleteObject(hRgn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class cMainFunctionInfo
|
public class cMainFunctionInfo
|
||||||
|
|||||||
Reference in New Issue
Block a user