UI: Drag and Drop Constraints, Layout Updates

This patch implements the list panel system D7490 for constraints.
In this case the panels are still defined in Python.

The layouts are also updated to use subpanels and the a more organized
single column layout. There may be more tweaks necessary for the
layouts.

Reviewed By: Severin, billreynish, Mets

Differential Revision: https://developer.blender.org/D7499
This commit is contained in:
Hans Goudey 2020-06-19 12:40:48 -04:00
parent 27fb75fec2
commit eaa44afe70
Notes: blender-bot 2023-02-14 05:52:32 +01:00
Referenced by commit 36ae6e66c1, Fix T84367: Fix crash when showing invalid/legacy constraints
Referenced by commit 7a0a60dde8, Dont show temporary IK constraints in the constraint stack
Referenced by issue #84367, Select bone (with constraint) in Pose Mode from Outliner (and constraint tab in Properties Editor showing) crashes
Referenced by issue #80437, Auto IK Double Generates IK constraints
14 changed files with 1687 additions and 856 deletions

File diff suppressed because it is too large Load Diff

View File

@ -136,6 +136,9 @@ typedef struct bConstraintTypeInfo {
const bConstraintTypeInfo *BKE_constraint_typeinfo_get(struct bConstraint *con);
const bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type);
void BKE_constraint_panel_id(int type, char *r_name);
void BKE_constraint_bone_panel_id(int type, char *r_name);
/* ---------------------------------------------------------------------------- */
/* Constraint function prototypes */

View File

@ -5412,9 +5412,16 @@ static bConstraint *add_new_constraint_internal(const char *name, short type)
/* Set up a generic constraint data-block. */
con->type = type;
con->flag |= CONSTRAINT_EXPAND | CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
con->flag |= CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
con->enforce = 1.0f;
/* Only open the main panel when constraints are created, not the subpanels. */
con->ui_expand_flag = (1 << 0);
if (type == CONSTRAINT_TYPE_ACTION || CONSTRAINT_TYPE_SPLINEIK) {
/* Expand the two subpanels in the cases where the main panel barely has any properties. */
con->ui_expand_flag |= (1 << 1) | (1 << 2);
}
/* Determine a basic name, and info */
if (cti) {
/* initialize constraint data */

View File

@ -24,6 +24,7 @@
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
#include "DNA_constraint_types.h"
#include "DNA_genfile.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_modifier_types.h"
@ -287,5 +288,19 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
scene->eevee.motion_blur_max = 32;
}
}
/* Transition to saving expansion for all of a constraint's subpanels. */
if (!DNA_struct_elem_find(fd->filesdna, "bConstraint", "short", "ui_expand_flag")) {
for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
LISTBASE_FOREACH (bConstraint *, con, &object->constraints) {
if (con->flag & CONSTRAINT_EXPAND_DEPRECATED) {
con->ui_expand_flag = 1;
}
else {
con->ui_expand_flag = 0;
}
}
}
}
}
}

View File

