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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* \param rectanglehandle: The handle to the rectangle.
|
||||
|
|
|
@ -441,6 +441,13 @@ class GHOST_ISystem {
|
|||
*/
|
||||
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
|
||||
/**
|
||||
* Sets 3D mouse deadzone
|
||||
|
|
|
@ -107,6 +107,10 @@ typedef enum {
|
|||
* Set when there is support for system clipboard copy/paste.
|
||||
*/
|
||||
GHOST_kCapabilityClipboardImages = (1 << 4),
|
||||
/**
|
||||
* Support for sampling a color outside of the Blender windows.
|
||||
*/
|
||||
GHOST_kCapabilityDesktopSample = (1 << 5),
|
||||
} GHOST_TCapabilityFlag;
|
||||
|
||||
/**
|
||||
|
@ -115,7 +119,8 @@ typedef enum {
|
|||
*/
|
||||
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||
(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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return ((GHOST_Rect *)rectanglehandle)->getWidth();
|
||||
|
|
|
@ -341,6 +341,11 @@ GHOST_TTabletAPI GHOST_System::getTabletAPI()
|
|||
return m_tabletAPI;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::getPixelAtCursor(float[3] /* r_color */) const
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
void GHOST_System::setNDOFDeadZone(float deadzone)
|
||||
{
|
||||
|
|
|
@ -256,6 +256,13 @@ class GHOST_System : public GHOST_ISystem {
|
|||
virtual void setTabletAPI(GHOST_TTabletAPI api);
|
||||
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
|
||||
/***************************************************************************************
|
||||
* Access to 3D mouse.
|
||||
|
|
|
@ -921,6 +921,8 @@ GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
|
|||
~(
|
||||
/* Cocoa has no support for a primary selection clipboard. */
|
||||
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. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
/* No windowing functionality supported. */
|
||||
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||
GHOST_kCapabilityPrimaryClipboard |
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
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. */
|
||||
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. */
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
|
|
@ -6843,6 +6843,8 @@ GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
|||
* screen-shot and eye-dropper sampling logic, both operations where the overhead
|
||||
* is negligible. */
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
/* `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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
***************************************************************************************/
|
||||
|
|
|
@ -1693,6 +1693,8 @@ GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
|||
{
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* No support yet for desktop sampling. */
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
/* No support yet for image copy/paste. */
|
||||
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])
|
||||
{
|
||||
/* we could use some clever */
|
||||
Main *bmain = CTX_data_main(C);
|
||||
const char *display_device = CTX_data_scene(C)->display_settings.display_device;
|
||||
ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
ScrArea *area = nullptr;
|
||||
|
||||
int mval[2];
|
||||
wmWindow *win;
|
||||
ScrArea *area;
|
||||
datadropper_win_area_find(C, m_xy, mval, &win, &area);
|
||||
wmWindow *win = WM_window_find_under_cursor(CTX_wm_window(C), m_xy, mval);
|
||||
if (win) {
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mval);
|
||||
}
|
||||
|
||||
if (area) {
|
||||
if (area->spacetype == SPACE_IMAGE) {
|
||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
||||
if (region) {
|
||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
||||
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);
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (area->spacetype == SPACE_NODE) {
|
||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
||||
if (region) {
|
||||
else if (area->spacetype == SPACE_NODE) {
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (area->spacetype == SPACE_CLIP) {
|
||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval);
|
||||
if (region) {
|
||||
else if (area->spacetype == SPACE_CLIP) {
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
|
@ -362,9 +352,20 @@ void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3])
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -170,6 +170,8 @@ enum eWM_CapabilitiesFlag {
|
|||
WM_CAPABILITY_GPU_FRONT_BUFFER_READ = (1 << 3),
|
||||
/** Ability to copy/paste system clipboard images. */
|
||||
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. */
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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) {
|
||||
flag |= WM_CAPABILITY_CLIPBOARD_IMAGES;
|
||||
}
|
||||
if (ghost_flag & GHOST_kCapabilityDesktopSample) {
|
||||
flag |= WM_CAPABILITY_DESKTOP_SAMPLE;
|
||||
}
|
||||
|
||||
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.