UI: Add property decorator buttons
When use_property_split is enabled, this template adds buttons to set keyframes, (Alternative to showing color). See: T54951
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_animsys.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
@@ -63,6 +64,10 @@
|
||||
|
||||
#include "interface_intern.h"
|
||||
|
||||
/* Show an icon button after each RNA button to use to quickly set keyframes,
|
||||
* this is a way to display animation/driven/override status, see T54951. */
|
||||
#define UI_PROP_DECORATE
|
||||
|
||||
/************************ Structs and Defines *************************/
|
||||
|
||||
#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
|
||||
@@ -132,6 +137,9 @@ enum {
|
||||
|
||||
UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
|
||||
UI_ITEM_PROP_SEP = 1 << 3,
|
||||
/* Show an icon button next to each property (to set keyframes, show status).
|
||||
* Enabled by default, depends on 'UI_ITEM_PROP_SEP'. */
|
||||
UI_ITEM_PROP_DECORATE = 1 << 4,
|
||||
};
|
||||
|
||||
typedef struct uiButtonItem {
|
||||
@@ -1477,6 +1485,18 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
|
||||
bool is_array;
|
||||
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
|
||||
|
||||
#ifdef UI_PROP_DECORATE
|
||||
struct {
|
||||
bool use_prop_decorate;
|
||||
uiLayout *layout;
|
||||
uiBut *but;
|
||||
} ui_decorate = {
|
||||
.use_prop_decorate = (
|
||||
((layout->item.flag & UI_ITEM_PROP_DECORATE) != 0) &&
|
||||
(use_prop_sep && ptr->id.data && id_can_have_animdata(ptr->id.data))),
|
||||
};
|
||||
#endif /* UI_PROP_DECORATE */
|
||||
|
||||
UI_block_layout_set_current(block, layout);
|
||||
|
||||
/* retrieve info */
|
||||
@@ -1558,14 +1578,24 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
|
||||
|
||||
/* Split the label / property. */
|
||||
if (use_prop_sep) {
|
||||
uiLayout *layout_row = NULL;
|
||||
#ifdef UI_PROP_DECORATE
|
||||
if (ui_decorate.use_prop_decorate) {
|
||||
layout_row = uiLayoutRow(layout, true);
|
||||
layout_row->space = 0;
|
||||
}
|
||||
#endif /* UI_PROP_DECORATE */
|
||||
|
||||
if (name[0] == '\0') {
|
||||
/* Ensure we get a column when text is not set. */
|
||||
layout = uiLayoutColumn(layout, true);
|
||||
layout = uiLayoutColumn(layout_row ? layout_row : layout, true);
|
||||
layout->space = 0;
|
||||
}
|
||||
else {
|
||||
const PropertySubType subtype = RNA_property_subtype(prop);
|
||||
uiLayout *layout_split = uiLayoutSplit(layout, UI_ITEM_PROP_SEP_DIVIDE, true);
|
||||
uiLayout *layout_split = uiLayoutSplit(
|
||||
layout_row ? layout_row : layout,
|
||||
UI_ITEM_PROP_SEP_DIVIDE, true);
|
||||
layout_split->space = 0;
|
||||
uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
|
||||
layout_sub->space = 0;
|
||||
@@ -1607,6 +1637,15 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
|
||||
layout->space = 0;
|
||||
name = "";
|
||||
}
|
||||
|
||||
#ifdef UI_PROP_DECORATE
|
||||
if (ui_decorate.use_prop_decorate) {
|
||||
ui_decorate.layout = uiLayoutColumn(layout_row, true);
|
||||
ui_decorate.layout->space = 0;
|
||||
UI_block_layout_set_current(block, layout);
|
||||
ui_decorate.but = block->buttons.last;
|
||||
}
|
||||
#endif /* UI_PROP_DECORATE */
|
||||
}
|
||||
/* End split. */
|
||||
|
||||
@@ -1655,6 +1694,39 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
|
||||
UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
|
||||
}
|
||||
|
||||
#ifdef UI_PROP_DECORATE
|
||||
if (ui_decorate.use_prop_decorate) {
|
||||
const bool is_anim = RNA_property_animateable(ptr, prop);
|
||||
uiBut *but_decorate = ui_decorate.but ? ui_decorate.but->next : block->buttons.first;
|
||||
uiLayout *layout_col = uiLayoutColumn(ui_decorate.layout, false);
|
||||
layout_col->space = 0;
|
||||
layout_col->emboss = UI_EMBOSS_NONE;
|
||||
int i;
|
||||
for (i = 0; but_decorate; i++) {
|
||||
/* The icons are set in 'ui_but_anim_flag' */
|
||||
if (is_anim) {
|
||||
but = uiDefIconBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_DOT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
|
||||
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Animate property"));
|
||||
UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL);
|
||||
}
|
||||
else {
|
||||
/* We may show other information here in future, for now use empty space. */
|
||||
but = uiDefIconBut(
|
||||
block, UI_BTYPE_BUT, 0, ICON_BLANK1, 0, 0, UI_UNIT_X, UI_UNIT_Y,
|
||||
NULL, 0.0, 0.0, 0.0, 0.0, "");
|
||||
but->flag |= UI_BUT_DISABLED;
|
||||
}
|
||||
/* Order the decorator after the button we decorate, this is used so we can always
|
||||
* do a quick lookup. */
|
||||
BLI_remlink(&block->buttons, but);
|
||||
BLI_insertlinkafter(&block->buttons, but_decorate, but);
|
||||
but_decorate = but->next;
|
||||
}
|
||||
BLI_assert(len ? i < len : i == 1);
|
||||
}
|
||||
#endif /* UI_PROP_DECORATE */
|
||||
|
||||
if (no_bg) {
|
||||
layout->emboss = prev_emboss;
|
||||
}
|
||||
@@ -3435,7 +3507,7 @@ static void ui_litem_init_from_parent(uiLayout *litem, uiLayout *layout, int ali
|
||||
litem->redalert = layout->redalert;
|
||||
litem->w = layout->w;
|
||||
litem->emboss = layout->emboss;
|
||||
litem->item.flag = (layout->item.flag & UI_ITEM_PROP_SEP);
|
||||
litem->item.flag = (layout->item.flag & (UI_ITEM_PROP_SEP | UI_ITEM_PROP_DECORATE));
|
||||
BLI_addtail(&layout->items, litem);
|
||||
}
|
||||
|
||||
@@ -3700,6 +3772,16 @@ void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
|
||||
SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_SEP);
|
||||
}
|
||||
|
||||
bool uiLayoutGetPropDecorate(uiLayout *layout)
|
||||
{
|
||||
return (layout->item.flag & UI_ITEM_PROP_DECORATE) != 0;
|
||||
}
|
||||
|
||||
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
|
||||
{
|
||||
SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_DECORATE);
|
||||
}
|
||||
|
||||
bool uiLayoutGetActive(uiLayout *layout)
|
||||
{
|
||||
return layout->active;
|
||||
@@ -4002,6 +4084,9 @@ uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int s
|
||||
layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
|
||||
layout->item.type = ITEM_LAYOUT_ROOT;
|
||||
|
||||
/* Only used when 'UI_ITEM_PROP_SEP' is set. */
|
||||
layout->item.flag = UI_ITEM_PROP_DECORATE;
|
||||
|
||||
layout->x = x;
|
||||
layout->y = y;
|
||||
layout->root = root;
|
||||
|
Reference in New Issue
Block a user