Merge ScreenUtilities into Platform for simplicity and make it Editor-only
#2800
This commit is contained in:
@@ -303,19 +303,22 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
if (_activeEyedropper)
|
||||
{
|
||||
_activeEyedropper = false;
|
||||
Color color = colorPicked;
|
||||
if (_linear)
|
||||
color = color.ToLinear();
|
||||
SelectedColor = color;
|
||||
ScreenUtilities.PickColorDone -= OnColorPicked;
|
||||
if (colorPicked != Color.Transparent)
|
||||
{
|
||||
Color color = colorPicked;
|
||||
if (_linear)
|
||||
color = color.ToLinear();
|
||||
SelectedColor = color;
|
||||
}
|
||||
Platform.PickScreenColorDone -= OnColorPicked;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEyedropStart()
|
||||
{
|
||||
_activeEyedropper = true;
|
||||
ScreenUtilities.PickColor();
|
||||
ScreenUtilities.PickColorDone += OnColorPicked;
|
||||
Platform.PickScreenColor();
|
||||
Platform.PickScreenColorDone += OnColorPicked;
|
||||
}
|
||||
|
||||
private void OnRGBAChanged()
|
||||
@@ -353,7 +356,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
// Try reading the color under the cursor in realtime if supported by the platform
|
||||
Float2 mousePosition = Platform.MousePosition;
|
||||
Color color = ScreenUtilities.GetColorAt(mousePosition);
|
||||
Color color = Platform.GetScreenColorAt(mousePosition);
|
||||
if (color != Color.Transparent)
|
||||
{
|
||||
if (_linear)
|
||||
@@ -441,7 +444,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
// Cancel eye dropping
|
||||
_activeEyedropper = false;
|
||||
ScreenUtilities.PickColorDone -= OnColorPicked;
|
||||
Platform.PickScreenColorDone -= OnColorPicked;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
// [Deprecated in v1.12]
|
||||
#include "Engine/Platform/ScreenUtilities.h"
|
||||
@@ -797,6 +797,26 @@ void PlatformBase::CollectCrashData(const String& crashDataFolder, void* context
|
||||
{
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
|
||||
Delegate<Color32> PlatformBase::PickScreenColorDone;
|
||||
|
||||
Color32 PlatformBase::GetScreenColorAt(const Float2& pos)
|
||||
{
|
||||
// No supported
|
||||
return Color32::Transparent;
|
||||
}
|
||||
|
||||
void PlatformBase::PickScreenColor()
|
||||
{
|
||||
// Just return transparent color when not implemented/supported
|
||||
PickScreenColorDone(Color32::Transparent);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const Char* ToString(PlatformType type)
|
||||
{
|
||||
switch (type)
|
||||
|
||||
@@ -888,6 +888,26 @@ public:
|
||||
|
||||
// Crash dump data handling
|
||||
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);
|
||||
|
||||
public:
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// Gets the pixel color at the specified coordinates.
|
||||
/// </summary>
|
||||
/// <param name="pos">Screen-space coordinate to read.</param>
|
||||
/// <returns>Pixel color at the specified coordinates, or transparent color when color couldn't be picked up.</returns>
|
||||
API_FUNCTION() static Color32 GetScreenColorAt(const Float2& pos);
|
||||
|
||||
/// <summary>
|
||||
/// Starts async color picking. Color will be returned through PickColorDone event when the action ends (user selected the final color with a mouse). When action is active, GetColorAt can be used to read the current value.
|
||||
/// </summary>
|
||||
API_FUNCTION() static void PickScreenColor();
|
||||
|
||||
/// <summary>
|
||||
/// Called when PickColor action is finished.
|
||||
/// </summary>
|
||||
API_EVENT() static Delegate<Color32> PickScreenColorDone;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern FLAXENGINE_API const Char* ToString(PlatformType type);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
|
||||
API_INJECT_CODE(cpp, "#include \"Engine/Platform/ScreenUtilities.h\"");
|
||||
|
||||
/// <summary>
|
||||
/// Platform-dependent screen utilities.
|
||||
/// </summary>
|
||||
API_CLASS(Static, Name="ScreenUtilities", Tag="NativeInvokeUseName")
|
||||
class FLAXENGINE_API ScreenUtilitiesBase
|
||||
{
|
||||
public:
|
||||
static struct FLAXENGINE_API ScriptingTypeInitializer TypeInitializer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pixel color at the specified coordinates.
|
||||
/// </summary>
|
||||
/// <param name="pos">Screen-space coordinate to read.</param>
|
||||
/// <returns>Pixel color at the specified coordinates, or transparent color when color couldn't be picked up.</returns>
|
||||
API_FUNCTION() static Color32 GetColorAt(const Float2& pos)
|
||||
{
|
||||
return Color32::Transparent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts async color picking. Color will be returned through PickColorDone event when the actions ends (user selected the final color with a mouse). When action is active, GetColorAt can be used to read the current value.
|
||||
/// </summary>
|
||||
API_FUNCTION() static void PickColor()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when PickColor action is finished.
|
||||
/// </summary>
|
||||
API_EVENT() static Delegate<Color32> PickColorDone;
|
||||
};
|
||||
@@ -1,13 +1,14 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Platform/Window.h"
|
||||
#include "Engine/Platform/WindowsManager.h"
|
||||
#include "Engine/Platform/IGuiData.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Platform/WindowsManager.h"
|
||||
#include "Engine/Graphics/GPUSwapChain.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Input/Input.h"
|
||||
#include "Engine/Platform/IGuiData.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Profiler/ProfilerMemory.h"
|
||||
|
||||
@@ -3164,4 +3164,160 @@ Array<LinuxPlatform::StackFrame> LinuxPlatform::GetStackFrames(int32 skipCount,
|
||||
return result;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Platform/Linux/LinuxPlatform.h"
|
||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
||||
|
||||
#if PLATFORM_SDL
|
||||
#include <libportal/portal-enums.h>
|
||||
#include <libportal/screenshot.h>
|
||||
|
||||
namespace PortalImpl
|
||||
{
|
||||
XdpPortal* Portal = nullptr;
|
||||
int64 MainLoopReady = 0;
|
||||
|
||||
gpointer GLibMainLoop(gpointer data);
|
||||
void PickColorCallback(GObject* source, GAsyncResult* result, gpointer data);
|
||||
}
|
||||
#endif
|
||||
|
||||
Color32 LinuxPlatform::GetScreenColorAt(const Float2& pos)
|
||||
{
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (display)
|
||||
{
|
||||
int defaultScreen = X11::XDefaultScreen(display);
|
||||
X11::Window rootWindow = X11::XRootWindow(display, defaultScreen);
|
||||
X11::XImage* image = X11::XGetImage(display, rootWindow, (int)pos.X, (int)pos.Y, 1, 1, AllPlanes, XYPixmap);
|
||||
if (image)
|
||||
{
|
||||
X11::XColor color;
|
||||
color.pixel = XGetPixel(image, 0, 0);
|
||||
X11::XFree(image);
|
||||
|
||||
X11::XQueryColor(display, X11::XDefaultColormap(display, defaultScreen), &color);
|
||||
|
||||
Color32 outputColor;
|
||||
outputColor.R = color.red / 256;
|
||||
outputColor.G = color.green / 256;
|
||||
outputColor.B = color.blue / 256;
|
||||
outputColor.A = 255;
|
||||
return outputColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XWayland doesn't support XGetImage
|
||||
}
|
||||
}
|
||||
|
||||
return Color32::Transparent;
|
||||
}
|
||||
|
||||
void OnScreenUtilsXEventCallback(void* eventPtr)
|
||||
{
|
||||
X11::XEvent* event = (X11::XEvent*)eventPtr;
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (event->type == ButtonPress)
|
||||
{
|
||||
const Float2 cursorPos = Platform::GetMousePosition();
|
||||
const Color32 colorPicked = LinuxPlatform::GetScreenColorAt(cursorPos);
|
||||
X11::XUngrabPointer(display, CurrentTime);
|
||||
PlatformBase::PickScreenColorDone(colorPicked);
|
||||
LinuxPlatform::xEventReceived.Unbind(OnScreenUtilsXEventCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxPlatform::PickScreenColor()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (display)
|
||||
{
|
||||
X11::Window rootWindow = X11::XRootWindow(display, X11::XDefaultScreen(display));
|
||||
X11::Cursor cursor = XCreateFontCursor(display, 130);
|
||||
int grabbedPointer = X11::XGrabPointer(display, rootWindow, 0, ButtonPressMask, GrabModeAsync, GrabModeAsync, rootWindow, cursor, CurrentTime);
|
||||
if (grabbedPointer != GrabSuccess)
|
||||
{
|
||||
LOG(Error, "Failed to grab cursor for events.");
|
||||
X11::XFreeCursor(display, cursor);
|
||||
return;
|
||||
}
|
||||
|
||||
X11::XFreeCursor(display, cursor);
|
||||
LinuxPlatform::xEventReceived.Bind(OnScreenUtilsXEventCallback);
|
||||
return;
|
||||
}
|
||||
#if PLATFORM_SDL
|
||||
if (PortalImpl::MainLoopReady == 0)
|
||||
{
|
||||
// Initialize portal
|
||||
GError* error = nullptr;
|
||||
PortalImpl::Portal = xdp_portal_initable_new(&error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
PortalImpl::MainLoopReady = 2;
|
||||
LOG(Error, "Failed to initialize XDP Portal");
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the GLib main loop in other thread in order to process asynchronous callbacks
|
||||
g_thread_new(nullptr, PortalImpl::GLibMainLoop, nullptr);
|
||||
while (Platform::AtomicRead(&PortalImpl::MainLoopReady) != 1)
|
||||
Platform::Sleep(1);
|
||||
}
|
||||
|
||||
if (PortalImpl::Portal != nullptr)
|
||||
{
|
||||
// Enter color picking mode, the callback receives the final color
|
||||
xdp_portal_pick_color(PortalImpl::Portal, nullptr, nullptr, PortalImpl::PickColorCallback, nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PLATFORM_SDL
|
||||
|
||||
gpointer PortalImpl::GLibMainLoop(gpointer data)
|
||||
{
|
||||
GMainContext* mainContext = g_main_context_get_thread_default();
|
||||
GMainLoop* mainLoop = g_main_loop_new(mainContext, false);
|
||||
|
||||
Platform::AtomicStore(&PortalImpl::MainLoopReady, 1);
|
||||
|
||||
g_main_loop_run(mainLoop);
|
||||
g_main_loop_unref(mainLoop);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PortalImpl::PickColorCallback(GObject* source, GAsyncResult* result, gpointer data)
|
||||
{
|
||||
GError* error = nullptr;
|
||||
GVariant* variant = xdp_portal_pick_color_finish(PortalImpl::Portal, result, &error);
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
LOG(Info, "XDP Portal pick color cancelled");
|
||||
else
|
||||
LOG(Error, "XDP Portal pick color failed: {}", String(error->message));
|
||||
return;
|
||||
}
|
||||
|
||||
// The color is stored in a triple double variant, extract the values
|
||||
Double4 colorDouble;
|
||||
g_variant_get(variant, "(ddd)", &colorDouble.X, &colorDouble.Y, &colorDouble.Z);
|
||||
g_variant_unref(variant);
|
||||
colorDouble.W = 1.0f;
|
||||
Vector4 colorVector = colorDouble;
|
||||
Color32 color = Color32(colorVector);
|
||||
|
||||
PlatformBase::PickScreenColorDone(color);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,6 +155,10 @@ public:
|
||||
static void FreeLibrary(void* handle);
|
||||
static void* GetProcAddress(void* handle, const char* symbol);
|
||||
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
|
||||
#if USE_EDITOR
|
||||
static Color32 GetScreenColorAt(const Float2& pos);
|
||||
static void PickScreenColor();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
|
||||
#include "Engine/Platform/Types.h"
|
||||
#include "Engine/Platform/ScreenUtilities.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Platform/Linux/LinuxPlatform.h"
|
||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
||||
|
||||
#if PLATFORM_SDL
|
||||
#include <libportal/portal-enums.h>
|
||||
#include <libportal/screenshot.h>
|
||||
|
||||
namespace PortalImpl
|
||||
{
|
||||
XdpPortal* Portal = nullptr;
|
||||
int64 MainLoopReady = 0;
|
||||
|
||||
gpointer GLibMainLoop(gpointer data);
|
||||
void PickColorCallback(GObject* source, GAsyncResult* result, gpointer data);
|
||||
}
|
||||
#endif
|
||||
|
||||
Delegate<Color32> ScreenUtilitiesBase::PickColorDone;
|
||||
|
||||
Color32 LinuxScreenUtilities::GetColorAt(const Float2& pos)
|
||||
{
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (display)
|
||||
{
|
||||
int defaultScreen = X11::XDefaultScreen(display);
|
||||
X11::Window rootWindow = X11::XRootWindow(display, defaultScreen);
|
||||
X11::XImage* image = X11::XGetImage(display, rootWindow, (int)pos.X, (int)pos.Y, 1, 1, AllPlanes, XYPixmap);
|
||||
if (image)
|
||||
{
|
||||
X11::XColor color;
|
||||
color.pixel = XGetPixel(image, 0, 0);
|
||||
X11::XFree(image);
|
||||
|
||||
X11::XQueryColor(display, X11::XDefaultColormap(display, defaultScreen), &color);
|
||||
|
||||
Color32 outputColor;
|
||||
outputColor.R = color.red / 256;
|
||||
outputColor.G = color.green / 256;
|
||||
outputColor.B = color.blue / 256;
|
||||
outputColor.A = 255;
|
||||
return outputColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XWayland doesn't support XGetImage
|
||||
}
|
||||
}
|
||||
|
||||
return Color32::Transparent;
|
||||
}
|
||||
|
||||
void OnScreenUtilsXEventCallback(void* eventPtr)
|
||||
{
|
||||
X11::XEvent* event = (X11::XEvent*) eventPtr;
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (event->type == ButtonPress)
|
||||
{
|
||||
const Float2 cursorPos = Platform::GetMousePosition();
|
||||
const Color32 colorPicked = ScreenUtilities::GetColorAt(cursorPos);
|
||||
X11::XUngrabPointer(display, CurrentTime);
|
||||
ScreenUtilities::PickColorDone(colorPicked);
|
||||
LinuxPlatform::xEventReceived.Unbind(OnScreenUtilsXEventCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxScreenUtilities::PickColor()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
X11::Display* display = (X11::Display*)Platform::GetXDisplay();
|
||||
if (display)
|
||||
{
|
||||
X11::Window rootWindow = X11::XRootWindow(display, X11::XDefaultScreen(display));
|
||||
|
||||
X11::Cursor cursor = XCreateFontCursor(display, 130);
|
||||
int grabbedPointer = X11::XGrabPointer(display, rootWindow, 0, ButtonPressMask, GrabModeAsync, GrabModeAsync, rootWindow, cursor, CurrentTime);
|
||||
if (grabbedPointer != GrabSuccess)
|
||||
{
|
||||
LOG(Error, "Failed to grab cursor for events.");
|
||||
X11::XFreeCursor(display, cursor);
|
||||
return;
|
||||
}
|
||||
|
||||
X11::XFreeCursor(display, cursor);
|
||||
LinuxPlatform::xEventReceived.Bind(OnScreenUtilsXEventCallback);
|
||||
return;
|
||||
}
|
||||
#if PLATFORM_SDL
|
||||
if (PortalImpl::MainLoopReady == 0)
|
||||
{
|
||||
// Initialize portal
|
||||
GError* error = nullptr;
|
||||
PortalImpl::Portal = xdp_portal_initable_new(&error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
PortalImpl::MainLoopReady = 2;
|
||||
LOG(Error, "Failed to initialize XDP Portal");
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the GLib main loop in other thread in order to process asynchronous callbacks
|
||||
g_thread_new(nullptr, PortalImpl::GLibMainLoop, nullptr);
|
||||
while (Platform::AtomicRead(&PortalImpl::MainLoopReady) != 1)
|
||||
Platform::Sleep(1);
|
||||
}
|
||||
|
||||
if (PortalImpl::Portal != nullptr)
|
||||
{
|
||||
// Enter color picking mode, the callback receives the final color
|
||||
xdp_portal_pick_color(PortalImpl::Portal, nullptr, nullptr, PortalImpl::PickColorCallback, nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PLATFORM_SDL
|
||||
|
||||
gpointer PortalImpl::GLibMainLoop(gpointer data)
|
||||
{
|
||||
GMainContext* mainContext = g_main_context_get_thread_default();
|
||||
GMainLoop* mainLoop = g_main_loop_new(mainContext, false);
|
||||
|
||||
Platform::AtomicStore(&PortalImpl::MainLoopReady, 1);
|
||||
|
||||
g_main_loop_run(mainLoop);
|
||||
g_main_loop_unref(mainLoop);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PortalImpl::PickColorCallback(GObject* source, GAsyncResult* result, gpointer data)
|
||||
{
|
||||
GError* error = nullptr;
|
||||
GVariant* variant = xdp_portal_pick_color_finish(PortalImpl::Portal, result, &error);
|
||||
if (error)
|
||||
{
|
||||
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
LOG(Info, "XDP Portal pick color cancelled");
|
||||
else
|
||||
LOG(Error, "XDP Portal pick color failed: {}", String(error->message));
|
||||
return;
|
||||
}
|
||||
|
||||
// The color is stored in a triple double variant, extract the values
|
||||
Double4 colorDouble;
|
||||
g_variant_get(variant, "(ddd)", &colorDouble.X, &colorDouble.Y, &colorDouble.Z);
|
||||
g_variant_unref(variant);
|
||||
colorDouble.W = 1.0f;
|
||||
Vector4 colorVector = colorDouble;
|
||||
Color32 color = Color32(colorVector);
|
||||
|
||||
ScreenUtilities::PickColorDone(color);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
|
||||
#include "Engine/Platform/Base/ScreenUtilitiesBase.h"
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
|
||||
/// <summary>
|
||||
/// Platform-dependent screen utilities.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API LinuxScreenUtilities : public ScreenUtilitiesBase
|
||||
{
|
||||
public:
|
||||
|
||||
// [ScreenUtilitiesBase]
|
||||
static Color32 GetColorAt(const Float2& pos);
|
||||
static void PickColor();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#if USE_EDITOR && PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/Types.h"
|
||||
#include "Engine/Platform/ScreenUtilities.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
Delegate<Color32> ScreenUtilitiesBase::PickColorDone;
|
||||
|
||||
Color32 MacScreenUtilities::GetColorAt(const Float2& pos)
|
||||
{
|
||||
// TODO: implement ScreenUtilities for macOS
|
||||
return { 0, 0, 0, 255 };
|
||||
}
|
||||
|
||||
void MacScreenUtilities::PickColor()
|
||||
{
|
||||
// This is what C# calls to start the color picking sequence
|
||||
// This should stop mouse clicks from working for one click, and that click is on the selected color
|
||||
// There is a class called NSColorSample that might implement that for you, but maybe not.
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if USE_EDITOR && PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/Base/ScreenUtilitiesBase.h"
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
|
||||
/// <summary>
|
||||
/// Platform-dependent screen utilities.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API MacScreenUtilities : public ScreenUtilitiesBase
|
||||
{
|
||||
public:
|
||||
|
||||
// [ScreenUtilitiesBase]
|
||||
static Color32 GetColorAt(const Float2& pos);
|
||||
static void PickColor();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include "Windows/WindowsScreenUtilities.h"
|
||||
#elif PLATFORM_LINUX
|
||||
#include "Linux/LinuxScreenUtilities.h"
|
||||
#elif PLATFORM_MAC
|
||||
#include "Mac/MacScreenUtilities.h"
|
||||
#else
|
||||
#include "Base/ScreenUtilitiesBase.h"
|
||||
#endif
|
||||
|
||||
#include "Types.h"
|
||||
@@ -30,8 +30,6 @@ class Win32Network;
|
||||
typedef Win32Network Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class WindowsScreenUtilities;
|
||||
typedef WindowsScreenUtilities ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_UWP
|
||||
|
||||
@@ -59,8 +57,6 @@ class Win32Network;
|
||||
typedef Win32Network Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_LINUX
|
||||
|
||||
@@ -90,8 +86,6 @@ class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class LinuxScreenUtilities;
|
||||
typedef LinuxScreenUtilities ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_PS4
|
||||
|
||||
@@ -119,8 +113,6 @@ class PS4Network;
|
||||
typedef PS4Network Network;
|
||||
class PS4User;
|
||||
typedef PS4User User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_PS5
|
||||
|
||||
@@ -148,8 +140,6 @@ class PS5Network;
|
||||
typedef PS5Network Network;
|
||||
class PS5User;
|
||||
typedef PS5User User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_XBOX_ONE
|
||||
|
||||
@@ -177,8 +167,6 @@ class Win32Network;
|
||||
typedef Win32Network Network;
|
||||
class GDKUser;
|
||||
typedef GDKUser User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_XBOX_SCARLETT
|
||||
|
||||
@@ -206,8 +194,6 @@ class Win32Network;
|
||||
typedef Win32Network Network;
|
||||
class GDKUser;
|
||||
typedef GDKUser User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_ANDROID
|
||||
|
||||
@@ -235,8 +221,6 @@ class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_SWITCH
|
||||
|
||||
@@ -264,8 +248,6 @@ class SwitchNetwork;
|
||||
typedef SwitchNetwork Network;
|
||||
class SwitchUser;
|
||||
typedef SwitchUser User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_MAC
|
||||
|
||||
@@ -295,8 +277,6 @@ class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class MacScreenUtilities;
|
||||
typedef MacScreenUtilities ScreenUtilities;
|
||||
|
||||
#elif PLATFORM_IOS
|
||||
|
||||
@@ -324,8 +304,6 @@ class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
class ScreenUtilitiesBase;
|
||||
typedef ScreenUtilitiesBase ScreenUtilities;
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -1562,4 +1562,49 @@ void WindowsPlatform::CollectCrashData(const String& crashDataFolder, void* cont
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
|
||||
WIN_API COLORREF WIN_API_CALLCONV GetPixel(_In_ HDC hdc, _In_ int x, _In_ int y);
|
||||
#define GetRValue(rgb) (LOBYTE(rgb))
|
||||
#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
|
||||
#define GetBValue(rgb) (LOBYTE((rgb) >> 16))
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
|
||||
static HHOOK MouseCallbackHook;
|
||||
|
||||
LRESULT CALLBACK OnScreenUtilsMouseCallback(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && wParam == WM_LBUTTONDOWN)
|
||||
{
|
||||
UnhookWindowsHookEx(MouseCallbackHook);
|
||||
|
||||
// Push event with the picked color
|
||||
const Float2 cursorPos = Platform::GetMousePosition();
|
||||
const Color32 colorPicked = PlatformBase::GetScreenColorAt(cursorPos);
|
||||
PlatformBase::PickScreenColorDone(colorPicked);
|
||||
return 1;
|
||||
}
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
Color32 WindowsPlatform::GetScreenColorAt(const Float2& pos)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
HDC deviceContext = GetDC(NULL);
|
||||
COLORREF color = GetPixel(deviceContext, (int)pos.X, (int)pos.Y);
|
||||
ReleaseDC(NULL, deviceContext);
|
||||
return Color32(GetRValue(color), GetGValue(color), GetBValue(color), 255);
|
||||
}
|
||||
|
||||
void WindowsPlatform::PickScreenColor()
|
||||
{
|
||||
MouseCallbackHook = SetWindowsHookEx(WH_MOUSE_LL, OnScreenUtilsMouseCallback, NULL, NULL);
|
||||
if (MouseCallbackHook == NULL)
|
||||
LOG(Warning, "Failed to set mouse hook (GetLastError={})", GetLastError());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -90,6 +90,10 @@ public:
|
||||
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
|
||||
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
static Color32 GetScreenColorAt(const Float2& pos);
|
||||
static void PickScreenColor();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
#include "Engine/Platform/Types.h"
|
||||
#include "Engine/Platform/ScreenUtilities.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#pragma comment(lib, "Gdi32.lib")
|
||||
|
||||
Delegate<Color32> ScreenUtilitiesBase::PickColorDone;
|
||||
|
||||
static HHOOK MouseCallbackHook;
|
||||
|
||||
LRESULT CALLBACK OnScreenUtilsMouseCallback(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && wParam == WM_LBUTTONDOWN)
|
||||
{
|
||||
UnhookWindowsHookEx(MouseCallbackHook);
|
||||
|
||||
// Push event with the picked color
|
||||
const Float2 cursorPos = Platform::GetMousePosition();
|
||||
const Color32 colorPicked = ScreenUtilities::GetColorAt(cursorPos);
|
||||
ScreenUtilities::PickColorDone(colorPicked);
|
||||
return 1;
|
||||
}
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
Color32 WindowsScreenUtilities::GetColorAt(const Float2& pos)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
HDC deviceContext = GetDC(NULL);
|
||||
COLORREF color = GetPixel(deviceContext, (int)pos.X, (int)pos.Y);
|
||||
ReleaseDC(NULL, deviceContext);
|
||||
return Color32(GetRValue(color), GetGValue(color), GetBValue(color), 255);
|
||||
}
|
||||
|
||||
void WindowsScreenUtilities::PickColor()
|
||||
{
|
||||
MouseCallbackHook = SetWindowsHookEx(WH_MOUSE_LL, OnScreenUtilsMouseCallback, NULL, NULL);
|
||||
if (MouseCallbackHook == NULL)
|
||||
{
|
||||
LOG(Warning, "Failed to set mouse hook.");
|
||||
LOG(Warning, "Error: {0}", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
|
||||
#include "Engine/Platform/Base/ScreenUtilitiesBase.h"
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
|
||||
/// <summary>
|
||||
/// Platform-dependent screen utilities.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API WindowsScreenUtilities : public ScreenUtilitiesBase
|
||||
{
|
||||
public:
|
||||
|
||||
// [ScreenUtilitiesBase]
|
||||
static Color32 GetColorAt(const Float2& pos);
|
||||
static void PickColor();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user