@ -1318,7 +1318,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
else {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) {
if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag && (1 << 0))) {
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;

View File

@ -2004,6 +2004,8 @@ void uiTemplatePathBuilder(uiLayout *layout,
struct PointerRNA *root_ptr,
const char *text);
void uiTemplateModifiers(uiLayout *layout, struct bContext *C);
void uiTemplateConstraints(uiLayout *layout, struct bContext *C, bool use_bone_constraints);
uiLayout *uiTemplateGpencilModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
void uiTemplateGpencilColorPreview(uiLayout *layout,
struct bContext *C,
@ -2018,7 +2020,7 @@ uiLayout *uiTemplateShaderFx(uiLayout *layout, struct bContext *C, struct Pointe
void uiTemplateOperatorRedoProperties(uiLayout *layout, const struct bContext *C);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplateConstraintHeader(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout,
struct bContext *C,
struct ID *id,

View File

@ -387,9 +387,19 @@ bool UI_panel_list_matches_data(ARegion *region,
ListBase *data,
uiListPanelIDFromDataFunc panel_idname_func)
{
int data_len = BLI_listbase_count(data);
/* Check for NULL data. */
int data_len = 0;
Link *data_link = NULL;
if (data == NULL) {
data_len = 0;
data_link = NULL;
}
else {
data_len = BLI_listbase_count(data);
data_link = data->first;
}
int i = 0;
Link *data_link = data->first;
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if (panel->type != NULL && panel->type->flag & PNL_INSTANCED) {
/* The panels were reordered by drag and drop. */

View File

@ -1823,6 +1823,20 @@ void uiTemplatePathBuilder(uiLayout *layout,
* Template for building the panel layout for the active object's modifiers.
* \{ */
/**
* Get the active object or the property region's pinned object.
*/
static Object *get_context_object(const bContext *C)
{
SpaceProperties *sbuts = CTX_wm_space_properties(C);
if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
return (Object *)sbuts->pinid;
}
else {
return CTX_data_active_object(C);
}
}
static void modifier_panel_id(void *md_link, char *r_name)
{
ModifierData *md = (ModifierData *)md_link;
@ -1834,14 +1848,7 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
Object *ob;
SpaceProperties *sbuts = CTX_wm_space_properties(C);
if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
ob = (Object *)sbuts->pinid;
}
else {
ob = CTX_data_active_object(C);
}
Object *ob = get_context_object(C);
ListBase *modifiers = &ob->modifiers;
bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
@ -1873,6 +1880,162 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Constraints Template
*
* Template for building the panel layout for the active object or bone's constraints.
* \{ */
/** For building the panel UI for constraints. */
#define CONSTRAINT_TYPE_PANEL_PREFIX "OBJECT_PT_"
#define CONSTRAINT_BONE_TYPE_PANEL_PREFIX "BONE_PT_"
/**
* Check if the panel's ID starts with 'BONE', meaning it is a bone constraint.
*/
static bool constraint_panel_is_bone(Panel *panel)
{
return (panel->panelname[0] == 'B') && (panel->panelname[1] == 'O') &&
(panel->panelname[2] == 'N') && (panel->panelname[3] == 'E');
}
/**
* Get the constraints for the active pose bone or the active / pinned object.
*/
static ListBase *get_constraints(const bContext *C, bool use_bone_constraints)
{
ListBase *constraints = {NULL};
if (use_bone_constraints) {
bPoseChannel *pose_bone = CTX_data_pointer_get(C, "pose_bone").data;
if (pose_bone != NULL) {
constraints = &pose_bone->constraints;
}
}
else {
Object *ob = get_context_object(C);
if (ob != NULL) {
constraints = &ob->constraints;
}
}
return constraints;
}
/**
* Move a constraint to the index it's moved to after a drag and drop.
*/
static void constraint_reorder(bContext *C, Panel *panel, int new_index)
{
bool constraint_from_bone = constraint_panel_is_bone(panel);
ListBase *lb = get_constraints(C, constraint_from_bone);
bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
PointerRNA props_ptr;
wmOperatorType *ot = WM_operatortype_find("CONSTRAINT_OT_move_to_index", false);
WM_operator_properties_create_ptr(&props_ptr, ot);
RNA_string_set(&props_ptr, "constraint", con->name);
RNA_int_set(&props_ptr, "index", new_index);
/* Set owner to #EDIT_CONSTRAINT_OWNER_OBJECT or #EDIT_CONSTRAINT_OWNER_BONE. */
RNA_enum_set(&props_ptr, "owner", constraint_from_bone ? 1 : 0);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
WM_operator_properties_free(&props_ptr);
}
/**
* Get the expand flag from the active constraint to use for the panel.
*/
static short get_constraint_expand_flag(const bContext *C, Panel *panel)
{
bool constraint_from_bone = constraint_panel_is_bone(panel);
ListBase *lb = get_constraints(C, constraint_from_bone);
bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
return con->ui_expand_flag;
}
/**
* Save the expand flag for the panel and subpanels to the constraint.
*/
static void set_constraint_expand_flag(const bContext *C, Panel *panel, short expand_flag)
{
bool constraint_from_bone = constraint_panel_is_bone(panel);
ListBase *lb = get_constraints(C, constraint_from_bone);
bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
con->ui_expand_flag = expand_flag;
}
/**
* Function with void * argument for #uiListPanelIDFromDataFunc.
*
* \note: Constraint panel types are assumed to be named with the struct name field
* concatenated to the defined prefix.
*/
static void object_constraint_panel_id(void *md_link, char *r_name)
{
bConstraint *con = (bConstraint *)md_link;
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
strcpy(r_name, CONSTRAINT_TYPE_PANEL_PREFIX);
strcat(r_name, cti->structName);
}
static void bone_constraint_panel_id(void *md_link, char *r_name)
{
bConstraint *con = (bConstraint *)md_link;
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
strcpy(r_name, CONSTRAINT_BONE_TYPE_PANEL_PREFIX);
strcat(r_name, cti->structName);
}
/**
* Check if the constraint panels don't match the data and rebuild the panels if so.
*/
void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
ListBase *constraints = get_constraints(C, use_bone_constraints);
/* Switch between the bone panel ID function and the object panel ID function. */
uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id :
object_constraint_panel_id;
bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func);
if (!panels_match) {
UI_panels_free_instanced(C, region);
bConstraint *con = (constraints == NULL) ? NULL : constraints->first;
for (int i = 0; con; i++, con = con->next) {
char panel_idname[MAX_NAME];
panel_id_func(con, panel_idname);
Panel *new_panel = UI_panel_add_instanced(sa, region, &region->panels, panel_idname, i);
if (new_panel) {
/* Set the list panel functionality function pointers since we don't do it with python. */
new_panel->type->set_list_data_expand_flag = set_constraint_expand_flag;
new_panel->type->get_list_data_expand_flag = get_constraint_expand_flag;
new_panel->type->reorder = constraint_reorder;
UI_panel_set_expand_from_list_data(C, new_panel);
}
}
}
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
UI_panel_set_expand_from_list_data(C, panel);
}
}
}
#undef CONSTRAINT_TYPE_PANEL_PREFIX
#undef CONSTRAINT_BONE_TYPE_PANEL_PREFIX
/** \} */
/* -------------------------------------------------------------------- */
/** \name Grease Pencil Modifier Template
* \{ */
@ -2441,7 +2604,7 @@ void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Constraint Template
/** \name Constraint Header Template
* \{ */
static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
@ -2449,30 +2612,15 @@ static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
ED_object_constraint_active_set(ob_v, con_v);
}
/* draw panel showing settings for a constraint */
static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
{
bPoseChannel *pchan = BKE_pose_channel_active(ob);
const bConstraintTypeInfo *cti;
uiBlock *block;
uiLayout *result = NULL, *col, *box, *row;
uiLayout *sub;
PointerRNA ptr;
char typestr[32];
short proxy_protected, xco = 0, yco = 0;
// int rb_col; // UNUSED
/* get constraint typeinfo */
cti = BKE_constraint_typeinfo_get(con);
if (cti == NULL) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
BLI_strncpy(typestr,
(con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"),
sizeof(typestr));
}
else {
BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
}
/* determine whether constraint is proxy protected or not */
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
@ -2487,36 +2635,23 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
col = uiLayoutColumn(layout, true);
uiLayoutSetContextPointer(col, "constraint", &ptr);
uiLayoutSetContextPointer(layout, "constraint", &ptr);
box = uiLayoutBox(col);
row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(box);
/* Constraint type icon. */
sub = uiLayoutRow(layout, false);
uiLayoutSetEmboss(sub, false);
uiLayoutSetRedAlert(sub, (con->flag & CONSTRAINT_DISABLE));
uiItemL(sub, "", RNA_struct_ui_icon(ptr.type));
/* Draw constraint header */
/* open/close */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
/* constraint-type icon */
uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
UI_block_emboss_set(block, UI_EMBOSS);
if (con->flag & CONSTRAINT_DISABLE) {
uiLayoutSetRedAlert(row, true);
}
if (proxy_protected == 0) {
uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
uiItemR(layout, &ptr, "name", 0, "", ICON_NONE);
}
else {
uiItemL(row, con->name, ICON_NONE);
uiItemL(layout, con->name, ICON_NONE);
}
uiLayoutSetRedAlert(row, false);
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
if (proxy_protected) {
UI_block_emboss_set(block, UI_EMBOSS_NONE);
@ -2555,54 +2690,20 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
UI_block_emboss_set(block, UI_EMBOSS);
}
else {
short prev_proxylock, show_upbut, show_downbut;
/* Up/Down buttons:
* Proxy-constraints are not allowed to occur after local (non-proxy) constraints
* as that poses problems when restoring them, so disable the "up" button where
* it may cause this situation.
*
* Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
*/
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
if (con->prev) {
prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
}
else {
prev_proxylock = 0;
}
}
else {
prev_proxylock = 0;
}
show_upbut = ((prev_proxylock == 0) && (con->prev));
show_downbut = (con->next) ? 1 : 0;
/* enabled */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemR(row, &ptr, "mute", 0, "", 0);
uiItemR(layout, &ptr, "mute", 0, "", 0);
UI_block_emboss_set(block, UI_EMBOSS);
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
/* up/down */
if (show_upbut || show_downbut) {
UI_block_align_begin(block);
if (show_upbut) {
uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
}
if (show_downbut) {
uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
}
UI_block_align_end(block);
}
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
uiItemO(layout, "", ICON_X, "CONSTRAINT_OT_delete");
UI_block_emboss_set(block, UI_EMBOSS);
/* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
uiItemS(layout);
}
/* Set but-locks for protected settings (magic numbers are used here!) */
@ -2610,23 +2711,11 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
UI_block_lock_set(block, true, TIP_("Cannot edit Proxy-Protected Constraint"));
}
/* Draw constraint data */
if ((con->flag & CONSTRAINT_EXPAND) == 0) {
(yco) -= 10.5f * UI_UNIT_Y;
}
else {
box = uiLayoutBox(col);
block = uiLayoutAbsoluteBlock(box);
result = box;
}
/* clear any locks set up for proxies/lib-linking */
UI_block_lock_clear(block);
return result;
}
uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
void uiTemplateConstraintHeader(uiLayout *layout, PointerRNA *ptr)
{
Object *ob;
bConstraint *con;
@ -2634,7 +2723,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
/* verify we have valid data */
if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
RNA_warning("Expected constraint on object");
return NULL;
return;
}
ob = (Object *)ptr->owner_id;
@ -2642,7 +2731,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
if (!ob || !(GS(ob->id.name) == ID_OB)) {
RNA_warning("Expected constraint on object");
return NULL;
return;
}
UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
@ -2651,11 +2740,11 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
return NULL;
return;
}
}
return draw_constraint(layout, ob, con);
draw_constraint_header(layout, ob, con);
}
/** \} */

