diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-06-12 11:11:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-06-12 11:42:49 +0300 |
commit | 4bf331c0fcfebf211443bdd15181a334cdf1566b (patch) | |
tree | 5d2188bdb5799f8130212c6683930c60fb7cc379 /source/blender | |
parent | 3937e8fbc3bb6ec7bdd3caad26e4e8a504ee5100 (diff) |
UI: Initial persistent floating redo panel
This is the first step to moving redo out of the top-bar, see: T55039
- Support for floating panels in the ScrArea has been added.
- A new region type RGN_TYPE_HUD is used for floating settings input.
- Only one HUD should be visible at a time.
- Currently HUD regions are only visible
for 3D view and image space types.
- There are currently some remaining glitches with hide/show
that need further investigation.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 4 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 17 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_region_hud.c | 276 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 70 | ||||
-rw-r--r-- | source/blender/editors/space_image/space_image.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 8 |
10 files changed, 377 insertions, 12 deletions
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 2291e70fa4d..97653286f28 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -318,6 +318,10 @@ void ED_region_cache_draw_background(const struct ARegion *ar); void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y); void ED_region_cache_draw_cached_segments(const struct ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra); +/* interface_region_hud.c */ +struct ARegionType *ED_area_type_hud(int space_type); +void ED_area_type_hud_ensure(struct bContext *C, struct ScrArea *sa); + /* default keymaps, bitflags */ #define ED_KEYMAP_UI 1 #define ED_KEYMAP_VIEW2D 2 diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index c82a320268f..547cfc65c09 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -830,6 +830,7 @@ struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, struct List void UI_panel_end(uiBlock *block, int width, int height); void UI_panels_scale(struct ARegion *ar, float new_width); void UI_panel_label_offset(struct uiBlock *block, int *x, int *y); +int UI_panel_size_y(const struct Panel *pa); bool UI_panel_category_is_visible(struct ARegion *ar); void UI_panel_category_add(struct ARegion *ar, const char *name); diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 49fe6bfb2dc..07ba3b90e11 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -58,6 +58,7 @@ set(SRC interface_panel.c interface_regions.c interface_region_color_picker.c + interface_region_hud.c interface_region_menu_pie.c interface_region_menu_popup.c interface_region_popover.c diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index dbdf2a0863c..e383ae42f8c 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -110,7 +110,7 @@ typedef struct uiHandlePanelData { int startsizex, startsizey; } uiHandlePanelData; -static int get_panel_real_size_y(Panel *pa); +static int get_panel_real_size_y(const Panel *pa); static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state); /*********************** space specific code ************************/ @@ -855,7 +855,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con /************************** panel alignment *************************/ -static int get_panel_header(Panel *pa) +static int get_panel_header(const Panel *pa) { if (pa->type && (pa->type->flag & PNL_NO_HEADER)) return 0; @@ -863,7 +863,7 @@ static int get_panel_header(Panel *pa) return PNL_HEADER; } -static int get_panel_size_y(Panel *pa) +static int get_panel_size_y(const Panel *pa) { if (pa->type && (pa->type->flag & PNL_NO_HEADER)) return pa->sizey; @@ -871,7 +871,7 @@ static int get_panel_size_y(Panel *pa) return PNL_HEADER + pa->sizey; } -static int get_panel_real_size_y(Panel *pa) +static int get_panel_real_size_y(const Panel *pa) { int sizey = (pa->flag & PNL_CLOSED) ? 0 : pa->sizey; @@ -881,6 +881,11 @@ static int get_panel_real_size_y(Panel *pa) return PNL_HEADER + sizey; } +int UI_panel_size_y(const Panel *pa) +{ + return get_panel_real_size_y(pa); +} + /* this function is needed because uiBlock and Panel itself don't * change sizey or location when closed */ static int get_panel_real_ofsy(Panel *pa) @@ -1596,6 +1601,10 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in ED_region_tag_redraw(ar); } else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) { + /* XXX, for now don't allow dragging in floating windows yet. */ + if (ar->alignment == RGN_ALIGN_FLOAT) { + return; + } panel_activate_state(C, block->panel, PANEL_STATE_DRAG); } else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) { diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c new file mode 100644 index 00000000000..ad779d2580f --- /dev/null +++ b/source/blender/editors/interface/interface_region_hud.c @@ -0,0 +1,276 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/interface/interface_region_hud.c + * \ingroup edinterface + * + * Floating Persistent Region + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_userdef_types.h" + +#include "BLI_string.h" +#include "BLI_rect.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_screen.h" +#include "BKE_main.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" + +#include "BIF_gl.h" + +#include "UI_interface.h" +#include "UI_view2d.h" + +#include "BLT_translation.h" + +#include "ED_screen.h" +#include "ED_undo.h" + +#include "interface_intern.h" + + +/* -------------------------------------------------------------------- */ +/** \name Utilities + * \{ */ + +static bool last_redo_poll(const bContext *C) +{ + wmOperator *op = WM_operator_last_redo(C); + if (op == NULL) { + return false; + } + bool success = false; + if (!WM_operator_check_ui_empty(op->type)) { + success = WM_operator_poll((bContext *)C, op->type); + } + return success; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Redo Panel + * \{ */ + +static int hud_panel_operator_redo_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + return last_redo_poll(C); +} + +static void hud_panel_operator_redo_draw_header(const bContext *C, Panel *pa) +{ + wmOperator *op = WM_operator_last_redo(C); + BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname)); +} + +static void hud_panel_operator_redo_draw(const bContext *C, Panel *pa) +{ + wmOperator *op = WM_operator_last_redo(C); + if (op == NULL) { + return; + } + if (!WM_operator_check_ui_enabled(C, op->type->name)) { + uiLayoutSetEnabled(pa->layout, false); + } + uiLayout *col = uiLayoutColumn(pa->layout, false); + uiTemplateOperatorRedoProperties(col, C); +} + +static void hud_panels_register(ARegionType *art, int space_type, int region_type) +{ + PanelType *pt; + + pt = MEM_callocN(sizeof(PanelType), __func__); + strcpy(pt->idname, "OPERATOR_PT_redo"); + strcpy(pt->label, N_("Redo")); + strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + pt->draw_header = hud_panel_operator_redo_draw_header; + pt->draw = hud_panel_operator_redo_draw; + pt->poll = hud_panel_operator_redo_poll; + pt->space_type = space_type; + pt->region_type = region_type; + BLI_addtail(&art->paneltypes, pt); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for Floating Region + * \{ */ + +static void hud_region_init(wmWindowManager *wm, ARegion *ar) +{ + ED_region_panels_init(wm, ar); + UI_region_handlers_add(&ar->handlers); +} + +static void hud_region_layout(const bContext *C, ARegion *ar) +{ + if (!last_redo_poll(C)) { + ED_region_tag_redraw(ar); + ar->flag |= RGN_FLAG_HIDDEN; + return; + } + + int size_y = ar->sizey; + + ED_region_panels_layout_ex(C, ar, NULL, -1, true); + + if (ar->panels.first && (ar->sizey != size_y)) { + View2D *v2d = &ar->v2d; + ar->winx = ar->sizex; + ar->winy = ar->sizey; + + ar->winrct.xmax = (ar->winrct.xmin + ar->winx) - 1; + ar->winrct.ymax = (ar->winrct.ymin + ar->winy) - 1; + + UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); + } + + /* restore view matrix */ + UI_view2d_view_restore(C); +} + +static void hud_region_draw(const bContext *C, ARegion *ar) +{ + UI_view2d_view_ortho(&ar->v2d); + wmOrtho2_region_pixelspace(ar); + glClearColor(0, 0, 0, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + if ((ar->flag & RGN_FLAG_HIDDEN) == 0) { + ui_draw_widget_back(UI_WTYPE_BOX, false, &(rcti){.xmax = ar->winx, .ymax = ar->winy}); + ED_region_panels_draw(C, ar); + } +} + +ARegionType *ED_area_type_hud(int space_type) +{ + ARegionType *art = MEM_callocN(sizeof(ARegionType), __func__); + art->regionid = RGN_TYPE_HUD; + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; + art->layout = hud_region_layout; + art->draw = hud_region_draw; + art->init = hud_region_init; + + hud_panels_register(art, space_type, art->regionid); + + art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */ + return art; +} + +static ARegion *hud_region_add(ScrArea *sa) +{ + ARegion *ar = MEM_callocN(sizeof(ARegion), "area region"); + ARegion *ar_win = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + if (ar_win) { + BLI_insertlinkbefore(&sa->regionbase, ar_win, ar); + } + else { + BLI_addtail(&sa->regionbase, ar); + } + ar->regiontype = RGN_TYPE_HUD; + ar->alignment = RGN_ALIGN_FLOAT; + ar->overlap = true; + ar->flag |= RGN_FLAG_DYNAMIC_SIZE; + + return ar; +} + +void ED_area_type_hud_ensure(bContext *C, ScrArea *sa) +{ + /* 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); + } + } + } + } + } + } + } + + ARegionType *art = BKE_regiontype_from_id(sa->type, RGN_TYPE_HUD); + if (art == NULL) { + return; + } + + bool init = false; + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HUD); + if (!last_redo_poll(C)) { + if (ar) { + ar->flag |= RGN_FLAG_HIDDEN; + } + return; + } + + if (ar == NULL) { + init = true; + ar = hud_region_add(sa); + ar->type = art; + } + + ED_region_init(ar); + ED_region_tag_redraw(ar); + + /* Let 'ED_area_update_region_sizes' do the work of placing the region. + * Otherwise we could set the 'ar->winrct' & 'ar->winx/winy' here. */ + if (init) { + sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + } + else { + if (ar->flag & RGN_FLAG_HIDDEN) { + sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + } + ar->flag &= ~RGN_FLAG_HIDDEN; + + } + + /* We shouldn't need to do this every time :S */ + /* XXX, this is evil! - it also makes the menu show on first draw. :( */ + hud_region_layout(C, ar); +} + +/** \} */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 4eef386dd04..316b8cbe55f 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -953,6 +953,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar) } if (ar1->overlap && ((ar1->alignment & RGN_SPLIT_PREV) == 0)) { + if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { + continue; + } align1 = ar1->alignment; if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { if (align1 != align) { @@ -994,6 +997,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar) if (ar1->flag & (RGN_FLAG_HIDDEN)) { continue; } + if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { + continue; + } if (ar1->overlap && (ar1->alignment & RGN_SPLIT_PREV) == 0) { if ((ar1->alignment != align) && BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { @@ -1009,6 +1015,9 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar) bool ED_region_is_overlap(int spacetype, int regiontype) { if (U.uiflag2 & USER_REGION_OVERLAP) { + if (regiontype == RGN_TYPE_HUD) { + return 1; + } if (ELEM(spacetype, SPACE_VIEW3D, SPACE_SEQ, SPACE_IMAGE)) { if (ELEM(regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) return 1; @@ -1052,8 +1061,9 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti /* clear state flags first */ ar->flag &= ~RGN_FLAG_TOO_SMALL; /* user errors */ - if (ar->next == NULL && alignment != RGN_ALIGN_QSPLIT) + if ((ar->next == NULL) && !ELEM(alignment, RGN_ALIGN_QSPLIT, RGN_ALIGN_FLOAT)) { alignment = RGN_ALIGN_NONE; + } /* prefsize, taking into account DPI */ prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex); @@ -1076,7 +1086,28 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti /* hidden is user flag */ } else if (alignment == RGN_ALIGN_FLOAT) { - /* XXX floating area region, not handled yet here */ + /** + * \note Currently this window type is only used for #RGN_TYPE_HUD, + * We expect the panel to resize it's self to be larger. + * + * This aligns to the lower left of the area. + */ + rcti overlap_remainder_margin = *overlap_remainder; + BLI_rcti_resize( + &overlap_remainder_margin, + max_ii(0, BLI_rcti_size_x(overlap_remainder) - UI_UNIT_X / 2), + max_ii(0, BLI_rcti_size_y(overlap_remainder) - UI_UNIT_Y / 2)); + ar->winrct.xmin = overlap_remainder_margin.xmin; + ar->winrct.ymin = overlap_remainder_margin.ymin; + ar->winrct.xmax = ar->winrct.xmin + ar->sizex; + ar->winrct.ymax = ar->winrct.ymin + ar->sizey; + + BLI_rcti_isect(&ar->winrct, &overlap_remainder_margin, &ar->winrct); + if (BLI_rcti_size_x(&ar->winrct) < UI_UNIT_X || + BLI_rcti_size_y(&ar->winrct) < UI_UNIT_Y) + { + ar->flag |= RGN_FLAG_TOO_SMALL; + } } else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { /* remainder is too small for any usage */ @@ -1215,7 +1246,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC; /* exception for multiple overlapping regions on same spot */ - if (ar->overlap) { + if (ar->overlap & (alignment != RGN_ALIGN_FLOAT)) { region_overlap_fix(sa, ar); } @@ -1781,7 +1812,10 @@ static ThemeColorID region_background_color_id(const bContext *C, const ARegion static void region_clear_color(const bContext *C, const ARegion *ar, ThemeColorID colorid) { - if (ar->overlap) { + if (ar->alignment == RGN_ALIGN_FLOAT) { + /* handle our own drawing. */ + } + else if (ar->overlap) { /* view should be in pixelspace */ UI_view2d_view_restore(C); @@ -1911,6 +1945,7 @@ void ED_region_panels_layout_ex( const char *category = NULL; const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH; int margin_x = 0; + const bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE; BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *); @@ -2021,7 +2056,25 @@ void ED_region_panels_layout_ex( UI_panels_end(C, ar, &x, &y); /* before setting the view */ - if (vertical) { + if (region_layout_based) { + /* XXX, only single panel support atm. + * Can't use x/y values calculated above because they're not using the real height of panels, + * instead they calculate offsets for the next panel to start drawing. */ + Panel *panel = ar->panels.last; + int size_dyn[2] = { + UI_UNIT_X * 12, + UI_panel_size_y(panel), + }; + /* region size is layout based and needs to be updated */ + if ((ar->sizex != size_dyn[0]) || + (ar->sizey != size_dyn[1])) + { + ar->sizex = size_dyn[0]; + ar->sizey = size_dyn[1]; + sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + } + } + else if (vertical) { /* we always keep the scroll offset - so the total view gets increased with the scrolled away part */ if (v2d->cur.ymax < -FLT_EPSILON) { /* Clamp to lower view boundary */ @@ -2071,7 +2124,9 @@ void ED_region_panels_draw(const bContext *C, ARegion *ar) { View2D *v2d = &ar->v2d; - region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + if (ar->alignment != RGN_ALIGN_FLOAT) { + region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + } /* reset line width for drawing tabs */ glLineWidth(1.0f); @@ -2717,6 +2772,9 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect) rect->ymax = arn->winrct.ymin; } } + else if (arn->alignment == RGN_ALIGN_FLOAT) { + /* Skip floating. */ + } else { BLI_assert(!"Region overlap with unknown alignment"); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a99788dcb23..a73ed09a632 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -1096,7 +1096,6 @@ void ED_spacetype_image(void) art->init = image_main_region_init; art->draw = image_main_region_draw; art->listener = image_main_region_listener; - BLI_addhead(&st->regiontypes, art); /* regions: listview/buttons */ @@ -1134,5 +1133,9 @@ void ED_spacetype_image(void) BLI_addhead(&st->regiontypes, art); + /* regions: hud */ + art = ED_area_type_hud(st->spaceid); + BLI_addhead(&st->regiontypes, art); + BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index d3f24edc38e..964f6f8ea4e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1565,5 +1565,9 @@ void ED_spacetype_view3d(void) art->message_subscribe = view3d_header_region_message_subscribe; BLI_addhead(&st->regiontypes, art); + /* regions: hud */ + art = ED_area_type_hud(st->spaceid); + BLI_addhead(&st->regiontypes, art); + BKE_spacetype_register(st); } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index c7a35490d5b..efb3bf486bf 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -463,7 +463,8 @@ enum { RGN_TYPE_UI = 4, RGN_TYPE_TOOLS = 5, RGN_TYPE_TOOL_PROPS = 6, - RGN_TYPE_PREVIEW = 7 + RGN_TYPE_PREVIEW = 7, + RGN_TYPE_HUD = 8, }; /* use for function args */ #define RGN_TYPE_ANY -1 diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ffef33d344a..ebf771c4745 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -873,6 +873,14 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat, wm_operator_register(C, op); 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); + } + } } else { WM_operator_free(op); |