Merge branch 'ifromstone-dev/MacOSUIImprovement'
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL || PLATFORM_MAC
|
||||
#define USE_IS_FOREGROUND
|
||||
#else
|
||||
#endif
|
||||
#if PLATFORM_SDL
|
||||
#if PLATFORM_SDL || PLATFORM_MAC
|
||||
#define USE_SDL_WORKAROUNDS
|
||||
#endif
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
@@ -189,12 +189,18 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Determined automatically based on the system and any known compatibility issues with native decorations.
|
||||
/// </summary>
|
||||
#if PLATFORM_MAC && !PLATFORM_SDL
|
||||
[HideInEditor]
|
||||
#endif
|
||||
Auto,
|
||||
|
||||
/// <summary>
|
||||
/// Automatically choose most compatible window decorations for child windows, prefer custom decorations on main window.
|
||||
/// </summary>
|
||||
[EditorDisplay(Name = "Auto (Child Only)")]
|
||||
#if PLATFORM_MAC && !PLATFORM_SDL
|
||||
[HideInEditor]
|
||||
#endif
|
||||
AutoChildOnly,
|
||||
|
||||
/// <summary>
|
||||
@@ -307,18 +313,18 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Interface"), EditorOrder(322)]
|
||||
public bool ScrollToScriptOnAdd { get; set; } = true;
|
||||
|
||||
#if PLATFORM_SDL
|
||||
#if PLATFORM_SDL || PLATFORM_MAC
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether use native window title bar decorations in child windows. Editor restart required.
|
||||
/// </summary>
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_MAC
|
||||
[DefaultValue(WindowDecorationsType.ClientSide)]
|
||||
#else
|
||||
[DefaultValue(WindowDecorationsType.AutoChildOnly)]
|
||||
#endif
|
||||
[EditorDisplay("Tabs & Windows"), EditorOrder(70), Tooltip("Determines whether use native window title bar decorations. Editor restart required.")]
|
||||
public WindowDecorationsType WindowDecorations { get; set; } =
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_MAC
|
||||
WindowDecorationsType.ClientSide;
|
||||
#else
|
||||
WindowDecorationsType.AutoChildOnly;
|
||||
|
||||
@@ -1293,6 +1293,12 @@ namespace FlaxEditor.Utilities
|
||||
};
|
||||
#elif PLATFORM_WINDOWS
|
||||
return !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
|
||||
#elif PLATFORM_MAC
|
||||
return Editor.Instance.Options.Options.Interface.WindowDecorations switch
|
||||
{
|
||||
Options.InterfaceOptions.WindowDecorationsType.ClientSide => true,
|
||||
_ => false
|
||||
};
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@ struct Transform;
|
||||
template<typename T>
|
||||
class AssetReference;
|
||||
struct ScriptingTypeHandle;
|
||||
template<typename Type> ScriptingTypeHandle StaticType();
|
||||
|
||||
/// <summary>
|
||||
/// Represents an object type that can be interpreted as more than one type.
|
||||
|
||||
@@ -200,6 +200,19 @@ Float2 GetMousePosition(MacWindow* window, NSEvent* event)
|
||||
return Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||
}
|
||||
|
||||
NSRect GetFrameRectForClientBounds(MacWindow* macWindow, NSWindow* window, const Rectangle& clientArea)
|
||||
{
|
||||
const float screenScale = MacPlatform::ScreenScale;
|
||||
NSRect rect = NSMakeRect(0, 0, clientArea.Size.X / screenScale, clientArea.Size.Y / screenScale);
|
||||
rect = [window frameRectForContentRect:rect];
|
||||
|
||||
Float2 pos = AppleUtils::PosToCoca(clientArea.Location) / screenScale;
|
||||
Float2 titleSize = GetWindowTitleSize(macWindow);
|
||||
rect.origin.x = pos.X + titleSize.X;
|
||||
rect.origin.y = pos.Y - rect.size.height + titleSize.Y;
|
||||
return rect;
|
||||
}
|
||||
|
||||
class MacDropData : public IGuiData
|
||||
{
|
||||
public:
|
||||
@@ -310,6 +323,12 @@ NSDragOperation GetDragDropOperation(DragDropEffect dragDropEffect)
|
||||
Window->OnLostFocus();
|
||||
}
|
||||
|
||||
- (void)windowDidMove:(NSNotification*)notification
|
||||
{
|
||||
if (IsWindowInvalid(Window)) return;
|
||||
Window->SyncWindowState();
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification
|
||||
{
|
||||
[self setDelegate: nil];
|
||||
@@ -518,6 +537,28 @@ static void ConvertNSRect(NSScreen *screen, NSRect *r)
|
||||
if (IsWindowInvalid(Window)) return;
|
||||
Float2 mousePos = GetMousePosition(Window, event);
|
||||
mousePos = Window->ClientToScreen(mousePos);
|
||||
|
||||
if ([event clickCount] == 1 && !Input::Mouse->IsRelative())
|
||||
{
|
||||
WindowHitCodes hit = WindowHitCodes::Client;
|
||||
bool handled = false;
|
||||
Window->OnHitTest(mousePos, hit, handled);
|
||||
|
||||
if (hit == WindowHitCodes::Caption)
|
||||
{
|
||||
bool consumed = false;
|
||||
Window->OnLeftButtonHit(hit, consumed);
|
||||
|
||||
if (!consumed)
|
||||
{
|
||||
[(NSWindow*)Window->GetNativePtr() performWindowDragWithEvent:event];
|
||||
Window->SyncWindowState();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MouseButton mouseButton = MouseButton::Left;
|
||||
if ([event clickCount] == 2 && !Input::Mouse->IsRelative())
|
||||
Input::Mouse->OnMouseDoubleClick(mousePos, mouseButton, Window);
|
||||
@@ -835,15 +876,28 @@ MacWindow::MacWindow(const CreateWindowSettings& settings)
|
||||
|
||||
MacWindow::~MacWindow()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
[window close];
|
||||
[window release];
|
||||
if (NSWindow* window = (NSWindow*)_window)
|
||||
{
|
||||
[window close];
|
||||
[window release];
|
||||
}
|
||||
_window = nullptr;
|
||||
_view = nullptr;
|
||||
}
|
||||
|
||||
void MacWindow::SyncWindowState()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (window)
|
||||
{
|
||||
_minimized = window.miniaturized;
|
||||
_maximized = window.zoomed;
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::CheckForResize(float width, float height)
|
||||
{
|
||||
SyncWindowState();
|
||||
const Float2 clientSize(width, height);
|
||||
if (clientSize != _clientSize)
|
||||
{
|
||||
@@ -940,7 +994,7 @@ void MacWindow::Hide()
|
||||
[window orderOut:nil];
|
||||
|
||||
// Transfer focus back to the parent when hiding popup
|
||||
if (_settings.Parent && wasKey)
|
||||
if (_settings.Parent && wasKey && _settings.Type != WindowType::Popup && _settings.Type != WindowType::Tooltip)
|
||||
{
|
||||
NSWindow* parent = (NSWindow*)_settings.Parent->GetNativePtr();
|
||||
[parent makeKeyAndOrderFront:nil];
|
||||
@@ -951,6 +1005,27 @@ void MacWindow::Hide()
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::Close(ClosingReason reason)
|
||||
{
|
||||
const BOOL wasKey = _window && [(NSWindow*)_window isKeyWindow];
|
||||
WindowBase::Close(reason);
|
||||
|
||||
// Closing can be cancelled by managed Window.Closing handlers.
|
||||
if (!IsClosed())
|
||||
return;
|
||||
|
||||
if (NSWindow* window = (NSWindow*)_window)
|
||||
{
|
||||
[window close];
|
||||
}
|
||||
|
||||
if (_settings.Parent && wasKey && _settings.Type != WindowType::Popup && _settings.Type != WindowType::Tooltip)
|
||||
{
|
||||
NSWindow* parent = (NSWindow*)_settings.Parent->GetNativePtr();
|
||||
[parent makeKeyAndOrderFront:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void MacWindow::Minimize()
|
||||
{
|
||||
if (!_settings.AllowMinimize)
|
||||
@@ -967,17 +1042,43 @@ void MacWindow::Maximize()
|
||||
if (!_settings.AllowMaximize)
|
||||
return;
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
if (!window.zoomed)
|
||||
{
|
||||
if (!_maximized)
|
||||
{
|
||||
_restoreClientBounds = GetClientBounds();
|
||||
_hasRestoreClientBounds = true;
|
||||
}
|
||||
[window zoom:nil];
|
||||
}
|
||||
SyncWindowState();
|
||||
}
|
||||
|
||||
void MacWindow::Restore()
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
if (window.miniaturized)
|
||||
{
|
||||
[window deminiaturize:nil];
|
||||
SyncWindowState();
|
||||
}
|
||||
else if (_maximized && _hasRestoreClientBounds)
|
||||
{
|
||||
const Rectangle restoreClientBounds = _restoreClientBounds;
|
||||
_hasRestoreClientBounds = false;
|
||||
NSRect restoreFrame = GetFrameRectForClientBounds(this, window, restoreClientBounds);
|
||||
[window setFrame:restoreFrame display:YES animate:YES];
|
||||
_maximized = false;
|
||||
}
|
||||
else if (window.zoomed)
|
||||
{
|
||||
[window zoom:nil];
|
||||
SyncWindowState();
|
||||
}
|
||||
}
|
||||
|
||||
bool MacWindow::IsForegroundWindow() const
|
||||
@@ -1001,17 +1102,7 @@ void MacWindow::SetClientBounds(const Rectangle& clientArea)
|
||||
NSWindow* window = (NSWindow*)_window;
|
||||
if (!window)
|
||||
return;
|
||||
const float screenScale = MacPlatform::ScreenScale;
|
||||
|
||||
NSRect oldRect = [window frame];
|
||||
NSRect newRect = NSMakeRect(0, 0, clientArea.Size.X / screenScale, clientArea.Size.Y / screenScale);
|
||||
newRect = [window frameRectForContentRect:newRect];
|
||||
|
||||
Float2 pos = AppleUtils::PosToCoca(clientArea.Location) / screenScale;
|
||||
Float2 titleSize = GetWindowTitleSize(this);
|
||||
newRect.origin.x = pos.X + titleSize.X;
|
||||
newRect.origin.y = pos.Y - newRect.size.height + titleSize.Y;
|
||||
|
||||
NSRect newRect = GetFrameRectForClientBounds(this, window, clientArea);
|
||||
[window setFrame:newRect display:YES];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,16 @@ private:
|
||||
void* _window = nullptr;
|
||||
void* _view = nullptr;
|
||||
bool _isMouseOver = false;
|
||||
bool _hasRestoreClientBounds = false;
|
||||
Rectangle _restoreClientBounds;
|
||||
Float2 _mouseTrackPos = Float2::Minimum;
|
||||
String _dragText;
|
||||
|
||||
public:
|
||||
MacWindow(const CreateWindowSettings& settings);
|
||||
~MacWindow();
|
||||
~MacWindow() override;
|
||||
|
||||
void SyncWindowState();
|
||||
void CheckForResize(float width, float height);
|
||||
void SetIsMouseOver(bool value);
|
||||
const String& GetDragText() const
|
||||
@@ -37,6 +40,7 @@ public:
|
||||
void OnUpdate(float dt) override;
|
||||
void Show() override;
|
||||
void Hide() override;
|
||||
void Close(ClosingReason reason) override;
|
||||
void Minimize() override;
|
||||
void Maximize() override;
|
||||
void Restore() override;
|
||||
|
||||
Reference in New Issue
Block a user