View File

@ -1556,6 +1556,77 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot)
/** \} */
/* ------------------------------------------------------------------- */
/** \name Move Constraint To Index Operator
* \{ */
static int constraint_move_to_index_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, 0);
int new_index = RNA_int_get(op->ptr, "index");
if (new_index < 0) {
new_index = 0;
}
if (con) {
ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL);
int current_index = BLI_findindex(conlist, con);
BLI_assert(current_index >= 0);
BLI_listbase_link_move(conlist, con, new_index - current_index);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
static int constraint_move_to_index_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op)) {
return constraint_move_to_index_exec(C, op);
}
else {
return OPERATOR_CANCELLED;
}
}
void CONSTRAINT_OT_move_to_index(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Move Constraint To Index";
ot->idname = "CONSTRAINT_OT_move_to_index";
ot->description =
"Change the constraint's position in the list so it evaluates after the set number of "
"others";
/* callbacks */
ot->exec = constraint_move_to_index_exec;
ot->invoke = constraint_move_to_index_invoke;
ot->poll = edit_constraint_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
edit_constraint_properties(ot);
RNA_def_int(ot->srna,
"index",
0,
0,
INT_MAX,
"Index",
"The index to move the constraint to",
0,
INT_MAX);
}
/** \} */
/* ------------------------------------------------------------------- */
/** \name Clear Pose Constraints Operator
* \{ */

