UI: Allow Eyedropper Outside of Blender #105324
|
@ -764,6 +764,13 @@ extern void GHOST_SetMultitouchGestures(GHOST_SystemHandle systemhandle, const b
|
||||||
*/
|
*/
|
||||||
extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api);
|
extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the pixel at the current mouse cursor location
|
||||||
|
* \param r_color: returned sRGB float colors
|
||||||
Harley marked this conversation as resolved
Outdated
|
|||||||
|
* \return Success value (true == successful and supported by platform)
|
||||||
|
*/
|
||||||
|
extern GHOST_TSuccess GHOST_GetPixelAtCursor(float r_color[3]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to rectangle width.
|
* Access to rectangle width.
|
||||||
* \param rectanglehandle: The handle to the rectangle.
|
* \param rectanglehandle: The handle to the rectangle.
|
||||||
|
|
|
@ -441,6 +441,13 @@ class GHOST_ISystem {
|
||||||
*/
|
*/
|
||||||
virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
|
virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the pixel at the current mouse cursor location
|
||||||
|
* \param r_color: returned sRGB float colors
|
||||||
|
* \return Success value (true == successful and supported by platform)
|
||||||
|
*/
|
||||||
|
virtual GHOST_TSuccess getPixelAtCursor(float r_color[3]) const = 0;
|
||||||
|
|
||||||
#ifdef WITH_INPUT_NDOF
|
#ifdef WITH_INPUT_NDOF
|
||||||
/**
|
/**
|
||||||
* Sets 3D mouse deadzone
|
* Sets 3D mouse deadzone
|
||||||
|
|
|
@ -107,6 +107,10 @@ typedef enum {
|
||||||
* Set when there is support for system clipboard copy/paste.
|
* Set when there is support for system clipboard copy/paste.
|
||||||
*/
|
*/
|
||||||
GHOST_kCapabilityClipboardImages = (1 << 4),
|
GHOST_kCapabilityClipboardImages = (1 << 4),
|
||||||
|
/**
|
||||||
|
* Support for sampling a color outside of the Blender windows.
|
||||||
|
*/
|
||||||
|
GHOST_kCapabilityDesktopSample = (1 << 5),
|
||||||
} GHOST_TCapabilityFlag;
|
} GHOST_TCapabilityFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,7 +119,8 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
#define GHOST_CAPABILITY_FLAG_ALL \
|
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||||
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||||
GHOST_kCapabilityPrimaryClipboard | GHOST_kCapabilityGPUReadFrontBuffer)
|
GHOST_kCapabilityPrimaryClipboard | GHOST_kCapabilityGPUReadFrontBuffer | \
|
||||||
|
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityDesktopSample)
|
||||||
|
|
||||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||||
* vertically upright in either the X or Y direction, with X and Y the
|
* vertically upright in either the X or Y direction, with X and Y the
|
||||||
|
|
|
@ -768,6 +768,12 @@ void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
|
||||||
system->setTabletAPI(api);
|
system->setTabletAPI(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TSuccess GHOST_GetPixelAtCursor(float r_color[3])
|
||||||
|
{
|
||||||
|
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||||
|
return system->getPixelAtCursor(r_color);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
|
int32_t GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
|
||||||
{
|
{
|
||||||
return ((GHOST_Rect *)rectanglehandle)->getWidth();
|
return ((GHOST_Rect *)rectanglehandle)->getWidth();
|
||||||
|
|
|
@ -341,6 +341,11 @@ GHOST_TTabletAPI GHOST_System::getTabletAPI()
|
||||||
return m_tabletAPI;
|
return m_tabletAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TSuccess GHOST_System::getPixelAtCursor(float[3] /* r_color */) const
|
||||||
|
{
|
||||||
|
return GHOST_kFailure;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_INPUT_NDOF
|
#ifdef WITH_INPUT_NDOF
|
||||||
void GHOST_System::setNDOFDeadZone(float deadzone)
|
void GHOST_System::setNDOFDeadZone(float deadzone)
|
||||||
{
|
{
|
||||||
|
|
|
@ -256,6 +256,13 @@ class GHOST_System : public GHOST_ISystem {
|
||||||
virtual void setTabletAPI(GHOST_TTabletAPI api);
|
virtual void setTabletAPI(GHOST_TTabletAPI api);
|
||||||
GHOST_TTabletAPI getTabletAPI(void);
|
GHOST_TTabletAPI getTabletAPI(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the pixel at the current mouse cursor location
|
||||||
|
* \param r_color: returned sRGB float colors
|
||||||
|
* \return Success value (true == successful and supported by platform)
|
||||||
|
*/
|
||||||
|
GHOST_TSuccess getPixelAtCursor(float r_color[3]) const;
|
||||||
|
|
||||||
#ifdef WITH_INPUT_NDOF
|
#ifdef WITH_INPUT_NDOF
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Access to 3D mouse.
|
* Access to 3D mouse.
|
||||||
|
|
|
@ -921,6 +921,8 @@ GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
|
||||||
~(
|
~(
|
||||||
/* Cocoa has no support for a primary selection clipboard. */
|
/* Cocoa has no support for a primary selection clipboard. */
|
||||||
GHOST_kCapabilityPrimaryClipboard |
|
GHOST_kCapabilityPrimaryClipboard |
|
||||||
|
/* Cocoa has no support for sampling colors from the desktop. */
|
||||||
|
GHOST_kCapabilityDesktopSample |
|
||||||
/* This Cocoa back-end has not yet implemented image copy/paste. */
|
/* This Cocoa back-end has not yet implemented image copy/paste. */
|
||||||
GHOST_kCapabilityClipboardImages));
|
GHOST_kCapabilityClipboardImages));
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
||||||
/* No windowing functionality supported. */
|
/* No windowing functionality supported. */
|
||||||
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||||
GHOST_kCapabilityPrimaryClipboard |
|
GHOST_kCapabilityPrimaryClipboard |
|
||||||
|
GHOST_kCapabilityDesktopSample |
|
||||||
GHOST_kCapabilityClipboardImages));
|
GHOST_kCapabilityClipboardImages));
|
||||||
}
|
}
|
||||||
char *getClipboard(bool /*selection*/) const override
|
char *getClipboard(bool /*selection*/) const override
|
||||||
|
|
|
@ -772,6 +772,8 @@ GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const
|
||||||
~(
|
~(
|
||||||
/* This SDL back-end has not yet implemented primary clipboard. */
|
/* This SDL back-end has not yet implemented primary clipboard. */
|
||||||
GHOST_kCapabilityPrimaryClipboard |
|
GHOST_kCapabilityPrimaryClipboard |
|
||||||
|
/* This SDL back-end has not yet implemented color sampling the desktop. */
|
||||||
|
GHOST_kCapabilityDesktopSample |
|
||||||
/* This SDL back-end has not yet implemented image copy/paste. */
|
/* This SDL back-end has not yet implemented image copy/paste. */
|
||||||
GHOST_kCapabilityClipboardImages));
|
GHOST_kCapabilityClipboardImages));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6843,6 +6843,8 @@ GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
||||||
* screen-shot and eye-dropper sampling logic, both operations where the overhead
|
* screen-shot and eye-dropper sampling logic, both operations where the overhead
|
||||||
* is negligible. */
|
* is negligible. */
|
||||||
GHOST_kCapabilityGPUReadFrontBuffer |
|
GHOST_kCapabilityGPUReadFrontBuffer |
|
||||||
|
/* This WAYLAND back-end has not yet implemented desktop color sample. */
|
||||||
|
GHOST_kCapabilityDesktopSample |
|
||||||
/* This WAYLAND back-end has not yet implemented image copy/paste. */
|
/* This WAYLAND back-end has not yet implemented image copy/paste. */
|
||||||
GHOST_kCapabilityClipboardImages));
|
GHOST_kCapabilityClipboardImages));
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,6 +448,31 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(int32_t x, int32_t y)
|
||||||
return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TSuccess GHOST_SystemWin32::getPixelAtCursor(float r_color[3]) const
|
||||||
|
{
|
||||||
|
POINT point;
|
||||||
|
if (!GetCursorPos(&point)) {
|
||||||
|
return GHOST_kFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC dc = GetDC(NULL);
|
||||||
|
if (dc == NULL) {
|
||||||
|
return GHOST_kFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLORREF color = GetPixel(dc, point.x, point.y);
|
||||||
|
ReleaseDC(NULL, dc);
|
||||||
|
|
||||||
|
if (color == CLR_INVALID) {
|
||||||
|
return GHOST_kFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_color[0] = GetRValue(color) / 255.0f;
|
||||||
|
r_color[1] = GetGValue(color) / 255.0f;
|
||||||
|
r_color[2] = GetBValue(color) / 255.0f;
|
||||||
|
return GHOST_kSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const
|
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||||
{
|
{
|
||||||
/* `GetAsyncKeyState` returns the current interrupt-level state of the hardware, which is needed
|
/* `GetAsyncKeyState` returns the current interrupt-level state of the hardware, which is needed
|
||||||
|
|
|
@ -182,6 +182,13 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y);
|
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the pixel at the current mouse cursor location
|
||||||
|
* \param r_color: returned sRGB float colors
|
||||||
|
* \return Success value (true == successful and supported by platform)
|
||||||
|
*/
|
||||||
|
GHOST_TSuccess getPixelAtCursor(float r_color[3]) const;
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
** Access to mouse button and keyboard states.
|
** Access to mouse button and keyboard states.
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
|
|
@ -1693,6 +1693,8 @@ GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
||||||
{
|
{
|
||||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||||
~(
|
~(
|
||||||
|
/* No support yet for desktop sampling. */
|
||||||
|
GHOST_kCapabilityDesktopSample |
|
||||||
/* No support yet for image copy/paste. */
|
/* No support yet for image copy/paste. */
|
||||||
GHOST_kCapabilityClipboardImages));
|
GHOST_kCapabilityClipboardImages));
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,45 +315,35 @@ static bool eyedropper_cryptomatte_sample_fl(bContext *C,
|
||||||
|
|
||||||
void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3])
|
void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3])
|
||||||
{
|
{
|
||||||
/* we could use some clever */
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
Main *bmain = CTX_data_main(C);
|
ScrArea *area = nullptr;
|
||||||
const char *display_device = CTX_data_scene(C)->display_settings.display_device;
|
|
||||||
ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
|
|
||||||
|
|
||||||
int mval[2];
|
int mval[2];
|
||||||
wmWindow *win;
|
wmWindow *win = WM_window_find_under_cursor(CTX_wm_window(C), m_xy, mval);
|
||||||
ScrArea *area;
|
if (win) {
|
||||||
datadropper_win_area_find(C, m_xy, mval, &win, &area);
|
bScreen *screen = WM_window_get_active_screen(win);
|
||||||
|
area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mval);
|
||||||
|
}
|
||||||
|
|
||||||
if (area) {
|
if (area) {
|
||||||
if (area->spacetype == SPACE_IMAGE) {
|
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
||||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
if (region) {
|
||||||
if (region) {
|
const int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin};
|
||||||
|
if (area->spacetype == SPACE_IMAGE) {
|
||||||
SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
|
SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
|
||||||
const int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin};
|
|
||||||
|
|
||||||
if (ED_space_image_color_sample(sima, region, region_mval, r_col, nullptr)) {
|
if (ED_space_image_color_sample(sima, region, region_mval, r_col, nullptr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (area->spacetype == SPACE_NODE) {
|
||||||
else if (area->spacetype == SPACE_NODE) {
|
|
||||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
|
||||||
if (region) {
|
|
||||||
SpaceNode *snode = static_cast<SpaceNode *>(area->spacedata.first);
|
SpaceNode *snode = static_cast<SpaceNode *>(area->spacedata.first);
|
||||||
const int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin};
|
Main *bmain = CTX_data_main(C);
|
||||||
|
|
||||||
if (ED_space_node_color_sample(bmain, snode, region, region_mval, r_col)) {
|
if (ED_space_node_color_sample(bmain, snode, region, region_mval, r_col)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (area->spacetype == SPACE_CLIP) {
|
||||||
else if (area->spacetype == SPACE_CLIP) {
|
|
||||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
|
||||||
if (region) {
|
|
||||||
SpaceClip *sc = static_cast<SpaceClip *>(area->spacedata.first);
|
SpaceClip *sc = static_cast<SpaceClip *>(area->spacedata.first);
|
||||||
const int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin};
|
|
||||||
|
|
||||||
if (ED_space_clip_color_sample(sc, region, region_mval, r_col)) {
|
if (ED_space_clip_color_sample(sc, region, region_mval, r_col)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -362,9 +352,20 @@ void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win) {
|
if (win) {
|
||||||
WM_window_pixels_read_sample(C, win, mval, r_col);
|
/* Other areas within a Blender window. */
|
||||||
|
if (!WM_window_pixels_read_sample(C, win, mval, r_col)) {
|
||||||
|
WM_window_pixels_read_sample_from_offscreen(C, win, mval, r_col);
|
||||||
|
}
|
||||||
|
const char *display_device = CTX_data_scene(C)->display_settings.display_device;
|
||||||
|
ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
|
||||||
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
|
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
|
||||||
}
|
}
|
||||||
|
else if ((WM_capabilities_flag() & WM_CAPABILITY_DESKTOP_SAMPLE) &&
|
||||||
|
WM_desktop_cursor_sample_read(r_col))
|
||||||
|
{
|
||||||
|
/* Outside of the Blender window if we support it. */
|
||||||
|
IMB_colormanagement_srgb_to_scene_linear_v3(r_col, r_col);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Harley marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
Use When doing color picker of for a 3D viewport or render that Blender displays then taking into account the view transform makes sense. But from another window, it seems wrong to me. Use `IMB_colormanagement_srgb_to_scene_linear_v3` instead if the color came from another window.
When doing color picker of for a 3D viewport or render that Blender displays then taking into account the view transform makes sense. But from another window, it seems wrong to me.
|
|||||||
zero_v3(r_col);
|
zero_v3(r_col);
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,8 @@ enum eWM_CapabilitiesFlag {
|
||||||
WM_CAPABILITY_GPU_FRONT_BUFFER_READ = (1 << 3),
|
WM_CAPABILITY_GPU_FRONT_BUFFER_READ = (1 << 3),
|
||||||
/** Ability to copy/paste system clipboard images. */
|
/** Ability to copy/paste system clipboard images. */
|
||||||
WM_CAPABILITY_CLIPBOARD_IMAGES = (1 << 4),
|
WM_CAPABILITY_CLIPBOARD_IMAGES = (1 << 4),
|
||||||
|
/** Ability to sample a color outside of Blender windows. */
|
||||||
|
WM_CAPABILITY_DESKTOP_SAMPLE = (1 << 5),
|
||||||
/** The initial value, indicates the value needs to be set by inspecting GHOST. */
|
/** The initial value, indicates the value needs to be set by inspecting GHOST. */
|
||||||
WM_CAPABILITY_INITIALIZED = (1 << 31),
|
WM_CAPABILITY_INITIALIZED = (1 << 31),
|
||||||
};
|
};
|
||||||
|
@ -194,6 +196,12 @@ wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mv
|
||||||
*/
|
*/
|
||||||
wmWindow *WM_window_find_by_area(wmWindowManager *wm, const ScrArea *area);
|
wmWindow *WM_window_find_by_area(wmWindowManager *wm, const ScrArea *area);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the color of the pixel at the current mouse cursor position on the desktop, whether in a
|
||||||
|
* Blender window or not. Returns false on failure or if not supported by the platform.
|
||||||
|
*/
|
||||||
|
bool WM_desktop_cursor_sample_read(float r_col[3]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read pixels from the front-buffer (fast).
|
* Read pixels from the front-buffer (fast).
|
||||||
*
|
*
|
||||||
|
|
|
@ -1411,6 +1411,11 @@ bool WM_window_pixels_read_sample(bContext *C, wmWindow *win, const int pos[2],
|
||||||
return WM_window_pixels_read_sample_from_offscreen(C, win, pos, r_col);
|
return WM_window_pixels_read_sample_from_offscreen(C, win, pos, r_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WM_desktop_cursor_sample_read(float r_col[3])
|
||||||
|
{
|
||||||
|
return GHOST_GetPixelAtCursor(r_col);
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
|
@ -1887,6 +1887,9 @@ eWM_CapabilitiesFlag WM_capabilities_flag()
|
||||||
if (ghost_flag & GHOST_kCapabilityClipboardImages) {
|
if (ghost_flag & GHOST_kCapabilityClipboardImages) {
|
||||||
flag |= WM_CAPABILITY_CLIPBOARD_IMAGES;
|
flag |= WM_CAPABILITY_CLIPBOARD_IMAGES;
|
||||||
}
|
}
|
||||||
|
if (ghost_flag & GHOST_kCapabilityDesktopSample) {
|
||||||
|
flag |= WM_CAPABILITY_DESKTOP_SAMPLE;
|
||||||
|
}
|
||||||
|
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Can you change RGB -> sRGB to clarify the color space. Here and a few other places that repeat the same comment.