diff options
Diffstat (limited to 'source/blender/editors/animation/anim_channels_defines.c')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 551 |
1 files changed, 454 insertions, 97 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 7d8e278f0cf..6979850c21a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -36,7 +36,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLF_translation.h" +#include "BLT_translation.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" @@ -61,6 +61,7 @@ #include "RNA_access.h" +#include "BKE_animsys.h" #include "BKE_curve.h" #include "BKE_key.h" #include "BKE_nla.h" @@ -109,7 +110,7 @@ static void acf_generic_root_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUS /* backdrop for top-level widgets (Scene and Object only) */ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0; short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; @@ -120,8 +121,8 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); - uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } @@ -135,7 +136,7 @@ static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac), bAnimListElem /* backdrop for data expanders under top-level Scene/Object */ static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; float color[3]; @@ -159,14 +160,16 @@ static bool acf_show_channel_colors(bAnimContext *ac) { SpaceAction *saction = (SpaceAction *)ac->sl; showGroupColors = !(saction->flag & SACTION_NODRAWGCOLORS); - } + break; + } case SPACE_IPO: { SpaceIpo *sipo = (SpaceIpo *)ac->sl; showGroupColors = !(sipo->flag & SIPO_NODRAWGCOLORS); - } + break; + } } } @@ -176,7 +179,7 @@ static bool acf_show_channel_colors(bAnimContext *ac) /* get backdrop color for generic channels */ static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3]) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); bActionGroup *grp = NULL; short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0; bool showGroupColors = acf_show_channel_colors(ac); @@ -216,7 +219,7 @@ static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, floa /* backdrop for generic channels */ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; float color[3]; @@ -268,7 +271,7 @@ static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListE /* basic offset for channels derived from indention */ static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); if (acf && acf->get_indent_level) return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE; @@ -408,7 +411,7 @@ static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(al /* backdrop for summary widget */ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; float color[3]; @@ -420,8 +423,8 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi * - top and bottom * - special hack: make the top a bit higher, since we are first... */ - uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); - uiDrawBox(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + UI_draw_roundbox_gl_mode(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } /* name for summary entries */ @@ -789,7 +792,7 @@ static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float r_color[ /* backdrop for group widget */ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0; short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; @@ -800,8 +803,8 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc glColor3fv(color); /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ - uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); - uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); + UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8); } /* name for group entries */ @@ -864,7 +867,11 @@ static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings settin case ACHANNEL_SETTING_MUTE: /* muted */ return AGRP_MUTED; - + + case ACHANNEL_SETTING_MOD_OFF: /* muted */ + *neg = 1; + return AGRP_MODIFIERS_OFF; + case ACHANNEL_SETTING_PROTECT: /* protected */ return AGRP_PROTECTED; @@ -945,6 +952,7 @@ static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnim /* unsupported */ case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */ case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */ + case ACHANNEL_SETTING_PINNED: /* This is only for NLA Actions */ return false; /* conditionally available */ @@ -982,6 +990,10 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ return FCURVE_VISIBLE; + case ACHANNEL_SETTING_MOD_OFF: + *neg = 1; + return FCURVE_MOD_OFF; + default: /* unsupported */ return 0; } @@ -1016,6 +1028,149 @@ static bAnimChannelType ACF_FCURVE = acf_fcurve_setting_ptr /* pointer for setting */ }; +/* NLA Control FCurves Expander ----------------------- */ + +/* get backdrop color for nla controls widget */ +static void acf_nla_controls_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3]) +{ + // TODO: give this its own theme setting? + UI_GetThemeColorShade3fv(TH_GROUP, 55, r_color); +} + +/* backdrop for nla controls expander widget */ +static void acf_nla_controls_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +{ + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + View2D *v2d = &ac->ar->v2d; + short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0; + short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; + float color[3]; + + /* set backdrop drawing color */ + acf->get_backdrop_color(ac, ale, color); + glColor3fv(color); + + /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */ + UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5); +} + +/* name for nla controls expander entries */ +static void acf_nla_controls_name(bAnimListElem *UNUSED(ale), char *name) +{ + BLI_strncpy(name, IFACE_("NLA Strip Controls"), ANIM_CHAN_NAME_SIZE); +} + +/* check if some setting exists for this channel */ +static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting) +{ + /* for now, all settings are supported, though some are only conditionally */ + switch (setting) { + /* supported */ + case ACHANNEL_SETTING_EXPAND: + return true; + + // TOOD: selected? + + default: /* unsupported */ + return false; + } +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + *neg = true; + return ADT_NLA_SKEYS_COLLAPSED; + + default: + /* this shouldn't happen */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_nla_controls_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type) +{ + AnimData *adt = (AnimData *)ale->data; + + /* all flags are just in adt->flag for now... */ + return GET_ACF_FLAG_PTR(adt->flag, type); +} + +static int acf_nla_controls_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_NLA; +} + +/* NLA Control FCurves Expander type define */ +static bAnimChannelType ACF_NLACONTROLS = +{ + "NLA Controls Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + acf_nla_controls_color, /* backdrop color */ + acf_nla_controls_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_nla_controls_name, /* name */ + NULL, /* name prop */ + acf_nla_controls_icon, /* icon */ + + acf_nla_controls_setting_valid, /* has setting */ + acf_nla_controls_setting_flag, /* flag for setting */ + acf_nla_controls_setting_ptr /* pointer for setting */ +}; + + +/* NLA Control F-Curve -------------------------------- */ + +/* name for nla control fcurve entries */ +static void acf_nla_curve_name(bAnimListElem *ale, char *name) +{ + NlaStrip *strip = ale->owner; + FCurve *fcu = ale->data; + PropertyRNA *prop; + + /* try to get RNA property that this shortened path (relative to the strip) refers to */ + prop = RNA_struct_type_find_property(&RNA_NlaStrip, fcu->rna_path); + if (prop) { + /* "name" of this strip displays the UI identifier + the name of the NlaStrip */ + BLI_snprintf(name, 256, "%s (%s)", RNA_property_ui_name(prop), strip->name); + } + else { + /* unknown property... */ + BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index); + } +} + + +/* NLA Control F-Curve type define */ +static bAnimChannelType ACF_NLACURVE = +{ + "NLA Control F-Curve", /* type name */ + ACHANNEL_ROLE_CHANNEL, /* role */ + + acf_generic_channel_color, /* backdrop color */ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_nla_curve_name, /* name */ + acf_fcurve_name_prop, /* name prop */ + NULL, /* icon */ + + acf_fcurve_setting_valid, /* has setting */ + acf_fcurve_setting_flag, /* flag for setting */ + acf_fcurve_setting_ptr /* pointer for setting */ +}; + /* Object Action Expander ------------------------------------------- */ // TODO: just get this from RNA? @@ -2365,6 +2520,83 @@ static bAnimChannelType ACF_DSSPK = acf_dsspk_setting_ptr /* pointer for setting */ }; +/* GPencil Expander ------------------------------------------- */ + +// TODO: just get this from RNA? +static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_GREASEPENCIL; +} + +/* get the appropriate flag(s) for the setting when it is valid */ +static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg) +{ + /* clear extra return data first */ + *neg = false; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GP_DATA_EXPAND; + + case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ + return ADT_NLA_EVAL_OFF; + + case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ + *neg = true; + return ADT_CURVES_NOT_VISIBLE; + + case ACHANNEL_SETTING_SELECT: /* selected */ + return ADT_UI_SELECTED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type) +{ + bGPdata *gpd = (bGPdata *)ale->data; + + /* clear extra return data first */ + *type = 0; + + switch (setting) { + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return GET_ACF_FLAG_PTR(gpd->flag, type); + + case ACHANNEL_SETTING_SELECT: /* selected */ + case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */ + case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ + if (gpd->adt) + return GET_ACF_FLAG_PTR(gpd->adt->flag, type); + return NULL; + + default: /* unsupported */ + return NULL; + } +} + +/* grease pencil expander type define */ +static bAnimChannelType ACF_DSGPENCIL = +{ + "GPencil DS Expander", /* type name */ + ACHANNEL_ROLE_EXPANDER, /* role */ + + acf_generic_dataexpand_color, /* backdrop color */ + acf_generic_dataexpand_backdrop, /* backdrop */ + acf_generic_indention_1, /* indent level */ + acf_generic_basic_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idblock_name_prop, /* name prop */ + acf_dsgpencil_icon, /* icon */ + + acf_generic_dataexpand_setting_valid, /* has setting */ + acf_dsgpencil_setting_flag, /* flag for setting */ + acf_dsgpencil_setting_ptr /* pointer for setting */ +}; + /* ShapeKey Entry ------------------------------------------- */ /* name for ShapeKey */ @@ -2985,7 +3217,7 @@ static void acf_nlaaction_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, fl /* backdrop for nla action channel */ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; AnimData *adt = ale->adt; short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; @@ -3010,12 +3242,12 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y /* only on top left corner, to show that this channel sits on top of the preceding ones * while still linking into the action line strip to the right */ - uiSetRoundBox(UI_CNR_TOP_LEFT); + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT); /* draw slightly shifted up vertically to look like it has more separation from other channels, * but we then need to slightly shorten it so that it doesn't look like it overlaps */ - uiDrawBox(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8); + UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8); } /* name for nla action entries */ @@ -3144,6 +3376,9 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */ animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */ + animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */ + animchannelTypeInfo[type++] = &ACF_NLACURVE; /* NLA Control FCurve Channel */ + animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */ animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */ @@ -3162,6 +3397,7 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ + animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */ animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */ @@ -3177,7 +3413,7 @@ static void ANIM_init_channel_typeinfo_data(void) } /* Get type info from given channel type */ -bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale) +const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale) { /* santiy checks */ if (ale == NULL) @@ -3198,7 +3434,7 @@ bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale) /* Print debug info string for the given channel */ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); /* print indents */ for (; indent_level > 0; indent_level--) @@ -3230,7 +3466,7 @@ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level) */ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { @@ -3303,7 +3539,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne */ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { @@ -3348,13 +3584,29 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel #define ICON_WIDTH (0.85f * U.widget_unit) // width of sliders #define SLIDER_WIDTH (4 * U.widget_unit) -// width of rename textboxes -#define RENAME_TEXT_WIDTH (5 * U.widget_unit) +// min-width of rename textboxes +#define RENAME_TEXT_MIN_WIDTH (U.widget_unit) + + +/* Helper - Check if a channel needs renaming */ +static bool achannel_is_being_renamed(const bAnimContext *ac, const bAnimChannelType *acf, size_t channel_index) +{ + if (acf->name_prop && ac->ads) { + /* if rename index matches, this channel is being renamed */ + if (ac->ads->renameIndex == channel_index + 1) { + return true; + } + } + + /* not being renamed */ + return false; +} + /* Draw the given channel */ -void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) +void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; short selected, offset; float y, ymid, ytext; @@ -3407,11 +3659,12 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* step 4) draw special toggles ................................. * - in Graph Editor, checkboxes for visibility in curves area * - in NLA Editor, glowing dots for solo/not solo... + * - in Grease Pencil mode, color swatches for layer color */ if (ac->sl) { if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { /* for F-Curves, draw color-preview of curve behind checkbox */ - if (ale->type == ANIMTYPE_FCURVE) { + if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) { FCurve *fcu = (FCurve *)ale->data; /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever @@ -3431,11 +3684,16 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* just skip - drawn as widget now */ offset += ICON_WIDTH; } + else if (ale->type == ANIMTYPE_GPLAYER) { + /* just skip - drawn as a widget */ + offset += ICON_WIDTH; + } } /* step 5) draw name ............................................... */ - /* TODO: when renaming, we might not want to draw this, especially if name happens to be longer than channel */ - if (acf->name) { + /* Don't draw this if renaming... */ + if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) { + const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */ /* set text color */ @@ -3449,10 +3707,10 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float acf->name(ale, name); offset += 3; - UI_DrawString(offset, ytext, name); + UI_fontstyle_draw_simple(fstyle, offset, ytext, name); /* draw red underline if channel is disabled */ - if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) { + if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) { /* FIXME: replace hardcoded color here, and check on extents! */ glColor3f(1.0f, 0.0f, 0.0f); glLineWidth(2.0); @@ -3519,7 +3777,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float * (only only F-Curves really can support them for now) * - slider should start before the toggles (if they're visible) to keep a clean line down the side */ - if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) { + if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY)) { /* adjust offset */ offset += SLIDER_WIDTH; } @@ -3601,22 +3859,11 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void * WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); } -/* callback for rename widgets - clear rename-in-progress */ -static void achannel_setting_rename_done_cb(bContext *C, void *ads_poin, void *UNUSED(arg2)) -{ - bDopeSheet *ads = (bDopeSheet *)ads_poin; - - /* reset rename index so that edit box disappears now that editing is done */ - ads->renameIndex = 0; - - /* send notifiers */ - WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); -} - /* callback for widget sliders - insert keyframes */ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin) { ID *id = (ID *)id_poin; + AnimData *adt = BKE_animdata_from_id(id); FCurve *fcu = (FCurve *)fcu_poin; ReportList *reports = CTX_wm_reports(C); @@ -3627,9 +3874,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi bool done = false; float cfra; - /* get current frame */ - // NOTE: this will do for now... - cfra = (float)CFRA; + /* get current frame and apply NLA-mapping to it (if applicable) */ + cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); /* get flags for keyframing */ flag = ANIM_get_keyframing_flags(scene, 1); @@ -3666,9 +3912,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi bool done = false; float cfra; - /* get current frame */ - // NOTE: this will do for now... - cfra = (float)CFRA; + /* get current frame and apply NLA-mapping to it (if applicable) */ + cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP); /* get flags for keyframing */ flag = ANIM_get_keyframing_flags(scene, 1); @@ -3699,12 +3944,51 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi MEM_freeN(rna_path); } +/* callback for NLA Control Curve widget sliders - insert keyframes */ +static void achannel_setting_slider_nla_curve_cb(bContext *C, void *UNUSED(id_poin), void *fcu_poin) +{ + /* ID *id = (ID *)id_poin; */ + FCurve *fcu = (FCurve *)fcu_poin; + + PointerRNA ptr; + PropertyRNA *prop; + int index; + + ReportList *reports = CTX_wm_reports(C); + Scene *scene = CTX_data_scene(C); + short flag = 0; + bool done = false; + float cfra; + + /* get current frame - *no* NLA mapping should be done */ + cfra = (float)CFRA; + + /* get flags for keyframing */ + flag = ANIM_get_keyframing_flags(scene, 1); + + /* get pointer and property from the slider - this should all match up with the NlaStrip required... */ + UI_context_active_but_prop_get(C, &ptr, &prop, &index); + + if (fcu && prop) { + /* set the special 'replace' flag if on a keyframe */ + if (fcurve_frame_has_keyframe(fcu, cfra, 0)) + flag |= INSERTKEY_REPLACE; + + /* insert a keyframe for this F-Curve */ + done = insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag); + + if (done) + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + } +} + /* Draw a widget for some setting */ -static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, +static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting) { short ptrsize, butType; bool negflag; + bool usetoggle = true; int flag, icon; void *ptr; const char *tooltip; @@ -3721,12 +4005,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann //icon = ((enabled) ? ICON_VISIBLE_IPO_ON : ICON_VISIBLE_IPO_OFF); icon = ICON_VISIBLE_IPO_OFF; - if (ale->type == ANIMTYPE_FCURVE) + if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) tooltip = TIP_("F-Curve is visible in Graph Editor for editing"); else tooltip = TIP_("Channels are visible in Graph Editor for editing"); break; - + + case ACHANNEL_SETTING_MOD_OFF: /* modifiers disabled */ + icon = ICON_MODIFIER; + usetoggle = false; + tooltip = TIP_("F-Curve modifiers are disabled"); + break; + case ACHANNEL_SETTING_EXPAND: /* expanded triangle */ //icon = ((enabled) ? ICON_TRIA_DOWN : ICON_TRIA_RIGHT); icon = ICON_TRIA_RIGHT; @@ -3756,7 +4046,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann //icon = ((enabled) ? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF); icon = ICON_MUTE_IPO_OFF; - if (ale->type == ANIMTYPE_FCURVE) { + if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) { tooltip = TIP_("Does F-Curve contribute to result"); } else if ((ac) && (ac->spacetype == SPACE_NLA) && (ale->type != ANIMTYPE_NLATRACK)) { @@ -3787,11 +4077,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann } /* type of button */ - if (negflag) - butType = ICONTOGN; - else - butType = ICONTOG; - + if (usetoggle) { + if (negflag) + butType = UI_BTYPE_ICON_TOGGLE_N; + else + butType = UI_BTYPE_ICON_TOGGLE; + } + else { + if (negflag) + butType = UI_BTYPE_TOGGLE_N; + else + butType = UI_BTYPE_TOGGLE; + } /* draw button for setting */ if (ptr && flag) { switch (ptrsize) { @@ -3819,18 +4116,19 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann case ACHANNEL_SETTING_PROTECT: /* General - protection flags */ case ACHANNEL_SETTING_MUTE: /* General - muting flags */ case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */ - uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting)); + case ACHANNEL_SETTING_MOD_OFF: + UI_but_funcN_set(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting)); break; /* settings needing special attention */ case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */ - uiButSetFunc(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data); + UI_but_func_set(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data); break; /* no flushing */ case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */ default: - uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL); + UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL); break; } } @@ -3838,12 +4136,13 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann } /* Draw UI widgets the given channel */ -void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, float yminc, float ymaxc, size_t channel_index) +void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, float yminc, float ymaxc, size_t channel_index) { - bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); + const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale); View2D *v2d = &ac->ar->v2d; float y, ymid /*, ytext*/; short offset; + const bool is_being_renamed = achannel_is_being_renamed(ac, acf, channel_index); /* sanity checks - don't draw anything */ if (ELEM(NULL, acf, ale, block)) @@ -3861,7 +4160,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale ymid = y - 0.5f * ICON_WIDTH; /* no button backdrop behind icons */ - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); /* step 1) draw expand widget ....................................... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) { @@ -3878,6 +4177,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale /* step 3) draw special toggles ................................. * - in Graph Editor, checkboxes for visibility in curves area * - in NLA Editor, glowing dots for solo/not solo... + * - in Grease Pencil mode, color swatches for layer color */ if (ac->sl) { if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { @@ -3890,33 +4190,63 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO); offset += ICON_WIDTH; } + else if (ale->type == ANIMTYPE_GPLAYER) { + /* color swatch for layer color */ + bGPDlayer *gpl = (bGPDlayer *)ale->data; + PointerRNA ptr; + float w = ICON_WIDTH / 2.0f; + + RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr); + + UI_block_align_begin(block); + + UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE); + uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH, + &ptr, "color", -1, + 0, 0, 0, 0, gpl->info); + + UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE); + uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH, + &ptr, "fill_color", -1, + 0, 0, 0, 0, gpl->info); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_align_end(block); + + offset += ICON_WIDTH; + } } /* step 4) draw text - check if renaming widget is in use... */ - if (acf->name_prop && ac->ads) { - float channel_height = ymaxc - yminc; + if (is_being_renamed) { + PointerRNA ptr = {{NULL}}; + PropertyRNA *prop = NULL; - /* if rename index matches, add widget for this */ - if (ac->ads->renameIndex == channel_index + 1) { - PointerRNA ptr = {{NULL}}; - PropertyRNA *prop = NULL; + /* draw renaming widget if we can get RNA pointer for it + * NOTE: property may only be available in some cases, even if we have + * a callback available (e.g. broken F-Curve rename) + */ + if (acf->name_prop(ale, &ptr, &prop)) { + const short margin_x = 3 * iroundf(UI_DPI_FAC); + const short channel_height = iroundf(ymaxc - yminc); + const short width = ac->ar->winx - offset - (margin_x * 2); + uiBut *but; - /* draw renaming widget if we can get RNA pointer for it - * NOTE: property may only be available in some cases, even if we have - * a callback available (e.g. broken F-Curve rename) - */ - if (acf->name_prop(ale, &ptr, &prop)) { - uiBut *but; - - uiBlockSetEmboss(block, UI_EMBOSS); - - but = uiDefButR(block, TEX, 1, "", offset + 3, yminc, RENAME_TEXT_WIDTH, channel_height, - &ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, achannel_setting_rename_done_cb, ac->ads, NULL); - uiButActiveOnly(C, ac->ar, block, but); + UI_block_emboss_set(block, UI_EMBOSS); + + but = uiDefButR(block, UI_BTYPE_TEXT, 1, "", offset + margin_x, yminc, + MAX2(width, RENAME_TEXT_MIN_WIDTH), channel_height, + &ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL); + + /* copy what outliner does here, see outliner_buttons */ + if (UI_but_active_only(C, ac->ar, block, but) == false) { + ac->ads->renameIndex = 0; - uiBlockSetEmboss(block, UI_EMBOSSN); + /* send notifiers */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL); } + + UI_block_emboss_set(block, UI_EMBOSS_NONE); } } @@ -3925,7 +4255,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale offset = 0; // TODO: when drawing sliders, make those draw instead of these toggles if not enough space - if (v2d) { + if (v2d && !is_being_renamed) { short draw_sliders = 0; /* check if we need to show the sliders */ @@ -3959,6 +4289,12 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_MUTE); } + /* modifiers disable */ + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) { + offset += ICON_WIDTH * 1.2f; /* hack: extra spacing, to avoid touching the mute toggle */ + draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_MOD_OFF); + } + /* ----------- */ /* pinned... */ @@ -3972,16 +4308,16 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale uiBut *but; PointerRNA *opptr_b; - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); offset += UI_UNIT_X; - but = uiDefIconButO(block, BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN, + but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN, (int)v2d->cur.xmax - offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL); - opptr_b = uiButGetOperatorPtrRNA(but); + opptr_b = UI_but_operator_ptr_get(but); RNA_int_set(opptr_b, "channel_index", channel_index); - uiBlockSetEmboss(block, UI_EMBOSSN); + UI_block_emboss_set(block, UI_EMBOSS_NONE); } } @@ -3993,15 +4329,36 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale * and wouldn't be able to auto-keyframe... * - slider should start before the toggles (if they're visible) to keep a clean line down the side */ - if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) { + if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY)) { /* adjust offset */ // TODO: make slider width dynamic, so that they can be easier to use when the view is wide enough offset += SLIDER_WIDTH; /* need backdrop behind sliders... */ - uiBlockSetEmboss(block, UI_EMBOSS); + UI_block_emboss_set(block, UI_EMBOSS); - if (ale->id) { /* Slider using RNA Access -------------------- */ + if (ale->owner) { /* Slider using custom RNA Access ---------- */ + if (ale->type == ANIMTYPE_NLACURVE) { + NlaStrip *strip = (NlaStrip *)ale->owner; + FCurve *fcu = (FCurve *)ale->data; + PointerRNA ptr; + PropertyRNA *prop; + + /* create RNA pointers */ + RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, &ptr); + prop = RNA_struct_find_property(&ptr, fcu->rna_path); + + /* create property slider */ + if (prop) { + uiBut *but; + + /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */ + but = uiDefAutoButR(block, &ptr, prop, fcu->array_index, "", ICON_NONE, (int)v2d->cur.xmax - offset, ymid, SLIDER_WIDTH, (int)ymaxc - yminc); + UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data); + } + } + } + else if (ale->id) { /* Slider using RNA Access --------------- */ PointerRNA id_ptr, ptr; PropertyRNA *prop; char *rna_path = NULL; @@ -4037,9 +4394,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale /* assign keyframing function according to slider type */ if (ale->type == ANIMTYPE_SHAPEKEY) - uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data); + UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data); else - uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data); + UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data); } /* free the path if necessary */ |