View File

@ -217,6 +217,7 @@ void POSE_OT_ik_clear(struct wmOperatorType *ot);
void CONSTRAINT_OT_delete(struct wmOperatorType *ot);
void CONSTRAINT_OT_move_up(struct wmOperatorType *ot);
void CONSTRAINT_OT_move_to_index(struct wmOperatorType *ot);
void CONSTRAINT_OT_move_down(struct wmOperatorType *ot);
void CONSTRAINT_OT_stretchto_reset(struct wmOperatorType *ot);

View File

@ -179,6 +179,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(CONSTRAINT_OT_delete);
WM_operatortype_append(CONSTRAINT_OT_move_up);
WM_operatortype_append(CONSTRAINT_OT_move_down);
WM_operatortype_append(CONSTRAINT_OT_move_to_index);
WM_operatortype_append(CONSTRAINT_OT_stretchto_reset);
WM_operatortype_append(CONSTRAINT_OT_limitdistance_reset);
WM_operatortype_append(CONSTRAINT_OT_childof_set_inverse);

View File

@ -61,7 +61,8 @@ typedef struct bConstraint {
/** Constraint name, MAX_NAME. */
char name[64];
char _pad[2];
/* Flag for panel and subpanel closed / open state in the UI. */
short ui_expand_flag;
/** Amount of influence exherted by constraint (0.0-1.0). */
float enforce;
@ -689,8 +690,8 @@ typedef enum eBConstraint_Types {
/* flag 0x20 (1 << 5) was used to indicate that a constraint was evaluated
* using a 'local' hack for posebones only. */
typedef enum eBConstraint_Flags {
/* expand for UI */
CONSTRAINT_EXPAND = (1 << 0),
/* Expansion for old box constraint layouts. Just for versioning. */
CONSTRAINT_EXPAND_DEPRECATED = (1 << 0),
/* pre-check for illegal object name or bone name */
CONSTRAINT_DISABLE = (1 << 2),
/* to indicate which Ipo should be shown, maybe for 3d access later too */

View File

@ -2483,7 +2483,7 @@ static void rna_def_constraint_location_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
prop, "For Transform", "Transforms are affected by this constraint as well");
prop, "Affect Transform", "Transforms are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@ -2556,7 +2556,7 @@ static void rna_def_constraint_rotation_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
prop, "For Transform", "Transforms are affected by this constraint as well");
prop, "Affect Transform", "Transforms are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@ -2644,7 +2644,7 @@ static void rna_def_constraint_size_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", LIMIT_TRANSFORM);
RNA_def_property_ui_text(
prop, "For Transform", "Transforms are affected by this constraint as well");
prop, "Affect Transform", "Transforms are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@ -2684,7 +2684,7 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LIMITDIST_TRANSFORM);
RNA_def_property_ui_text(
prop, "For Transform", "Transforms are affected by this constraint as well");
prop, "Affect Transform", "Transforms are affected by this constraint as well");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
RNA_define_lib_overridable(false);
@ -3380,7 +3380,7 @@ void RNA_def_constraint(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_EXPAND);
RNA_def_property_boolean_sdna(prop, NULL, "ui_expand_flag", 0);
RNA_def_property_ui_text(prop, "Expanded", "Constraint's panel is expanded in UI");
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);

View File

@ -1213,6 +1213,15 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Generates the UI layout for the modifier stack");
func = RNA_def_function(srna, "template_constraints", "uiTemplateConstraints");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Generates the panels for the constraint stack");
RNA_def_boolean(func,
"use_bone_constraints",
true,
"",
"Add panels for bone constraints instead of object constraints");
func = RNA_def_function(srna, "template_greasepencil_modifier", "uiTemplateGpencilModifier");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Generates the UI layout for grease pencil modifiers");
@ -1251,12 +1260,10 @@ void RNA_api_ui_layout(StructRNA *srna)
"",
"Optionally limit the items which can be selected");
func = RNA_def_function(srna, "template_constraint", "uiTemplateConstraint");
RNA_def_function_ui_description(func, "Generates the UI layout for constraints");
func = RNA_def_function(srna, "template_constraint_header", "uiTemplateConstraintHeader");
RNA_def_function_ui_description(func, "Generates the header for constraint panels");
parm = RNA_def_pointer(func, "data", "Constraint", "", "Constraint data");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "template_preview", "uiTemplatePreview");
RNA_def_function_ui_description(