From 9175911ffabefcd00f15d847ffdf8afe5efadb10 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Apr 2021 17:17:49 +1000 Subject: Fix spin-gizmo button tool-tip placement gizmo_button2d_bounds result wasn't valid when the gizmo was part of a 3D gizmo group. Regression in cf6d17a6aa421e0038fc1f8e60e3f1f708887c3e --- .../gizmo_library/gizmo_types/button2d_gizmo.c | 40 +++++++++++++++++++--- .../editors/interface/interface_region_tooltip.c | 7 ++-- .../space_view3d/view3d_gizmo_navigate_type.c | 3 +- source/blender/windowmanager/gizmo/wm_gizmo_fn.h | 4 +-- 4 files changed, 43 insertions(+), 11 deletions(-) (limited to 'source') diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index f4c4e4eb2ac..d99ce25451c 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -320,14 +320,44 @@ static int gizmo_button2d_cursor_get(wmGizmo *gz) return WM_CURSOR_DEFAULT; } -static void gizmo_button2d_bounds(bContext *C, wmGizmo *gz, rcti *r_bounding_box) +static bool gizmo_button2d_bounds(bContext *C, wmGizmo *gz, rcti *r_bounding_box) { ScrArea *area = CTX_wm_area(C); float rad = CIRCLE_RESOLUTION * U.dpi_fac / 2.0f; - r_bounding_box->xmin = gz->matrix_basis[3][0] + area->totrct.xmin - rad; - r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad; - r_bounding_box->xmax = r_bounding_box->xmin + rad; - r_bounding_box->ymax = r_bounding_box->ymin + rad; + const float *co = NULL; + float matrix_final[4][4]; + float co_proj[3]; + WM_gizmo_calc_matrix_final(gz, matrix_final); + + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + ARegion *region = CTX_wm_region(C); + if (ED_view3d_project_float_global(region, matrix_final[3], co_proj, V3D_PROJ_TEST_NOP) == + V3D_PROJ_RET_OK) { + float matrix_final_no_offset[4][4]; + const RegionView3D *rv3d = region->regiondata; + WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset); + const float factor = ED_view3d_pixel_size_no_ui_scale(rv3d, matrix_final_no_offset[3]) / + ED_view3d_pixel_size_no_ui_scale(rv3d, matrix_final[3]); + /* It's possible (although unlikely) `matrix_final_no_offset` is behind the view. + * `matrix_final` has already been projected so both can't be negative. */ + if (factor > 0.0f) { + rad *= factor; + } + co = co_proj; + } + } + else { + co = matrix_final[3]; + } + + if (co != NULL) { + r_bounding_box->xmin = co[0] + area->totrct.xmin - rad; + r_bounding_box->ymin = co[1] + area->totrct.ymin - rad; + r_bounding_box->xmax = r_bounding_box->xmin + rad; + r_bounding_box->ymax = r_bounding_box->ymin + rad; + return true; + } + return false; } static void gizmo_button2d_free(wmGizmo *gz) diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 07e17033ee5..b11a727b173 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -1469,9 +1469,10 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) */ if (gz->type->screen_bounds_get) { rcti bounds; - gz->type->screen_bounds_get(C, gz, &bounds); - init_position[0] = bounds.xmin; - init_position[1] = bounds.ymin; + if (gz->type->screen_bounds_get(C, gz, &bounds)) { + init_position[0] = bounds.xmin; + init_position[1] = bounds.ymin; + } } return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 4ac16e8fbe8..05ea35f114f 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -372,7 +372,7 @@ static int gizmo_axis_cursor_get(wmGizmo *UNUSED(gz)) return WM_CURSOR_DEFAULT; } -static void gizmo_axis_screen_bounds_get(bContext *C, wmGizmo *gz, rcti *r_bounding_box) +static bool gizmo_axis_screen_bounds_get(bContext *C, wmGizmo *gz, rcti *r_bounding_box) { ScrArea *area = CTX_wm_area(C); const float rad = WIDGET_RADIUS; @@ -380,6 +380,7 @@ static void gizmo_axis_screen_bounds_get(bContext *C, wmGizmo *gz, rcti *r_bound r_bounding_box->ymin = gz->matrix_basis[3][1] + area->totrct.ymin - rad; r_bounding_box->xmax = r_bounding_box->xmin + rad; r_bounding_box->ymax = r_bounding_box->ymin + rad; + return true; } void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt) diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h index 84e6308223f..ac4f6b761ac 100644 --- a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h +++ b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h @@ -62,9 +62,9 @@ typedef void (*wmGizmoFnMatrixBasisGet)(const struct wmGizmo *, float[4][4]); typedef int (*wmGizmoFnInvoke)(struct bContext *, struct wmGizmo *, const struct wmEvent *); typedef void (*wmGizmoFnExit)(struct bContext *, struct wmGizmo *, const bool); typedef int (*wmGizmoFnCursorGet)(struct wmGizmo *); -typedef void (*wmGizmoFnScreenBoundsGet)(struct bContext *, +typedef bool (*wmGizmoFnScreenBoundsGet)(struct bContext *, struct wmGizmo *, - rcti *r_bounding_box); + rcti *r_bounding_box) ATTR_WARN_UNUSED_RESULT; typedef void (*wmGizmoFnSelectRefresh)(struct wmGizmo *); typedef void (*wmGizmoFnFree)(struct wmGizmo *); -- cgit v1.2.3