Fix #108722 : Measures not cleared when removing annotation layer

Removing the layer would leave the ruler gizmos on screen, only way to
update was changing to another tool and back. Now remove all
corresponding gizmo ruler items found (also in different windows/scenes)
when removing the ruler annotation layer.

Also add a proper notifier that grease pencil was edited (this way we
also get immediate update when a ruler annotation layer was added --
which was also missing).

Pull Request: https://projects.blender.org/blender/blender/pulls/135571
This commit is contained in:
Philipp Oeser
2025-03-07 09:52:01 +01:00
committed by Philipp Oeser
parent d18fe0c575
commit 084cb40e98
3 changed files with 55 additions and 1 deletions

View File

@@ -41,6 +41,7 @@
#include "ED_gpencil_legacy.hh"
#include "ED_object.hh"
#include "ED_view3d.hh"
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_build.hh"
@@ -246,6 +247,10 @@ static int gpencil_layer_remove_exec(bContext *C, wmOperator *op)
BKE_gpencil_layer_active_set(gpd, gpl->next);
}
if (gpl->flag & GP_LAYER_IS_RULER) {
ED_view3d_gizmo_ruler_remove_by_gpencil_layer(C, gpl);
}
/* delete the layer now... */
BKE_gpencil_layer_delete(gpd, gpl);

View File

@@ -46,6 +46,7 @@ struct ViewContext;
struct ViewLayer;
struct ViewOpsData;
struct bContext;
struct bGPDlayer;
struct bPoseChannel;
struct bScreen;
struct rctf;
@@ -1348,6 +1349,13 @@ void ED_view3d_gizmo_mesh_preselect_get_active(const bContext *C,
BMElem **r_ele);
void ED_view3d_gizmo_mesh_preselect_clear(wmGizmo *gz);
/* view3d_gizmo_ruler.cc */
/**
* Remove all rulers when Annotation layer is removed.
*/
void ED_view3d_gizmo_ruler_remove_by_gpencil_layer(struct bContext *C, bGPDlayer *gpl);
/* `space_view3d.cc` */
void ED_view3d_buttons_region_layout_ex(const bContext *C,

View File

@@ -632,6 +632,44 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup)
return changed;
}
void ED_view3d_gizmo_ruler_remove_by_gpencil_layer(bContext *C, bGPDlayer *gpl)
{
wmWindowManager *wm = CTX_wm_manager(C);
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
const Scene *scene = WM_window_get_active_scene(win);
if (!scene->gpd) {
continue;
}
bGPDlayer *gpl_scene = view3d_ruler_layer_get(scene->gpd);
if (gpl_scene != gpl) {
continue;
}
const bScreen *screen = WM_window_get_active_screen(win);
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
if (!region) {
continue;
}
wmGizmoMap *gzmap = region->runtime->gizmo_map;
wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id);
RulerItem *ruler_item;
while ((ruler_item = gzgroup_ruler_item_first_get(gzgroup))) {
ruler_item_remove(C, gzgroup, ruler_item);
}
ED_region_tag_redraw_editor_overlays(region);
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -1210,7 +1248,10 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
ruler_state_set(ruler_info, RULER_STATE_NORMAL);
}
/* We could convert only the current gizmo, for now just re-generate. */
view3d_ruler_to_gpencil(C, gzgroup);
if (view3d_ruler_to_gpencil(C, gzgroup)) {
/* For immediate update when a ruler annotation layer was added. */
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
}
MEM_SAFE_FREE(gz->interaction_data);