Fix T90817: Object Picker Doesn't Work on Second window

Solution similar to the one seen in {rBb94ab93dfb82}.

The idea is to find the window and region under the cursor to use in the
operator.

Reviewed By: brecht

Maniphest Tasks: T90817

Differential Revision: https://developer.blender.org/D12310
This commit is contained in:
Germano Cavalcante 2021-08-26 14:13:19 -03:00
parent aadbdb8048
commit 583f694826
Notes: blender-bot 2023-02-14 09:34:18 +01:00
Referenced by issue #91643, Eyedropper does not work across Blender windows
Referenced by issue #90817, Object Picker Doesn't Work on Second window
4 changed files with 37 additions and 31 deletions

View File

@ -126,23 +126,15 @@ void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const cha
}
void eyedropper_draw_cursor_text_region(const struct bContext *C,
const ARegion *region,
const int x,
const int y,
const char *name)
{
wmWindow *win = CTX_wm_window(C);
const int x = win->eventstate->x;
const int y = win->eventstate->y;
if ((name[0] == '\0') || (BLI_rcti_isect_pt(&region->winrct, x, y) == false)) {
if (name[0] == '\0') {
return;
}
const int mval[2] = {
x - region->winrct.xmin,
y - region->winrct.ymin,
};
eyedropper_draw_cursor_text_ex(mval[0], mval[1], name);
eyedropper_draw_cursor_text_ex(x, y, name);
}
/**

View File

@ -71,13 +71,14 @@ typedef struct DataDropper {
ScrArea *cursor_area; /* Area under the cursor */
ARegionType *art;
void *draw_handle_pixel;
int name_pos[2];
char name[200];
} DataDropper;
static void datadropper_draw_cb(const struct bContext *C, ARegion *region, void *arg)
{
DataDropper *ddr = arg;
eyedropper_draw_cursor_text_region(C, region, ddr->name);
eyedropper_draw_cursor_text_region(C, UNPACK2(ddr->name_pos), ddr->name);
}
static int datadropper_init(bContext *C, wmOperator *op)
@ -148,12 +149,10 @@ static void datadropper_exit(bContext *C, wmOperator *op)
/**
* \brief get the ID from the 3D view or outliner.
*/
static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id)
static void datadropper_id_sample_pt(
bContext *C, wmWindow *win, ScrArea *area, DataDropper *ddr, int mx, int my, ID **r_id)
{
/* we could use some clever */
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = BKE_screen_find_area_xy(screen, -1, mx, my);
wmWindow *win_prev = CTX_wm_window(C);
ScrArea *area_prev = CTX_wm_area(C);
ARegion *region_prev = CTX_wm_region(C);
@ -166,6 +165,7 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
Base *base;
CTX_wm_window_set(C, win);
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
@ -202,11 +202,15 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2);
*r_id = id;
}
ddr->name_pos[0] = mval[0];
ddr->name_pos[1] = mval[1];
}
}
}
}
CTX_wm_window_set(C, win_prev);
CTX_wm_area_set(C, area_prev);
CTX_wm_region_set(C, region_prev);
}
@ -232,7 +236,13 @@ static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my)
{
ID *id = NULL;
datadropper_id_sample_pt(C, ddr, mx, my, &id);
wmWindow *win;
ScrArea *area;
int mval[] = {mx, my};
datadropper_win_area_find(C, mval, mval, &win, &area);
datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id);
return datadropper_id_set(C, ddr, id);
}
@ -244,14 +254,8 @@ static void datadropper_cancel(bContext *C, wmOperator *op)
}
/* To switch the draw callback when region under mouse event changes */
static void datadropper_set_draw_callback_region(bContext *C,
DataDropper *ddr,
const int mx,
const int my)
static void datadropper_set_draw_callback_region(bContext *C, ScrArea *area, DataDropper *ddr)
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = BKE_screen_find_area_xy(screen, -1, mx, my);
if (area) {
/* If spacetype changed */
if (area->spacetype != ddr->cursor_area->spacetype) {
@ -300,10 +304,16 @@ static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
else if (event->type == MOUSEMOVE) {
ID *id = NULL;
/* Set the region for eyedropper cursor text drawing */
datadropper_set_draw_callback_region(C, ddr, event->x, event->y);
wmWindow *win;
ScrArea *area;
datadropper_id_sample_pt(C, ddr, event->x, event->y, &id);
int mval[] = {event->x, event->y};
datadropper_win_area_find(C, mval, mval, &win, &area);
/* Set the region for eyedropper cursor text drawing */
datadropper_set_draw_callback_region(C, area, ddr);
datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id);
}
return OPERATOR_RUNNING_MODAL;

View File

@ -72,13 +72,14 @@ typedef struct DepthDropper {
ARegionType *art;
void *draw_handle_pixel;
int name_pos[2];
char name[200];
} DepthDropper;
static void depthdropper_draw_cb(const struct bContext *C, ARegion *region, void *arg)
{
DepthDropper *ddr = arg;
eyedropper_draw_cursor_text_region(C, region, ddr->name);
eyedropper_draw_cursor_text_region(C, UNPACK2(ddr->name_pos), ddr->name);
}
static int depthdropper_init(bContext *C, wmOperator *op)
@ -172,6 +173,8 @@ static void depthdropper_depth_sample_pt(
/* weak, we could pass in some reference point */
const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
copy_v2_v2_int(ddr->name_pos, mval);
float co[3];
CTX_wm_area_set(C, area);

View File

@ -25,7 +25,8 @@
/* interface_eyedropper.c */
void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const char *name);
void eyedropper_draw_cursor_text_region(const struct bContext *C,
const struct ARegion *region,
const int x,
const int y,
const char *name);
uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event);
void datadropper_win_area_find(const struct bContext *C,