Browse Source

add hints for further control over chrome.

demo1
Dan Walmsley 6 years ago
parent
commit
37e4e68b9d
  1. 17
      src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs
  2. 6
      src/Avalonia.Controls/Platform/IWindowImpl.cs
  3. 14
      src/Avalonia.Controls/Window.cs
  4. 14
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  5. 14
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  6. 14
      src/Avalonia.Native/WindowImpl.cs
  7. 14
      src/Avalonia.X11/X11Window.cs
  8. 6
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  9. 74
      src/Windows/Avalonia.Win32/WindowImpl.cs

17
src/Avalonia.Controls/Platform/ExtendClientAreaChromeHints.cs

@ -0,0 +1,17 @@
using System;
namespace Avalonia.Platform
{
[Flags]
public enum ExtendClientAreaChromeHints
{
Default = SystemTitleBar | SystemChromeButtons,
NoChrome,
SystemTitleBar = 0x01,
SystemChromeButtons = 0x02,
ManagedChromeButtons = 0x04,
PreferSystemChromeButtons = 0x08,
AdaptiveChromeWithTitleBar = SystemTitleBar | PreferSystemChromeButtons,
AdaptiveChromeWithoutTitleBar = PreferSystemChromeButtons,
}
}

6
src/Avalonia.Controls/Platform/IWindowImpl.cs

@ -95,7 +95,11 @@ namespace Avalonia.Platform
/// ///
void SetMinMaxSize(Size minSize, Size maxSize); void SetMinMaxSize(Size minSize, Size maxSize);
bool ExtendClientAreaToDecorationsHint { get; set; } void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint);
bool IsClientAreaExtendedToDecorations { get; }
void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints);
Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }

14
src/Avalonia.Controls/Window.cs

@ -95,6 +95,9 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> ExtendClientAreaToDecorationsHintProperty = public static readonly StyledProperty<bool> ExtendClientAreaToDecorationsHintProperty =
AvaloniaProperty.Register<Window, bool>(nameof(ExtendClientAreaToDecorationsHint), false); AvaloniaProperty.Register<Window, bool>(nameof(ExtendClientAreaToDecorationsHint), false);
public static readonly StyledProperty<ExtendClientAreaChromeHints> ExtendClientAreaChromeHintsProperty =
AvaloniaProperty.Register<Window, ExtendClientAreaChromeHints>(nameof(ExtendClientAreaChromeHints), ExtendClientAreaChromeHints.Default);
/// <summary> /// <summary>
/// Defines the <see cref="IsExtendedIntoWindowDecorations"/> property. /// Defines the <see cref="IsExtendedIntoWindowDecorations"/> property.
@ -190,7 +193,10 @@ namespace Avalonia.Controls
(w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.WindowState = (WindowState)e.NewValue; }); (w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.WindowState = (WindowState)e.NewValue; });
ExtendClientAreaToDecorationsHintProperty.Changed.AddClassHandler<Window>( ExtendClientAreaToDecorationsHintProperty.Changed.AddClassHandler<Window>(
(w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.ExtendClientAreaToDecorationsHint = (bool)e.NewValue; }); (w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.SetExtendClientAreaToDecorationsHint((bool)e.NewValue); });
ExtendClientAreaChromeHintsProperty.Changed.AddClassHandler<Window>(
(w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.SetExtendClientAreaChromeHints((ExtendClientAreaChromeHints)e.NewValue); });
MinWidthProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size((double)e.NewValue, w.MinHeight), new Size(w.MaxWidth, w.MaxHeight))); MinWidthProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size((double)e.NewValue, w.MinHeight), new Size(w.MaxWidth, w.MaxHeight)));
MinHeightProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, (double)e.NewValue), new Size(w.MaxWidth, w.MaxHeight))); MinHeightProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, (double)e.NewValue), new Size(w.MaxWidth, w.MaxHeight)));
@ -275,6 +281,12 @@ namespace Avalonia.Controls
set { SetValue(ExtendClientAreaToDecorationsHintProperty, value); } set { SetValue(ExtendClientAreaToDecorationsHintProperty, value); }
} }
public ExtendClientAreaChromeHints ExtendClientAreaChromeHints
{
get => GetValue(ExtendClientAreaChromeHintsProperty);
set => SetValue(ExtendClientAreaChromeHintsProperty, value);
}
/// <summary> /// <summary>
/// Gets if the ClientArea is Extended into the Window Decorations. /// Gets if the ClientArea is Extended into the Window Decorations.
/// </summary> /// </summary>

