Eyedropper: Support get samples from other windows
This fix T77226 Differential Revision: https://developer.blender.org/D7910
This commit is contained in:
@@ -138,11 +138,26 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
|
|||||||
{
|
{
|
||||||
/* we could use some clever */
|
/* we could use some clever */
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
bScreen *screen = CTX_wm_screen(C);
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
|
|
||||||
const char *display_device = CTX_data_scene(C)->display_settings.display_device;
|
const char *display_device = CTX_data_scene(C)->display_settings.display_device;
|
||||||
struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
|
struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
|
||||||
|
|
||||||
|
wmWindow *win = CTX_wm_window(C);
|
||||||
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
|
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
|
||||||
|
if (area == NULL) {
|
||||||
|
int mval[2] = {mx, my};
|
||||||
|
if (WM_window_find_under_cursor(wm, NULL, win, mval, &win, mval)) {
|
||||||
|
mx = mval[0];
|
||||||
|
my = mval[1];
|
||||||
|
screen = WM_window_get_active_screen(win);
|
||||||
|
area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
win = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (area) {
|
if (area) {
|
||||||
if (area->spacetype == SPACE_IMAGE) {
|
if (area->spacetype == SPACE_IMAGE) {
|
||||||
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my);
|
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my);
|
||||||
@@ -179,12 +194,15 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fallback to simple opengl picker */
|
if (win) {
|
||||||
glReadBuffer(GL_FRONT);
|
/* Fallback to simple opengl picker. */
|
||||||
glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
|
int mval[2] = {mx, my};
|
||||||
glReadBuffer(GL_BACK);
|
WM_window_pixel_sample_read(wm, win, mval, r_col);
|
||||||
|
|
||||||
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
|
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zero_v3(r_col);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sets the sample color RGB, maintaining A */
|
/* sets the sample color RGB, maintaining A */
|
||||||
|
|||||||
@@ -106,6 +106,17 @@ void WM_reinit_gizmomap_all(struct Main *bmain);
|
|||||||
|
|
||||||
void WM_script_tag_reload(void);
|
void WM_script_tag_reload(void);
|
||||||
|
|
||||||
|
bool WM_window_find_under_cursor(const wmWindowManager *wm,
|
||||||
|
const wmWindow *win_ignore,
|
||||||
|
const wmWindow *win,
|
||||||
|
const int mval[2],
|
||||||
|
wmWindow **r_win,
|
||||||
|
int r_mval[2]);
|
||||||
|
void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
||||||
|
const wmWindow *win,
|
||||||
|
const int pos[2],
|
||||||
|
float r_col[3]);
|
||||||
|
|
||||||
uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, int r_size[2]);
|
uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, int r_size[2]);
|
||||||
|
|
||||||
int WM_window_pixels_x(const struct wmWindow *win);
|
int WM_window_pixels_x(const struct wmWindow *win);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
@@ -4254,7 +4254,7 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
|
|||||||
/* imperfect but probably usable... draw/enable drags to other windows */
|
/* imperfect but probably usable... draw/enable drags to other windows */
|
||||||
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
||||||
{
|
{
|
||||||
int mx = event->x, my = event->y;
|
int mval[2] = {event->x, event->y};
|
||||||
|
|
||||||
if (wm->windows.first == wm->windows.last) {
|
if (wm->windows.first == wm->windows.last) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -4263,7 +4263,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
|
|||||||
/* in order to use window size and mouse position (pixels), we have to use a WM function */
|
/* in order to use window size and mouse position (pixels), we have to use a WM function */
|
||||||
|
|
||||||
/* check if outside, include top window bar... */
|
/* check if outside, include top window bar... */
|
||||||
if (mx < 0 || my < 0 || mx > WM_window_pixels_x(win) || my > WM_window_pixels_y(win) + 30) {
|
if (mval[0] < 0 || mval[1] < 0 || mval[0] > WM_window_pixels_x(win) ||
|
||||||
|
mval[1] > WM_window_pixels_y(win) + 30) {
|
||||||
wmWindow *owin;
|
wmWindow *owin;
|
||||||
wmEventHandler *handler;
|
wmEventHandler *handler;
|
||||||
|
|
||||||
@@ -4276,27 +4277,12 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* to desktop space */
|
if (WM_window_find_under_cursor(wm, win, win, mval, &owin, mval)) {
|
||||||
mx += (int)(U.pixelsize * win->posx);
|
event->x = mval[0];
|
||||||
my += (int)(U.pixelsize * win->posy);
|
event->y = mval[1];
|
||||||
|
|
||||||
/* check other windows to see if it has mouse inside */
|
|
||||||
for (owin = wm->windows.first; owin; owin = owin->next) {
|
|
||||||
|
|
||||||
if (owin != win) {
|
|
||||||
int posx = (int)(U.pixelsize * owin->posx);
|
|
||||||
int posy = (int)(U.pixelsize * owin->posy);
|
|
||||||
|
|
||||||
if (mx - posx >= 0 && owin->posy >= 0 && mx - posx <= WM_window_pixels_x(owin) &&
|
|
||||||
my - posy <= WM_window_pixels_y(owin)) {
|
|
||||||
event->x = mx - (int)(U.pixelsize * owin->posx);
|
|
||||||
event->y = my - (int)(U.pixelsize * owin->posy);
|
|
||||||
|
|
||||||
return owin;
|
return owin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1983,6 +1983,90 @@ bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut)
|
|||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Find Window Utility
|
||||||
|
*
|
||||||
|
* \{ */
|
||||||
|
static void wm_window_desktop_pos_get(const wmWindow *win,
|
||||||
|
const int screen_pos[2],
|
||||||
|
int r_desk_pos[2])
|
||||||
|
{
|
||||||
|
/* To desktop space. */
|
||||||
|
r_desk_pos[0] = screen_pos[0] + (int)(U.pixelsize * win->posx);
|
||||||
|
r_desk_pos[1] = screen_pos[1] + (int)(U.pixelsize * win->posy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wm_window_screen_pos_get(const wmWindow *win,
|
||||||
|
const int desktop_pos[2],
|
||||||
|
int r_scr_pos[2])
|
||||||
|
{
|
||||||
|
/* To window space. */
|
||||||
|
r_scr_pos[0] = desktop_pos[0] - (int)(U.pixelsize * win->posx);
|
||||||
|
r_scr_pos[1] = desktop_pos[1] - (int)(U.pixelsize * win->posy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WM_window_find_under_cursor(const wmWindowManager *wm,
|
||||||
|
const wmWindow *win_ignore,
|
||||||
|
const wmWindow *win,
|
||||||
|
const int mval[2],
|
||||||
|
wmWindow **r_win,
|
||||||
|
int r_mval[2])
|
||||||
|
{
|
||||||
|
int desk_pos[2];
|
||||||
|
wm_window_desktop_pos_get(win, mval, desk_pos);
|
||||||
|
|
||||||
|
/* TODO: This should follow the order of the activated windows.
|
||||||
|
* The current solution is imperfect but usable in most cases. */
|
||||||
|
LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) {
|
||||||
|
if (win_iter == win_ignore) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (win_iter->windowstate == GHOST_kWindowStateMinimized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scr_pos[2];
|
||||||
|
wm_window_screen_pos_get(win_iter, desk_pos, scr_pos);
|
||||||
|
|
||||||
|
if (scr_pos[0] >= 0 && win_iter->posy >= 0 && scr_pos[0] <= WM_window_pixels_x(win_iter) &&
|
||||||
|
scr_pos[1] <= WM_window_pixels_y(win_iter)) {
|
||||||
|
|
||||||
|
*r_win = win_iter;
|
||||||
|
copy_v2_v2_int(r_mval, scr_pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WM_window_pixel_sample_read(const wmWindowManager *wm,
|
||||||
|
const wmWindow *win,
|
||||||
|
const int pos[2],
|
||||||
|
float r_col[3])
|
||||||
|
{
|
||||||
|
bool setup_context = wm->windrawable != win;
|
||||||
|
|
||||||
|
if (setup_context) {
|
||||||
|
GHOST_ActivateWindowDrawingContext(win->ghostwin);
|
||||||
|
GPU_context_active_set(win->gpuctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
glReadBuffer(GL_FRONT);
|
||||||
|
glReadPixels(pos[0], pos[1], 1, 1, GL_RGB, GL_FLOAT, r_col);
|
||||||
|
glReadBuffer(GL_BACK);
|
||||||
|
|
||||||
|
if (setup_context) {
|
||||||
|
if (wm->windrawable) {
|
||||||
|
GHOST_ActivateWindowDrawingContext(wm->windrawable->ghostwin);
|
||||||
|
GPU_context_active_set(wm->windrawable->gpuctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Window Screen Shot Utility
|
/** \name Window Screen Shot Utility
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user