UI/Py API: Add active_panel_category to RNA Region struct.

This new member gives access to the current active panel category (i.e.
tab) if supported, and allows to set its value to another defined
category.

While typically add-ons should not force a tab to be the active one,
there are cases where this is a valid and necessary behavior, e.g. in
'Blender App' where an app can add some new tab to the UI and require
them to be active.

Note that there is a ctach here: typically at start time these panel
categories are unknown (enum is empty), since they are validated by
drawing code. So setting them usually needs to be done after initial
startup and drawing of the UI...

Pull Request: https://projects.blender.org/blender/blender/pulls/114070
This commit is contained in:
Bastien Montagne 2023-10-23 19:07:07 +02:00 committed by Gitea
parent ae7719c312
commit f84b0a4dd2
3 changed files with 97 additions and 0 deletions

@ -1989,9 +1989,12 @@ bool UI_panel_can_be_pinned(const Panel *panel);
bool UI_panel_category_is_visible(const ARegion *region);
void UI_panel_category_add(ARegion *region, const char *name);
PanelCategoryDyn *UI_panel_category_find(const ARegion *region, const char *idname);
int UI_panel_category_index_find(ARegion *region, const char *idname);
PanelCategoryStack *UI_panel_category_active_find(ARegion *region, const char *idname);
const char *UI_panel_category_active_get(ARegion *region, bool set_fallback);
void UI_panel_category_active_set(ARegion *region, const char *idname);
/** \param index: index of item _in #ARegion.panels_category list_. */
void UI_panel_category_index_active_set(ARegion *region, const int index);
void UI_panel_category_active_set_default(ARegion *region, const char *idname);
void UI_panel_category_clear_all(ARegion *region);
/**

@ -2128,6 +2128,11 @@ PanelCategoryDyn *UI_panel_category_find(const ARegion *region, const char *idna
BLI_findstring(&region->panels_category, idname, offsetof(PanelCategoryDyn, idname)));
}
int UI_panel_category_index_find(ARegion *region, const char *idname)
{
return BLI_findstringindex(&region->panels_category, idname, offsetof(PanelCategoryDyn, idname));
}
PanelCategoryStack *UI_panel_category_active_find(ARegion *region, const char *idname)
{
return static_cast<PanelCategoryStack *>(BLI_findstring(
@ -2178,6 +2183,17 @@ void UI_panel_category_active_set(ARegion *region, const char *idname)
ui_panel_category_active_set(region, idname, false);
}
void UI_panel_category_index_active_set(ARegion *region, const int index)
{
PanelCategoryDyn *pc_dyn = static_cast<PanelCategoryDyn *>(
BLI_findlink(&region->panels_category, index));
if (!pc_dyn) {
return;
}
ui_panel_category_active_set(region, pc_dyn->idname, false);
}
void UI_panel_category_active_set_default(ARegion *region, const char *idname)
{
if (!UI_panel_category_active_find(region, idname)) {

@ -40,8 +40,15 @@ const EnumPropertyItem rna_enum_region_type_items[] = {
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem rna_enum_region_panel_category_items[] = {
{-1, "UNSUPPORTED", 0, "Not Supported", "This region does not support panel categories"},
{0, nullptr, 0, nullptr, nullptr},
};
#include "ED_screen.hh"
#include "UI_interface_c.hh"
#include "WM_api.hh"
#include "WM_types.hh"
@ -57,6 +64,8 @@ const EnumPropertyItem rna_enum_region_type_items[] = {
# include "UI_view2d.hh"
# include "BLT_translation.h"
# ifdef WITH_PYTHON
# include "BPY_extern.h"
# endif
@ -290,6 +299,61 @@ static PointerRNA rna_Region_data_get(PointerRNA *ptr)
return PointerRNA_NULL;
}
static int rna_region_active_panel_category_editable_get(PointerRNA *ptr, const char **r_info)
{
ARegion *region = static_cast<ARegion *>(ptr->data);
if (BLI_listbase_is_empty(&region->panels_category)) {
if (r_info) {
*r_info = N_("This region does not support panel categories");
}
return 0;
}
return PROP_EDITABLE;
}
static int rna_region_active_panel_category_get(PointerRNA *ptr)
{
ARegion *region = static_cast<ARegion *>(ptr->data);
const char *idname = UI_panel_category_active_get(region, false);
return UI_panel_category_index_find(region, idname);
}
static void rna_region_active_panel_category_set(PointerRNA *ptr, int value)
{
BLI_assert(rna_region_active_panel_category_editable_get(ptr, nullptr));
ARegion *region = static_cast<ARegion *>(ptr->data);
UI_panel_category_index_active_set(region, value);
}
static const EnumPropertyItem *rna_region_active_panel_category_itemf(bContext * /*C*/,
PointerRNA *ptr,
PropertyRNA * /*prop*/,
bool *r_free)
{
ARegion *region = static_cast<ARegion *>(ptr->data);
if (!rna_region_active_panel_category_editable_get(ptr, nullptr)) {
*r_free = false;
return rna_enum_region_panel_category_items;
}
EnumPropertyItem *items = nullptr;
EnumPropertyItem item = {0, "", 0, "", ""};
int totitems = 0;
int category_index;
LISTBASE_FOREACH_INDEX (PanelCategoryDyn *, pc_dyn, &region->panels_category, category_index) {
item.value = category_index;
item.identifier = pc_dyn->idname;
item.name = pc_dyn->idname;
RNA_enum_item_add(&items, &totitems, &item);
}
RNA_enum_item_end(&items, &totitems);
*r_free = true;
return items;
}
static void rna_View2D_region_to_view(View2D *v2d, float x, float y, float result[2])
{
UI_view2d_region_to_view(v2d, x, y, &result[0], &result[1]);
@ -564,6 +628,20 @@ static void rna_def_region(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "AnyType");
RNA_def_property_pointer_funcs(prop, "rna_Region_data_get", nullptr, nullptr, nullptr);
prop = RNA_def_property(srna, "active_panel_category", PROP_ENUM, PROP_NONE);
RNA_def_property_editable_func(prop, "rna_region_active_panel_category_editable_get");
RNA_def_property_enum_items(prop, rna_enum_region_panel_category_items);
RNA_def_property_enum_funcs(prop,
"rna_region_active_panel_category_get",
"rna_region_active_panel_category_set",
"rna_region_active_panel_category_itemf");
RNA_def_property_ui_text(
prop,
"Active Panel Category",
"The current active panel category, may be Null if the region does not "
"support this feature (NOTE: these categories are generated at runtime, so list may be "
"empty at initialization, before any drawing took place)");
RNA_def_function(srna, "tag_redraw", "ED_region_tag_redraw");
}