Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CanResize to Window #1522

Merged
merged 4 commits into from May 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Avalonia.Controls/Platform/IWindowImpl.cs
Expand Up @@ -45,6 +45,11 @@ public interface IWindowImpl : IWindowBaseImpl
/// </summary>
void ShowTaskbarIcon(bool value);

/// <summary>
/// Enables or disables resizing of the window
/// </summary>
void CanResize(bool value);

/// <summary>
/// Gets or sets a method called before the underlying implementation is destroyed.
/// Return true to prevent the underlying implementation from closing.
Expand Down
14 changes: 14 additions & 0 deletions src/Avalonia.Controls/Window.cs
Expand Up @@ -95,6 +95,9 @@ public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot, INameSco
o => o.WindowStartupLocation,
(o, v) => o.WindowStartupLocation = v);

public static readonly StyledProperty<bool> CanResizeProperty =
AvaloniaProperty.Register<Window, bool>(nameof(CanResize), true);

private readonly NameScope _nameScope = new NameScope();
private object _dialogResult;
private readonly Size _maxPlatformClientSize;
Expand All @@ -113,6 +116,8 @@ static Window()
ShowInTaskbarProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.ShowTaskbarIcon((bool)e.NewValue));

IconProperty.Changed.AddClassHandler<Window>((s, e) => s.PlatformImpl?.SetIcon(((WindowIcon)e.NewValue).PlatformImpl));

CanResizeProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.CanResize((bool)e.NewValue));
}

/// <summary>
Expand Down Expand Up @@ -208,6 +213,15 @@ public WindowState WindowState
}
}

/// <summary>
/// Enables or disables resizing of the window
/// </summary>
public bool CanResize
{
get { return GetValue(CanResizeProperty); }
set { SetValue(CanResizeProperty, value); }
}

/// <summary>
/// Gets or sets the icon of the window.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
Expand Up @@ -93,5 +93,9 @@ public void SetIcon(IWindowIconImpl icon)
public void ShowTaskbarIcon(bool value)
{
}

public void CanResize(bool value)
{
}
}
}
4 changes: 4 additions & 0 deletions src/Avalonia.DesignerSupport/Remote/Stubs.cs
Expand Up @@ -95,6 +95,10 @@ public void SetIcon(IWindowIconImpl icon)
public void ShowTaskbarIcon(bool value)
{
}

public void CanResize(bool value)
{
}
}

class ClipboardStub : IClipboard
Expand Down
3 changes: 3 additions & 0 deletions src/Gtk/Avalonia.Gtk3/Interop/Native.cs
Expand Up @@ -115,6 +115,8 @@ public static class D
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_title(GtkWindow gtkWindow, Utf8Buffer title);

[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_resizable(GtkWindow gtkWindow, bool resizable);

[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_decorated(GtkWindow gtkWindow, bool decorated);
Expand Down Expand Up @@ -395,6 +397,7 @@ public static class D
public static D.gdk_screen_get_monitor_geometry GdkScreenGetMonitorGeometry;
public static D.gdk_screen_get_monitor_workarea GdkScreenGetMonitorWorkarea;
public static D.gtk_window_set_decorated GtkWindowSetDecorated;
public static D.gtk_window_set_resizable GtkWindowSetResizable;
public static D.gtk_window_set_skip_taskbar_hint GtkWindowSetSkipTaskbarHint;
public static D.gtk_window_get_skip_taskbar_hint GtkWindowGetSkipTaskbarHint;
public static D.gtk_window_set_skip_pager_hint GtkWindowSetSkipPagerHint;
Expand Down
2 changes: 2 additions & 0 deletions src/Gtk/Avalonia.Gtk3/WindowImpl.cs
Expand Up @@ -61,6 +61,8 @@ public void SetCoverTaskbarWhenMaximized(bool enable)
}

public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value);

public void CanResize(bool value) => Native.GtkWindowSetResizable(GtkWidget, value);


class EmptyDisposable : IDisposable
Expand Down
18 changes: 15 additions & 3 deletions src/OSX/Avalonia.MonoMac/WindowImpl.cs
Expand Up @@ -9,6 +9,7 @@ namespace Avalonia.MonoMac
class WindowImpl : WindowBaseImpl, IWindowImpl
{
public bool IsDecorated = true;
public bool IsResizable = true;
public CGRect? UndecoratedLastUnmaximizedFrame;

public WindowImpl()
Expand Down Expand Up @@ -76,10 +77,15 @@ public void ShowTaskbarIcon(bool value)

protected override NSWindowStyle GetStyle()
{
var windowStyle = NSWindowStyle.Borderless;

if (IsDecorated)
return NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Miniaturizable |
NSWindowStyle.Titled;
return NSWindowStyle.Borderless;
windowStyle |= NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Titled;

if (IsResizable)
windowStyle |= NSWindowStyle.Resizable;

return windowStyle;
}

public void SetSystemDecorations(bool enabled)
Expand All @@ -88,6 +94,12 @@ public void SetSystemDecorations(bool enabled)
UpdateStyle();
}

public void CanResize(bool value)
{
IsResizable = value;
UpdateStyle();
}

public void SetTitle(string title) => Window.Title = title;

class ModalDisposable : IDisposable
Expand Down
13 changes: 12 additions & 1 deletion src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
Expand Up @@ -558,7 +558,18 @@ public enum DIBColorTable
{
DIB_RGB_COLORS = 0, /* color table in RGBs */
DIB_PAL_COLORS /* color table in palette indices */
};
}

public enum WindowLongParam
{
GWL_WNDPROC = -4,
GWL_HINSTANCE = -6,
GWL_HWNDPARENT = -8,
GWL_ID = -12,
GWL_STYLE = -16,
GWL_EXSTYLE = -20,
GWL_USERDATA = -21
}

[StructLayout(LayoutKind.Sequential)]
public struct RGBQUAD
Expand Down
47 changes: 36 additions & 11 deletions src/Windows/Avalonia.Win32/WindowImpl.cs
Expand Up @@ -31,6 +31,7 @@ public class WindowImpl : IWindowImpl
private IInputRoot _owner;
private bool _trackingMouse;
private bool _decorated = true;
private bool _resizable = true;
private double _scaling = 1;
private WindowState _showWindowState;
private FramebufferManager _framebuffer;
Expand Down Expand Up @@ -77,8 +78,8 @@ public Thickness BorderThickness
{
get
{
var style = UnmanagedMethods.GetWindowLong(_hwnd, -16);
var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, -20);
var style = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
var padding = new UnmanagedMethods.RECT();

if (UnmanagedMethods.AdjustWindowRectEx(ref padding, style, false, exStyle))
Expand Down Expand Up @@ -235,13 +236,19 @@ public void SetSystemDecorations(bool value)
return;
}

var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -16);
var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);

style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW;
var systemDecorationStyles = UnmanagedMethods.WindowStyles.WS_OVERLAPPED
| UnmanagedMethods.WindowStyles.WS_CAPTION
| UnmanagedMethods.WindowStyles.WS_SYSMENU
| UnmanagedMethods.WindowStyles.WS_MINIMIZEBOX
| UnmanagedMethods.WindowStyles.WS_MAXIMIZEBOX;

style |= systemDecorationStyles;

if (!value)
{
style ^= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW;
style ^= systemDecorationStyles;
}

UnmanagedMethods.RECT windowRect;
Expand All @@ -251,7 +258,7 @@ public void SetSystemDecorations(bool value)
Rect newRect;
var oldThickness = BorderThickness;

UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint)style);
UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style);

if (value)
{
Expand Down Expand Up @@ -798,11 +805,11 @@ private static int ToInt32(IntPtr ptr)

public void ShowTaskbarIcon(bool value)
{
var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -20);

style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);

style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);

style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
if (value)
style |= UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW;
else
Expand All @@ -813,9 +820,27 @@ public void ShowTaskbarIcon(bool value)
{
//Toggle to make the styles stick
UnmanagedMethods.ShowWindow(_hwnd, ShowWindowCommand.Hide);
UnmanagedMethods.SetWindowLong(_hwnd, -20, (uint)style);
UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE, (uint)style);
UnmanagedMethods.ShowWindow(_hwnd, windowPlacement.ShowCmd);
}
}

public void CanResize(bool value)
{
if (value == _resizable)
{
return;
}

var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);

if (value)
style |= UnmanagedMethods.WindowStyles.WS_SIZEFRAME;
else
style &= ~(UnmanagedMethods.WindowStyles.WS_SIZEFRAME);

UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style);
_resizable = value;
}
}
}