14
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -83,14 +83,14 @@ namespace Avalonia.DesignerSupport.Remote
} }
public IScreenImpl Screen { get; } = new ScreenStub(); public IScreenImpl Screen { get; } = new ScreenStub();
public Action GotInputWhenDisabled { get; set; } public Action GotInputWhenDisabled { get; set; }
public bool ExtendClientAreaToDecorationsHint { get; set; }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; } = new Thickness(); public Thickness ExtendedMargins { get; } = new Thickness();
public bool IsClientAreaExtendedToDecorations { get; }
public void Activate() public void Activate()
{ {
} }
@ -130,5 +130,13 @@ namespace Avalonia.DesignerSupport.Remote
public void SetEnabled(bool enable) public void SetEnabled(bool enable)
{ {
} }
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint)
{
}
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints)
{
}
} }
} }

14
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -37,9 +37,7 @@ namespace Avalonia.DesignerSupport.Remote
public WindowState WindowState { get; set; } public WindowState WindowState { get; set; }
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState> WindowStateChanged { get; set; }
public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; } public Action<WindowTransparencyLevel> TransparencyLevelChanged { get; set; }
public bool ExtendClientAreaToDecorationsHint { get; set; }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
@ -146,6 +144,14 @@ namespace Avalonia.DesignerSupport.Remote
{ {
} }
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint)
{
}
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints)
{
}
public IPopupPositioner PopupPositioner { get; } public IPopupPositioner PopupPositioner { get; }
public Action GotInputWhenDisabled { get; set; } public Action GotInputWhenDisabled { get; set; }
@ -157,6 +163,8 @@ namespace Avalonia.DesignerSupport.Remote
} }
public WindowTransparencyLevel TransparencyLevel { get; private set; } public WindowTransparencyLevel TransparencyLevel { get; private set; }
public bool IsClientAreaExtendedToDecorations { get; }
} }
class ClipboardStub : IClipboard class ClipboardStub : IClipboard

14
src/Avalonia.Native/WindowImpl.cs

@ -96,14 +96,22 @@ namespace Avalonia.Native
} }
} }
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState> WindowStateChanged { get; set; }
public bool ExtendClientAreaToDecorationsHint { get; set; }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; } = new Thickness(); public Thickness ExtendedMargins { get; } = new Thickness();
public bool IsClientAreaExtendedToDecorations { get; }
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint)
{
}
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints)
{
}
public void ShowTaskbarIcon(bool value) public void ShowTaskbarIcon(bool value)
{ {
// NO OP On OSX // NO OP On OSX

14
src/Avalonia.X11/X11Window.cs

@ -309,14 +309,14 @@ namespace Avalonia.X11
{ {
get => _transparencyHelper.TransparencyLevelChanged; get => _transparencyHelper.TransparencyLevelChanged;
set => _transparencyHelper.TransparencyLevelChanged = value; set => _transparencyHelper.TransparencyLevelChanged = value;
} }
public bool ExtendClientAreaToDecorationsHint { get; set; }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; } = new Thickness(); public Thickness ExtendedMargins { get; } = new Thickness();
public bool IsClientAreaExtendedToDecorations { get; }
public Action Closed { get; set; } public Action Closed { get; set; }
public Action<PixelPoint> PositionChanged { get; set; } public Action<PixelPoint> PositionChanged { get; set; }
@ -1041,6 +1041,14 @@ namespace Avalonia.X11
_disabled = !enable; _disabled = !enable;
} }
public void SetExtendClientAreaToDecorationsHint(bool extendIntoClientAreaHint)
{
}
public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints)
{
}
public Action GotInputWhenDisabled { get; set; } public Action GotInputWhenDisabled { get; set; }
public void SetIcon(IWindowIconImpl icon) public void SetIcon(IWindowIconImpl icon)

