/** * \brief get the color from the screen. * * Special check for image or nodes where we MAY have HDR pixels which don't display. */ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int mx, int my, float r_col[3]) { /* we could use some clever */ wmWindow *win = CTX_wm_window(C); ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my); if (sa) { if (sa->spacetype == SPACE_IMAGE) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { SpaceImage *sima = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) { return; } } } else if (sa->spacetype == SPACE_NODE) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { SpaceNode *snode = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) { return; } } } else if (sa->spacetype == SPACE_CLIP) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { SpaceClip *sc = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) { return; } } } } /* fallback to simple opengl picker */ glReadBuffer(GL_FRONT); glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col); glReadBuffer(GL_BACK); }
/** * \brief get the ID from the screen. */ static void depthdropper_depth_sample_pt( bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth) { /* we could use some clever */ bScreen *screen = CTX_wm_screen(C); ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my); Scene *scene = CTX_data_scene(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); ddr->name[0] = '\0'; if (sa) { if (sa->spacetype == SPACE_VIEW3D) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { struct Depsgraph *depsgraph = CTX_data_depsgraph(C); View3D *v3d = sa->spacedata.first; RegionView3D *rv3d = ar->regiondata; /* 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 - ar->winrct.xmin, my - ar->winrct.ymin}; float co[3]; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* grr, always draw else we leave stale text */ ED_region_tag_redraw(ar); view3d_operator_needs_opengl(C); if (ED_view3d_autodist(depsgraph, ar, v3d, mval, co, true, NULL)) { const float mval_center_fl[2] = {(float)ar->winx / 2, (float)ar->winy / 2}; float co_align[3]; /* quick way to get view-center aligned point */ ED_view3d_win_to_3d(v3d, ar, co, mval_center_fl, co_align); *r_depth = len_v3v3(view_co, co_align); bUnit_AsString2(ddr->name, sizeof(ddr->name), (double)*r_depth, 4, B_UNIT_LENGTH, &scene->unit, false); } else { BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name)); } } } } CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
/** * \brief get the ID from the screen. * */ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id) { /* we could use some clever */ wmWindow *win = CTX_wm_window(C); ScrArea *sa = BKE_screen_find_area_xy(win->screen, -1, mx, my); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); ddr->name[0] = '\0'; if (sa) { if (sa->spacetype == SPACE_VIEW3D) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { const int mval[2] = { mx - ar->winrct.xmin, my - ar->winrct.ymin}; Base *base; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* grr, always draw else we leave stale text */ ED_region_tag_redraw(ar); base = ED_view3d_give_base_under_cursor(C, mval); if (base) { Object *ob = base->object; ID *id = NULL; if (ddr->idcode == ID_OB) { id = (ID *)ob; } else if (ob->data) { if (GS(((ID *)ob->data)->name) == ddr->idcode) { id = (ID *)ob->data; } else { BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s", ddr->idcode_name); } } if (id) { BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2); *r_id = id; } } } } } CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
/** * Utility to retrieve a button representing a RNA property that is currently under the cursor. * * This is to be used by any eyedroppers which fetch properties (e.g. UI_OT_eyedropper_driver). * Especially during modal operations (e.g. as with the eyedroppers), context cannot be relied * upon to provide this information, as it is not updated until the operator finishes. * * \return A button under the mouse which relates to some RNA Property, or NULL */ static uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, event->x, event->y); ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_ANY, event->x, event->y); uiBut *but = ui_but_find_mouse_over(ar, event); if (ELEM(NULL, but, but->rnapoin.data, but->rnaprop)) { return NULL; } else { return but; } }