diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-09-01 08:23:55 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-09-02 08:58:44 +0300 |
commit | 428a1aaf7372aaad793fe7cc03128db18e3ae602 (patch) | |
tree | 8ff7b138f3d666d9533e63b448519611c673d009 /source/blender/editors/interface/interface_layout.c | |
parent | 89ed6b12936bc2a89b18cf6dbd7b86e0fbc760d3 (diff) |
UI: add back Layout.introspect
Add back this function, removed 2e14b7fb9770b.
Useful for checking operators used in menus.
Diffstat (limited to 'source/blender/editors/interface/interface_layout.c')
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 50355d350ac..e1f3e14eda1 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -31,6 +31,7 @@ #include "DNA_userdef_types.h" #include "BLI_alloca.h" +#include "BLI_dynstr.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -5637,3 +5638,126 @@ void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Layout (Debuging/Introspection) + * + * Serialize the layout as a Python compatible dictionary, + * + * \note Proper string escaping isn't used, + * triple quotes are used to prevent single quotes from interfering with Python syntax. + * If we want this to be fool-proof, we would need full Python compatible string escape support. + * As we don't use triple quotes in the UI it's good-enough in practice. + * \{ */ + +static void ui_layout_introspect_button(DynStr *ds, uiButtonItem *bitem) +{ + uiBut *but = bitem->but; + BLI_dynstr_appendf(ds, "'type':%d, ", (int)but->type); + BLI_dynstr_appendf(ds, "'draw_string':'''%s''', ", but->drawstr); + /* Not exactly needed, rna has this. */ + BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : ""); + + if (but->optype) { + char *opstr = WM_operator_pystring_ex( + but->block->evil_C, NULL, false, true, but->optype, but->opptr); + BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : ""); + MEM_freeN(opstr); + } + + { + PropertyRNA *prop = NULL; + wmOperatorType *ot = UI_but_operatortype_get_from_enum_menu(but, &prop); + if (ot) { + char *opstr = WM_operator_pystring_ex(but->block->evil_C, NULL, false, true, ot, NULL); + BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : ""); + BLI_dynstr_appendf(ds, "'property':'''%s''', ", prop ? RNA_property_identifier(prop) : ""); + MEM_freeN(opstr); + } + } + + if (but->rnaprop) { + BLI_dynstr_appendf(ds, + "'rna':'%s.%s[%d]', ", + RNA_struct_identifier(but->rnapoin.type), + RNA_property_identifier(but->rnaprop), + but->rnaindex); + } +} + +static void ui_layout_introspect_items(DynStr *ds, ListBase *lb) +{ + uiItem *item; + + BLI_dynstr_append(ds, "["); + + for (item = lb->first; item; item = item->next) { + + BLI_dynstr_append(ds, "{"); + +#define CASE_ITEM(id) \ + case id: { \ + const char *id_str = STRINGIFY(id); \ + BLI_dynstr_append(ds, "'type': '"); \ + /* Skip 'ITEM_'. */ \ + BLI_dynstr_append(ds, id_str + 5); \ + BLI_dynstr_append(ds, "', "); \ + break; \ + } \ + ((void)0) + + switch (item->type) { + CASE_ITEM(ITEM_BUTTON); + CASE_ITEM(ITEM_LAYOUT_ROW); + CASE_ITEM(ITEM_LAYOUT_COLUMN); + CASE_ITEM(ITEM_LAYOUT_COLUMN_FLOW); + CASE_ITEM(ITEM_LAYOUT_ROW_FLOW); + CASE_ITEM(ITEM_LAYOUT_BOX); + CASE_ITEM(ITEM_LAYOUT_ABSOLUTE); + CASE_ITEM(ITEM_LAYOUT_SPLIT); + CASE_ITEM(ITEM_LAYOUT_OVERLAP); + CASE_ITEM(ITEM_LAYOUT_ROOT); + CASE_ITEM(ITEM_LAYOUT_GRID_FLOW); + CASE_ITEM(ITEM_LAYOUT_RADIAL); + } + +#undef CASE_ITEM + + switch (item->type) { + case ITEM_BUTTON: + ui_layout_introspect_button(ds, (uiButtonItem *)item); + break; + default: + BLI_dynstr_append(ds, "'items':"); + ui_layout_introspect_items(ds, &((uiLayout *)item)->items); + break; + } + + BLI_dynstr_append(ds, "}"); + + if (item != lb->last) { + BLI_dynstr_append(ds, ", "); + } + } + /* Don't use a comma here as it's not needed and + * causes the result to evaluate to a tuple of 1. */ + BLI_dynstr_append(ds, "]"); +} + +/** + * Evaluate layout items as a Python dictionary. + */ +const char *UI_layout_introspect(uiLayout *layout) +{ + DynStr *ds = BLI_dynstr_new(); + uiLayout layout_copy = *layout; + layout_copy.item.next = NULL; + layout_copy.item.prev = NULL; + ListBase layout_dummy_list = {&layout_copy, &layout_copy}; + ui_layout_introspect_items(ds, &layout_dummy_list); + const char *result = BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return result; +} + +/** \} */ |