6
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -989,6 +989,12 @@ namespace Avalonia.Win32.Interop
} }
} }
[DllImport("user32.dll")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

74
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -41,6 +41,7 @@ namespace Avalonia.Win32
private SavedWindowInfo _savedWindowInfo; private SavedWindowInfo _savedWindowInfo;
private bool _isFullScreenActive; private bool _isFullScreenActive;
private bool _isClientAreaExtended; private bool _isClientAreaExtended;
private Thickness _extendedMargins;
#if USE_MANAGED_DRAG #if USE_MANAGED_DRAG
private readonly ManagedWindowResizeDragHelper _managedDrag; private readonly ManagedWindowResizeDragHelper _managedDrag;
@ -666,7 +667,7 @@ namespace Avalonia.Win32
TaskBarList.MarkFullscreen(_hwnd, fullscreen); TaskBarList.MarkFullscreen(_hwnd, fullscreen);
} }
private void ExtendClientArea () private void ExtendClientArea (ExtendClientAreaChromeHints hints)
{ {
if (!_isClientAreaExtended) if (!_isClientAreaExtended)
{ {
@ -683,6 +684,16 @@ namespace Avalonia.Win32
AdjustWindowRectEx(ref border_thickness, (uint)(GetStyle()), false, 0); AdjustWindowRectEx(ref border_thickness, (uint)(GetStyle()), false, 0);
border_thickness.left *= -1; border_thickness.left *= -1;
border_thickness.top *= -1; border_thickness.top *= -1;
border_thickness.left = 1;
border_thickness.bottom = 1;
border_thickness.right = 1;
if (!hints.HasFlag(ExtendClientAreaChromeHints.SystemTitleBar))
{
border_thickness.top = 1;
}
} }
else if (GetStyle().HasFlag(WindowStyles.WS_BORDER)) else if (GetStyle().HasFlag(WindowStyles.WS_BORDER))
{ {
@ -697,6 +708,19 @@ namespace Avalonia.Win32
var hr = DwmExtendFrameIntoClientArea(_hwnd, ref margins); var hr = DwmExtendFrameIntoClientArea(_hwnd, ref margins);
if(!hints.HasFlag(ExtendClientAreaChromeHints.SystemChromeButtons) ||
(hints.HasFlag(ExtendClientAreaChromeHints.PreferSystemChromeButtons) &&
!hints.HasFlag(ExtendClientAreaChromeHints.SystemTitleBar)))
{
var style = GetStyle();
style &= ~(WindowStyles.WS_MINIMIZEBOX | WindowStyles.WS_MAXIMIZEBOX | WindowStyles.WS_SYSMENU);
SetStyle(style);
DisableCloseButton(_hwnd);
}
if (hr == 0) if (hr == 0)
{ {
_isClientAreaExtended = true; _isClientAreaExtended = true;
@ -854,9 +878,10 @@ namespace Avalonia.Win32
// Otherwise it will still show in the taskbar. // Otherwise it will still show in the taskbar.
} }
WindowStyles style;
if ((oldProperties.IsResizable != newProperties.IsResizable) || forceChanges) if ((oldProperties.IsResizable != newProperties.IsResizable) || forceChanges)
{ {
var style = GetStyle(); style = GetStyle();
if (newProperties.IsResizable) if (newProperties.IsResizable)
{ {
@ -877,7 +902,7 @@ namespace Avalonia.Win32
if ((oldProperties.Decorations != newProperties.Decorations) || forceChanges) if ((oldProperties.Decorations != newProperties.Decorations) || forceChanges)
{ {
var style = GetStyle(); style = GetStyle();
const WindowStyles fullDecorationFlags = WindowStyles.WS_CAPTION | WindowStyles.WS_SYSMENU; const WindowStyles fullDecorationFlags = WindowStyles.WS_CAPTION | WindowStyles.WS_SYSMENU;
@ -922,7 +947,26 @@ namespace Avalonia.Win32
SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOACTIVATE |
SetWindowPosFlags.SWP_FRAMECHANGED); SetWindowPosFlags.SWP_FRAMECHANGED);
} }
} }
}
private const int MF_BYCOMMAND = 0x0;
private const int MF_BYPOSITION = 0x400;
private const int MF_REMOVE = 0x1000;
private const int MF_ENABLED = 0x0;
private const int MF_GRAYED = 0x1;
private const int MF_DISABLED = 0x2;
private const int SC_CLOSE = 0xF060;
void DisableCloseButton(IntPtr hwnd)
{
EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
void EnableCloseButton(IntPtr hwnd)
{
EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE,
MF_BYCOMMAND | MF_ENABLED);
} }
#if USE_MANAGED_DRAG #if USE_MANAGED_DRAG
@ -946,23 +990,23 @@ namespace Avalonia.Win32
} }
} }
IntPtr EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo.Handle => Handle.Handle; IntPtr EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo.Handle => Handle.Handle;
public bool ExtendClientAreaToDecorationsHint public void SetExtendClientAreaToDecorationsHint(bool hint)
{ {
get => _extendClientAreaToDecorationsHint; ExtendClientArea(_extendChromeHints);
set }
{
_extendClientAreaToDecorationsHint = true;
ExtendClientArea(); private ExtendClientAreaChromeHints _extendChromeHints = ExtendClientAreaChromeHints.Default;
// TODO Trigger transition.
} public void SetExtendClientAreaChromeHints(ExtendClientAreaChromeHints hints)
{
_extendChromeHints = hints;
} }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public bool IsClientAreaExtendedToDecorations => _isClientAreaExtended;
private Thickness _extendedMargins; public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins => _extendedMargins; public Thickness ExtendedMargins => _extendedMargins;

Loading…
Cancel
Save