mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Change Titlebar to Custom TitleBar (SettingWindow)
This commit is contained in:
parent
b7d5f4f342
commit
979a7b8b7b
3 changed files with 2084 additions and 1768 deletions
|
|
@ -4,6 +4,89 @@
|
|||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:ui="http://schemas.modernwpf.com/2019">
|
||||
|
||||
|
||||
<!-- Title Bar -->
|
||||
|
||||
<Style x:Key="WindowMainPanelStyle" TargetType="{x:Type Border}">
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource WindowBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximized">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TitleBarButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="{DynamicResource WindowTextBrush}" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border
|
||||
x:Name="border"
|
||||
Background="#f3f3f3"
|
||||
BorderThickness="0"
|
||||
SnapsToDevicePixels="true">
|
||||
<ContentPresenter
|
||||
x:Name="contentPresenter"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Focusable="False"
|
||||
RecognizesAccessKey="True" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter TargetName="border" Property="Background" Value="#C6C6C6" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter TargetName="border" Property="Background" Value="#B0B0B0" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TitleBarCloseButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border
|
||||
x:Name="border"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
SnapsToDevicePixels="true">
|
||||
<ContentPresenter
|
||||
x:Name="contentPresenter"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Focusable="False"
|
||||
RecognizesAccessKey="True" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter TargetName="border" Property="Background" Value="#E10000" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MouseOverWindowCloseButtonForegroundBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter TargetName="border" Property="Background" Value="{DynamicResource PressedWindowCloseButtonBackgroundBrush}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MouseOverWindowCloseButtonForegroundBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Repeat Button -->
|
||||
<Style x:Key="DefaultRepeatButtonStyle" TargetType="RepeatButton">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -15,6 +15,7 @@ using Flow.Launcher.ViewModel;
|
|||
using Flow.Launcher.Helper;
|
||||
using System.Windows.Controls;
|
||||
using Flow.Launcher.Core.ExternalPlugins;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
|
|
@ -297,5 +298,146 @@ namespace Flow.Launcher
|
|||
textBox.MoveFocus(tRequest);
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom TitleBar */
|
||||
|
||||
private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
private void OnMaximizeRestoreButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.WindowState == WindowState.Maximized)
|
||||
{
|
||||
this.WindowState = WindowState.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.WindowState = WindowState.Maximized;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCloseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void RefreshMaximizeRestoreButton()
|
||||
{
|
||||
if (this.WindowState == WindowState.Maximized)
|
||||
{
|
||||
this.maximizeButton.Visibility = Visibility.Collapsed;
|
||||
this.restoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.maximizeButton.Visibility = Visibility.Visible;
|
||||
this.restoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Window_StateChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.RefreshMaximizeRestoreButton();
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
base.OnSourceInitialized(e);
|
||||
((HwndSource)PresentationSource.FromVisual(this)).AddHook(HookProc);
|
||||
}
|
||||
|
||||
public static IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == WM_GETMINMAXINFO)
|
||||
{
|
||||
// We need to tell the system what our size should be when maximized. Otherwise it will cover the whole screen,
|
||||
// including the task bar.
|
||||
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
|
||||
|
||||
// Adjust the maximized size and position to fit the work area of the correct monitor
|
||||
IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
if (monitor != IntPtr.Zero)
|
||||
{
|
||||
MONITORINFO monitorInfo = new MONITORINFO();
|
||||
monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
|
||||
GetMonitorInfo(monitor, ref monitorInfo);
|
||||
RECT rcWorkArea = monitorInfo.rcWork;
|
||||
RECT rcMonitorArea = monitorInfo.rcMonitor;
|
||||
mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
|
||||
mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
|
||||
mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
|
||||
mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
|
||||
}
|
||||
|
||||
Marshal.StructureToPtr(mmi, lParam, true);
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private const int WM_GETMINMAXINFO = 0x0024;
|
||||
|
||||
private const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr MonitorFromWindow(IntPtr handle, uint flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
||||
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
this.Left = left;
|
||||
this.Top = top;
|
||||
this.Right = right;
|
||||
this.Bottom = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MONITORINFO
|
||||
{
|
||||
public int cbSize;
|
||||
public RECT rcMonitor;
|
||||
public RECT rcWork;
|
||||
public uint dwFlags;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public POINT(int x, int y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MINMAXINFO
|
||||
{
|
||||
public POINT ptReserved;
|
||||
public POINT ptMaxSize;
|
||||
public POINT ptMaxPosition;
|
||||
public POINT ptMinTrackSize;
|
||||
public POINT ptMaxTrackSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue