Browse Source

[MONOMAC] Implemented maximize/unmaximize for borderless windows

pull/1005/head
Nikita Tsukanov 9 years ago
parent
commit
c954a86607
  1. 6
      samples/ControlCatalog/ControlCatalog.csproj
  2. 33
      samples/ControlCatalog/DecoratedWindow.xaml
  3. 53
      samples/ControlCatalog/DecoratedWindow.xaml.cs
  4. 2
      samples/ControlCatalog/MainView.xaml.cs
  5. 1
      samples/ControlCatalog/Pages/DialogsPage.xaml
  6. 4
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  7. 20
      src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs
  8. 36
      src/OSX/Avalonia.MonoMac/WindowImpl.cs

6
samples/ControlCatalog/ControlCatalog.csproj

@ -32,6 +32,9 @@
<EmbeddedResource Include="MainView.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="DecoratedWindow.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\DialogsPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
@ -86,6 +89,9 @@
<Compile Include="MainView.xaml.cs">
<DependentUpon>MainView.xaml</DependentUpon>
</Compile>
<Compile Include="DecoratedWindow.xaml.cs">
<DependentUpon>DecoratedWindow.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>

33
samples/ControlCatalog/DecoratedWindow.xaml

@ -0,0 +1,33 @@
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
Title="Avalonia Control Gallery"
Icon="resm:ControlCatalog.Assets.test_icon.ico?assembly=ControlCatalog"
xmlns:local="clr-namespace:ControlCatalog;assembly=ControlCatalog" HasSystemDecorations="False">
<Grid RowDefinitions="5,*,5" ColumnDefinitions="5,*,5">
<DockPanel Grid.Column="1" Grid.Row="1" >
<Grid Name="TitleBar" Background="LightBlue" DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto">
<TextBlock VerticalAlignment="Center" Margin="5,0,0,0">Title</TextBlock>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<StackPanel.Styles>
<Style Selector="Button">
<Setter Property="Margin" Value="2"/>
</Style>
</StackPanel.Styles>
<Button Name="MinimizeButton">_</Button>
<Button Name="MaximizeButton">[ ]</Button>
<Button Name="CloseButton">X</Button>
</StackPanel>
</Grid>
<Border Background="White" Margin="5">
<TextBlock>Hello world!</TextBlock>
</Border>
</DockPanel>
<Border Name="TopLeft" Background="Red"/>
<Border Name="TopRight" Background="Red" Grid.Column="2" />
<Border Name="BottomLeft" Background="Red" Grid.Row="2" />
<Border Name="BottomRight" Background="Red" Grid.Row="2" Grid.Column="2"/>
<Border Name="Top" Background="Blue" Grid.Column="1" />
<Border Name="Right" Background="Blue" Grid.Row="1" Grid.Column="2" />
<Border Name="Bottom" Background="Blue" Grid.Row="2" Grid.Column="1" />
<Border Name="Left" Background="Blue" Grid.Row="1" />
</Grid>
</Window>

53
samples/ControlCatalog/DecoratedWindow.xaml.cs

@ -0,0 +1,53 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System;
using Avalonia.Input;
namespace ControlCatalog
{
public class DecoratedWindow : Window
{
public DecoratedWindow()
{
this.InitializeComponent();
this.AttachDevTools();
}
void SetupSide(string name, StandardCursorType cursor, WindowEdge edge)
{
var ctl = this.FindControl<Control>(name);
ctl.Cursor = new Cursor(cursor);
ctl.PointerPressed += delegate
{
PlatformImpl.BeginResizeDrag(edge);
};
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
this.FindControl<Control>("TitleBar").PointerPressed += delegate
{
PlatformImpl.BeginMoveDrag();
};
SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West);
SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East);
SetupSide("Top", StandardCursorType.TopSide, WindowEdge.South);
SetupSide("Bottom", StandardCursorType.BottomSize, WindowEdge.North);
SetupSide("TopLeft", StandardCursorType.TopLeftCorner, WindowEdge.NorthWest);
SetupSide("TopRight", StandardCursorType.TopRightCorner, WindowEdge.NorthEast);
SetupSide("BottomLeft", StandardCursorType.BottomLeftCorner, WindowEdge.SouthWest);
SetupSide("BottomRight", StandardCursorType.BottomRightCorner, WindowEdge.SouthEast);
this.FindControl<Button>("MinimizeButton").Click += delegate { this.WindowState = WindowState.Minimized; };
this.FindControl<Button>("MaximizeButton").Click += delegate
{
WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
};
this.FindControl<Button>("CloseButton").Click += delegate
{
Close();
};
}
}
}

2
samples/ControlCatalog/MainView.xaml.cs

@ -15,7 +15,7 @@ namespace ControlCatalog
if (AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().IsDesktop)
((IList) this.FindControl<TabControl>("Sidebar").Items).Add(new TabItem()
{
Header = "System dialogs",
Header = "Dialogs",
Content = new DialogsPage()
});
}

1
samples/ControlCatalog/Pages/DialogsPage.xaml

@ -7,5 +7,6 @@
<CheckBox Name="IsModal" IsChecked="True"/>
<TextBlock>Modal to window</TextBlock>
</StackPanel>
<Button Name="DecoratedWindow">Decorated window</Button>
</StackPanel>
</UserControl>

4
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@ -30,6 +30,10 @@ namespace ControlCatalog.Pages
Title = "Select folder"
}.ShowAsync(GetWindow());
};
this.FindControl<Button>("DecoratedWindow").Click += delegate
{
new DecoratedWindow().Show();
};
}
Window GetWindow() => this.FindControl<CheckBox>("IsModal").IsChecked ? (Window)this.VisualRoot : null;

20
src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs

@ -2,6 +2,7 @@
using Avalonia.Controls;
using Avalonia.Platform;
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
using MonoMac.ObjCRuntime;
namespace Avalonia.MonoMac
@ -42,6 +43,12 @@ namespace Avalonia.MonoMac
_impl.Deactivated?.Invoke();
base.ResignKeyWindow();
}
private bool _canBecomeKeyAndMain;
public override bool CanBecomeKeyWindow => _canBecomeKeyAndMain;
public override bool CanBecomeMainWindow => _canBecomeKeyAndMain;
public void SetCanBecomeKeyAndMain() => _canBecomeKeyAndMain = true;
}
protected virtual NSWindowDelegate CreateWindowDelegate() => new WindowBaseDelegate(this);
@ -49,6 +56,7 @@ namespace Avalonia.MonoMac
public class WindowBaseDelegate : NSWindowDelegate
{
readonly WindowBaseImpl _impl;
private CGRect? _lastUnmaximizedFrame;
public WindowBaseDelegate(WindowBaseImpl impl)
{
@ -66,6 +74,18 @@ namespace Avalonia.MonoMac
_impl.Window = null;
_impl.Dispose();
}
public override CGRect WillUseStandardFrame(NSWindow window, CGRect newFrame)
{
if (_impl is WindowImpl w && w.UndecoratedIsMaximized && w.UndecoratedLastUnmaximizedFrame.HasValue)
return w.UndecoratedLastUnmaximizedFrame.Value;
return window.Screen.VisibleFrame;
}
public override bool ShouldZoom(NSWindow window, CGRect newFrame)
{
return true;
}
}

36
src/OSX/Avalonia.MonoMac/WindowImpl.cs

@ -2,16 +2,19 @@
using Avalonia.Controls;
using Avalonia.Platform;
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
namespace Avalonia.MonoMac
{
class WindowImpl : WindowBaseImpl, IWindowImpl
{
bool _decorated = true;
public bool IsDecorated = true;
public CGRect? UndecoratedLastUnmaximizedFrame;
public WindowImpl()
{
UpdateStyle();
Window.SetCanBecomeKeyAndMain();
}
public WindowState WindowState
@ -20,8 +23,9 @@ namespace Avalonia.MonoMac
{
if (Window.IsMiniaturized)
return WindowState.Minimized;
if (IsZoomed)
return WindowState.Maximized;
return WindowState.Normal;
}
set
{
@ -29,8 +33,8 @@ namespace Avalonia.MonoMac
{
if (Window.IsMiniaturized)
Window.Deminiaturize(Window);
if (!Window.IsZoomed)
Window.PerformZoom(Window);
if (!IsZoomed)
DoZoom();
}
else if (value.HasFlag(WindowState.Minimized))
Window.Miniaturize(Window);
@ -38,12 +42,28 @@ namespace Avalonia.MonoMac
{
if (Window.IsMiniaturized)
Window.Deminiaturize(Window);
if (Window.IsZoomed)
Window.IsZoomed = false;
if (IsZoomed)
DoZoom();
}
}
}
bool IsZoomed => IsDecorated ? Window.IsZoomed : UndecoratedIsMaximized;
public bool UndecoratedIsMaximized => Window.Frame == Window.Screen.VisibleFrame;
void DoZoom()
{
if (IsDecorated)
Window.PerformZoom(Window);
else
{
if (!UndecoratedIsMaximized)
UndecoratedLastUnmaximizedFrame = Window.Frame;
Window.Zoom(Window);
}
}
public void SetIcon(IWindowIconImpl icon)
{
//No-OP, see http://stackoverflow.com/a/7038671/2231814
@ -56,7 +76,7 @@ namespace Avalonia.MonoMac
protected override NSWindowStyle GetStyle()
{
if (_decorated)
if (IsDecorated)
return NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Miniaturizable |
NSWindowStyle.Titled;
return NSWindowStyle.Borderless;
@ -64,7 +84,7 @@ namespace Avalonia.MonoMac
public void SetSystemDecorations(bool enabled)
{
_decorated = true;
IsDecorated = enabled;
UpdateStyle();
}

Loading…
Cancel
Save