diff --git a/source/blender/blenkernel/BKE_screen.hh b/source/blender/blenkernel/BKE_screen.hh index 4fe3a1ba27c..97ccfbabbfd 100644 --- a/source/blender/blenkernel/BKE_screen.hh +++ b/source/blender/blenkernel/BKE_screen.hh @@ -527,6 +527,11 @@ ARegion *BKE_area_region_copy(const SpaceType *st, const ARegion *region); */ void BKE_area_region_free(SpaceType *st, ARegion *region); void BKE_area_region_panels_free(ListBase *panels); +/** + * Create and free panels. + */ +Panel *BKE_panel_new(PanelType *panel_type); +void BKE_panel_free(Panel *panel); /** * Doesn't free the area itself. */ diff --git a/source/blender/blenkernel/intern/screen.cc b/source/blender/blenkernel/intern/screen.cc index bf864d88d1d..1ac65547cc9 100644 --- a/source/blender/blenkernel/intern/screen.cc +++ b/source/blender/blenkernel/intern/screen.cc @@ -36,6 +36,7 @@ #include "BLI_math_vector.h" #include "BLI_mempool.h" #include "BLI_rect.h" +#include "BLI_string.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -486,23 +487,36 @@ void BKE_region_callback_free_gizmomap_set(void (*callback)(wmGizmoMap *)) region_free_gizmomap_callback = callback; } -static void area_region_panels_free_recursive(Panel *panel) +Panel *BKE_panel_new(PanelType *panel_type) +{ + Panel *panel = MEM_cnew(__func__); + panel->runtime = MEM_cnew(__func__); + panel->type = panel_type; + STRNCPY(panel->panelname, panel_type->idname); + return panel; +} + +void BKE_panel_free(Panel *panel) { MEM_SAFE_FREE(panel->activedata); MEM_SAFE_FREE(panel->drawname); + MEM_freeN(panel->runtime); + MEM_freeN(panel); +} +static void area_region_panels_free_recursive(Panel *panel) +{ LISTBASE_FOREACH_MUTABLE (Panel *, child_panel, &panel->children) { area_region_panels_free_recursive(child_panel); } - - MEM_freeN(panel); + BKE_panel_free(panel); } void BKE_area_region_panels_free(ListBase *panels) { LISTBASE_FOREACH_MUTABLE (Panel *, panel, panels) { /* Free custom data just for parent panels to avoid a double free. */ - MEM_SAFE_FREE(panel->runtime.custom_data_ptr); + MEM_SAFE_FREE(panel->runtime->custom_data_ptr); area_region_panels_free_recursive(panel); } BLI_listbase_clear(panels); @@ -1095,11 +1109,11 @@ static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb) BLO_read_list(reader, lb); LISTBASE_FOREACH (Panel *, panel, lb) { + panel->runtime = MEM_cnew(__func__); panel->runtime_flag = 0; panel->activedata = nullptr; panel->type = nullptr; panel->drawname = nullptr; - panel->runtime.custom_data_ptr = nullptr; direct_link_panel_list(reader, &panel->children); } } diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 8746ac28e96..cb0fb486317 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -3179,6 +3179,8 @@ void uiItemPopoverPanel_ptr( if (ok && (pt->draw_header != nullptr)) { layout = uiLayoutRow(layout, true); Panel panel{}; + Panel_Runtime panel_runtime{}; + panel.runtime = &panel_runtime; panel.type = pt; panel.layout = layout; panel.flag = PNL_POPOVER; @@ -5963,8 +5965,7 @@ static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *p static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, bool show_header) { - Panel *panel = MEM_cnew(__func__); - panel->type = pt; + Panel *panel = BKE_panel_new(pt); panel->flag = PNL_POPOVER; if (pt->listener) { @@ -5993,9 +5994,9 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, panel->layout = layout; pt->draw(C, panel); panel->layout = nullptr; - BLI_assert(panel->runtime.custom_data_ptr == nullptr); + BLI_assert(panel->runtime->custom_data_ptr == nullptr); - MEM_freeN(panel); + BKE_panel_free(panel); /* Draw child panels. */ LISTBASE_FOREACH (LinkData *, link, &pt->children) { diff --git a/source/blender/editors/interface/interface_panel.cc b/source/blender/editors/interface/interface_panel.cc index f25093cbc96..334b6e2c8d8 100644 --- a/source/blender/editors/interface/interface_panel.cc +++ b/source/blender/editors/interface/interface_panel.cc @@ -222,11 +222,9 @@ static bool panels_need_realign(const ScrArea *area, ARegion *region, Panel **r_ static Panel *panel_add_instanced(ListBase *panels, PanelType *panel_type, PointerRNA *custom_data) { - Panel *panel = MEM_cnew(__func__); - panel->type = panel_type; - STRNCPY(panel->panelname, panel_type->idname); + Panel *panel = BKE_panel_new(panel_type); - panel->runtime.custom_data_ptr = custom_data; + panel->runtime->custom_data_ptr = custom_data; panel->runtime_flag |= PANEL_NEW_ADDED; /* Add the panel's children too. Although they aren't instanced panels, we can still use this @@ -301,11 +299,7 @@ static void panel_delete(const bContext *C, ARegion *region, ListBase *panels, P BLI_freelistN(&panel->children); BLI_remlink(panels, panel); - if (panel->activedata) { - MEM_freeN(panel->activedata); - } - MEM_SAFE_FREE(panel->drawname); - MEM_freeN(panel); + BKE_panel_free(panel); } void UI_panels_free_instanced(const bContext *C, ARegion *region) @@ -319,8 +313,8 @@ void UI_panels_free_instanced(const bContext *C, ARegion *region) } /* Free panel's custom data. */ - if (panel->runtime.custom_data_ptr != nullptr) { - MEM_freeN(panel->runtime.custom_data_ptr); + if (panel->runtime->custom_data_ptr != nullptr) { + MEM_freeN(panel->runtime->custom_data_ptr); } /* Free the panel and its sub-panels. */ @@ -446,7 +440,7 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr /* Set the bit to tell the interface to instanced the list. */ drag_panel->flag |= PNL_INSTANCED_LIST_ORDER_CHANGED; - CTX_store_set(C, drag_panel->runtime.context); + CTX_store_set(C, drag_panel->runtime->context); /* Finally, move this panel's list item to the new index in its list. */ drag_panel->type->reorder(C, drag_panel, move_to_index); @@ -666,13 +660,10 @@ Panel *UI_panel_begin( { Panel *panel_last; const char *drawname = CTX_IFACE_(pt->translation_context, pt->label); - const char *idname = pt->idname; const bool newpanel = (panel == nullptr); if (newpanel) { - panel = MEM_cnew(__func__); - panel->type = pt; - STRNCPY(panel->panelname, idname); + panel = BKE_panel_new(pt); if (pt->flag & PANEL_TYPE_DEFAULT_CLOSED) { panel->flag |= PNL_CLOSED; @@ -694,7 +685,7 @@ Panel *UI_panel_begin( panel->type = pt; } - panel->runtime.block = block; + panel->runtime->block = block; UI_panel_drawname_set(panel, drawname); @@ -736,14 +727,14 @@ Panel *UI_panel_begin( void UI_panel_header_buttons_begin(Panel *panel) { - uiBlock *block = panel->runtime.block; + uiBlock *block = panel->runtime->block; ui_block_new_button_group(block, UI_BUTTON_GROUP_LOCK | UI_BUTTON_GROUP_PANEL_HEADER); } void UI_panel_header_buttons_end(Panel *panel) { - uiBlock *block = panel->runtime.block; + uiBlock *block = panel->runtime->block; /* A button group should always be created in #UI_panel_header_buttons_begin. */ BLI_assert(!block->button_groups.is_empty()); @@ -801,7 +792,7 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel) } else { const int old_sizex = panel->sizex, old_sizey = panel->sizey; - const int old_region_ofsx = panel->runtime.region_ofsx; + const int old_region_ofsx = panel->runtime->region_ofsx; /* Update width/height if non-zero. */ if (width != 0) { @@ -817,8 +808,8 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel) panel->ofsy += old_sizey - panel->sizey; } - panel->runtime.region_ofsx = panel_region_offset_x_get(region); - if (old_region_ofsx != panel->runtime.region_ofsx) { + panel->runtime->region_ofsx = panel_region_offset_x_get(region); + if (old_region_ofsx != panel->runtime->region_ofsx) { panel->runtime_flag |= PANEL_ANIM_ALIGN; } } @@ -922,7 +913,7 @@ static void region_panels_set_expansion_from_search_filter(const bContext *C, */ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *parent_panel) { - uiBlock *block = panel->runtime.block; + uiBlock *block = panel->runtime->block; BLI_assert(block != nullptr); BLI_assert(block->active); if (parent_panel != nullptr && UI_panel_is_closed(parent_panel)) { @@ -948,7 +939,7 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel * LISTBASE_FOREACH (Panel *, child_panel, &panel->children) { if (child_panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(child_panel->runtime.block != nullptr); + BLI_assert(child_panel->runtime->block != nullptr); panel_remove_invisible_layouts_recursive(child_panel, panel); } } @@ -958,7 +949,7 @@ static void region_panels_remove_invisible_layouts(ARegion *region) { LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(panel->runtime.block != nullptr); + BLI_assert(panel->runtime->block != nullptr); panel_remove_invisible_layouts_recursive(panel, nullptr); } } @@ -1058,7 +1049,7 @@ static void panel_draw_highlight_border(const Panel *panel, } const bTheme *btheme = UI_GetTheme(); - const float aspect = panel->runtime.block->aspect; + const float aspect = panel->runtime->block->aspect; const float radius = (btheme->tui.panel_roundness * U.widget_unit * 0.5f) / aspect; UI_draw_roundbox_corner_set(UI_CNR_ALL); @@ -1177,7 +1168,7 @@ static void panel_draw_aligned_backdrop(const Panel *panel, } const bTheme *btheme = UI_GetTheme(); - const float aspect = panel->runtime.block->aspect; + const float aspect = panel->runtime->block->aspect; const float radius = btheme->tui.panel_roundness * U.widget_unit * 0.5f / aspect; immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -1669,7 +1660,7 @@ static bool uiAlignPanelStep(ARegion *region, const float factor, const bool dra for (int i = 0; i < active_panels_len; i++) { PanelSort *ps = &panel_sort[i]; const bool show_background = UI_panel_should_show_background(region, ps->panel->type); - ps->panel->runtime.region_ofsx = region_offset_x; + ps->panel->runtime->region_ofsx = region_offset_x; ps->new_offset_x = region_offset_x + (show_background ? UI_PANEL_MARGIN_X : 0); } @@ -1828,7 +1819,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(panel->runtime.block != nullptr); + BLI_assert(panel->runtime->block != nullptr); panel_calculate_size_recursive(region, panel); } } @@ -2400,7 +2391,7 @@ int ui_handler_panel_region(bContext *C, static void ui_panel_custom_data_set_recursive(Panel *panel, PointerRNA *custom_data) { - panel->runtime.custom_data_ptr = custom_data; + panel->runtime->custom_data_ptr = custom_data; LISTBASE_FOREACH (Panel *, child_panel, &panel->children) { ui_panel_custom_data_set_recursive(child_panel, custom_data); @@ -2410,7 +2401,7 @@ static void ui_panel_custom_data_set_recursive(Panel *panel, PointerRNA *custom_ void UI_panel_context_pointer_set(Panel *panel, const char *name, PointerRNA *ptr) { uiLayoutSetContextPointer(panel->layout, name, ptr); - panel->runtime.context = uiLayoutGetContextStore(panel->layout); + panel->runtime->context = uiLayoutGetContextStore(panel->layout); } void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data) @@ -2418,8 +2409,8 @@ void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data) BLI_assert(panel->type != nullptr); /* Free the old custom data, which should be shared among all of the panel's sub-panels. */ - if (panel->runtime.custom_data_ptr != nullptr) { - MEM_freeN(panel->runtime.custom_data_ptr); + if (panel->runtime->custom_data_ptr != nullptr) { + MEM_freeN(panel->runtime->custom_data_ptr); } ui_panel_custom_data_set_recursive(panel, custom_data); @@ -2427,7 +2418,7 @@ void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data) PointerRNA *UI_panel_custom_data_get(const Panel *panel) { - return panel->runtime.custom_data_ptr; + return panel->runtime->custom_data_ptr; } PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wmEvent *event) diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 5ce238e4f70..9d300fd3799 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -172,7 +172,7 @@ typedef struct Panel { /** Sub panels. */ ListBase children; - Panel_Runtime runtime; + Panel_Runtime *runtime; } Panel; /**