UI: improve HUD ensure/clear logic

Running operators w/o redo now clears the HUD immediately.
This commit is contained in:
Campbell Barton 2018-06-12 16:49:52 +02:00
parent deb3d73eea
commit 2a3e7fe656
Notes: blender-bot 2023-02-14 06:25:25 +01:00
Referenced by issue #55457, Crash after failed vertice merge
3 changed files with 43 additions and 22 deletions

View File

@ -320,6 +320,7 @@ void ED_region_cache_draw_cached_segments(const struct ARegion *ar, const int nu
/* interface_region_hud.c */
struct ARegionType *ED_area_type_hud(int space_type);
void ED_area_type_hud_clear(struct wmWindowManager *wm, ScrArea *sa_keep);
void ED_area_type_hud_ensure(struct bContext *C, struct ScrArea *sa);
/* default keymaps, bitflags */

View File

@ -210,27 +210,30 @@ static ARegion *hud_region_add(ScrArea *sa)
return ar;
}
void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
void ED_area_type_hud_clear(wmWindowManager *wm, ScrArea *sa_keep)
{
/* We only want one at a time. */
Main *bmain = CTX_data_main(C);
for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
for (wmWindow *win = wm->windows.first; win; win = win->next) {
bScreen *screen = WM_window_get_active_screen(win);
for (ScrArea *sa_iter = screen->areabase.first; sa_iter; sa_iter = sa_iter->next) {
if (sa != sa_iter) {
for (ARegion *ar = sa_iter->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_HUD) {
if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
ar->flag |= RGN_FLAG_HIDDEN;
ED_region_tag_redraw(ar);
}
for (wmWindow *win = wm->windows.first; win; win = win->next) {
bScreen *screen = WM_window_get_active_screen(win);
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
if (sa != sa_keep) {
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_HUD) {
if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
ar->flag |= RGN_FLAG_HIDDEN;
ED_region_tag_redraw(ar);
ED_area_tag_redraw(sa);
}
}
}
}
}
}
}
void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
{
wmWindowManager *wm = CTX_wm_manager(C);
ED_area_type_hud_clear(wm, sa);
ARegionType *art = BKE_regiontype_from_id(sa->type, RGN_TYPE_HUD);
if (art == NULL) {
@ -241,6 +244,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HUD);
if (!last_redo_poll(C)) {
if (ar) {
ED_region_tag_redraw(ar);
ar->flag |= RGN_FLAG_HIDDEN;
}
return;

View File

@ -843,6 +843,7 @@ static bool wm_operator_register_check(wmWindowManager *wm, wmOperatorType *ot)
static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat, const bool store)
{
wmWindowManager *wm = CTX_wm_manager(C);
enum { NOP, SET, CLEAR, } hud_status = NOP;
op->customdata = NULL;
@ -854,10 +855,15 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat,
* called from operators that already do an undo push. usually
* this will happen for python operators that call C operators */
if (wm->op_undo_depth == 0) {
if (op->type->flag & OPTYPE_UNDO)
if (op->type->flag & OPTYPE_UNDO) {
ED_undo_push_op(C, op);
else if (op->type->flag & OPTYPE_UNDO_GROUPED)
hud_status = CLEAR;
}
else if (op->type->flag & OPTYPE_UNDO_GROUPED) {
ED_undo_grouped_push_op(C, op);
hud_status = CLEAR;
}
}
if (repeat == 0) {
@ -875,17 +881,27 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat,
WM_operator_region_active_win_set(C);
/* Show the redo panel. */
{
ScrArea *sa = CTX_wm_area(C);
if (sa) {
ED_area_type_hud_ensure(C, sa);
}
}
hud_status = SET;
}
else {
WM_operator_free(op);
}
}
if (hud_status != NOP) {
if (hud_status == SET) {
ScrArea *sa = CTX_wm_area(C);
if (sa) {
ED_area_type_hud_ensure(C, sa);
}
}
else if (hud_status == CLEAR) {
ED_area_type_hud_clear(wm, NULL);
}
else {
BLI_assert(0);
}
}
}
/* if repeat is true, it doesn't register again, nor does it free */