diff options
author | Germano Cavalcante <germano.costa@ig.com.br> | 2020-06-03 21:45:43 +0300 |
---|---|---|
committer | Germano Cavalcante <germano.costa@ig.com.br> | 2020-06-03 21:45:57 +0300 |
commit | b94ab93dfb82275c5c6241f8de1556c4f4be934c (patch) | |
tree | aa807125aa51799606acfd79f5344a303887a432 /source/blender/windowmanager | |
parent | a4e0bccb87bbcc6ff6f36a428aa402576de5f9ec (diff) |
Eyedropper: Support get samples from other windows
This fix T77226
Differential Revision: https://developer.blender.org/D7910
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 30 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 84 |
3 files changed, 103 insertions, 22 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ffa5bc15876..8783f2b5335 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -106,6 +106,17 @@ void WM_reinit_gizmomap_all(struct Main *bmain); 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]); int WM_window_pixels_x(const struct wmWindow *win); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e5f288b1963..53d6df915d6 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1,4 +1,4 @@ -/* +/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * 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 */ 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) { 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 */ /* 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; wmEventHandler *handler; @@ -4276,25 +4277,10 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi } } - /* to desktop space */ - mx += (int)(U.pixelsize * win->posx); - my += (int)(U.pixelsize * win->posy); - - /* 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; - } - } + if (WM_window_find_under_cursor(wm, win, win, mval, &owin, mval)) { + event->x = mval[0]; + event->y = mval[1]; + return owin; } } return NULL; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 02b50af0ac3..1ba22652157 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1984,6 +1984,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 * * Include here since it can involve low level buffer switching. |