diff options
-rw-r--r-- | release/datafiles/userdef/userdef_default_theme.c | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_userpref.py | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_userdef.c | 5 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 14 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframing.h | 6 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_anim.c | 4 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 65 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 10 |
10 files changed, 84 insertions, 28 deletions
diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index 6187f486a29..90e8ca256aa 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -228,6 +228,8 @@ const bTheme U_theme_default = { .inner_driven_sel = RGBA(0x9900e6ff), .inner_overridden = RGBA(0x19c3c300), .inner_overridden_sel = RGBA(0x118f8f00), + .inner_changed = RGBA(0xcc7529ff), + .inner_changed_sel = RGBA(0xe6852dff), .blend = 0.5f, }, .widget_emboss = RGBA(0x00000005), diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index ae1fe42b3d7..76bb14b4b73 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -754,6 +754,8 @@ class USERPREF_PT_theme(Panel): colsub.row().prop(ui_state, "inner_key_sel") colsub.row().prop(ui_state, "inner_overridden") colsub.row().prop(ui_state, "inner_overridden_sel") + colsub.row().prop(ui_state, "inner_changed") + colsub.row().prop(ui_state, "inner_changed_sel") col.separator() col.separator() diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 47e3cef2062..8e8f42bdf10 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -97,6 +97,11 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme) copy_v4_v4_char(btheme->tuserpref.navigation_bar, U_theme_default.tuserpref.navigation_bar); } + if (!USER_VERSION_ATLEAST(280, 36)) { + copy_v4_v4_char(btheme->tui.wcol_state.inner_changed, U_theme_default.tui.wcol_state.inner_changed); + copy_v4_v4_char(btheme->tui.wcol_state.inner_changed_sel, U_theme_default.tui.wcol_state.inner_changed_sel); + } + #undef USER_VERSION_ATLEAST } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 3e573d04d38..77dcc17c42a 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2242,6 +2242,20 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter) return false; } +/* Returns whether the current value of a given property differs from the interpolated value. */ +bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float frame) +{ + PathResolvedRNA anim_rna; + anim_rna.ptr = ptr; + anim_rna.prop = prop; + anim_rna.prop_index = fcu->array_index; + + float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame); + float cur_val = setting_get_rna_value(NULL, &ptr, prop, fcu->array_index, false); + + return !compare_ff_relative(fcurve_val, cur_val, FLT_EPSILON, 64); +} + /* Checks whether an Action has a keyframe for a given frame * Since we're only concerned whether a keyframe exists, we can simply loop until a match is found... */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index ed38e9cae58..b42fdf456e0 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -360,6 +360,12 @@ bool autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id); */ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter); +/* Lesser Keyframe Checking API call: + * - Returns whether the current value of a given property differs from the interpolated value. + * - Used for button drawing. + */ +bool fcurve_is_changed(struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float frame); + /* Main Keyframe Checking API call: * Checks whether a keyframe exists for the given ID-block one the given frame. * - It is recommended to call this method over the other keyframe-checkers directly, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 776c9459acc..bb45fbd4615 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -240,6 +240,8 @@ enum { UI_BUT_HAS_SHORTCUT = (1 << 23), /* Button has shortcut text. */ UI_BUT_ICON_REVERSE = (1 << 24), /* Reverse order of consecutive off/on icons */ + + UI_BUT_ANIMATED_CHANGED = (1 << 25), /* Value is animated, but the current value differs from the animated one. */ }; /* scale fixed button widths by this to account for DPI */ diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 4fe555615c2..42615821ee0 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -76,6 +76,7 @@ void ui_but_anim_flag(uiBut *but, float cfra) bool special; but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN); + but->drawflag &= ~UI_BUT_ANIMATED_CHANGED; /* NOTE: "special" is reserved for special F-Curves stored on the animation data * itself (which are used to animate properties of the animation data). @@ -96,6 +97,9 @@ void ui_but_anim_flag(uiBut *but, float cfra) if (fcurve_frame_has_keyframe(fcu, cfra, 0)) but->flag |= UI_BUT_ANIMATED_KEY; + + if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) + but->drawflag |= UI_BUT_ANIMATED_CHANGED; } else { but->flag |= UI_BUT_DRIVEN; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 2d906079e21..b358f87bb26 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -146,7 +146,7 @@ typedef struct uiWidgetType { /* converted colors for state */ uiWidgetColors wcol; - void (*state)(struct uiWidgetType *, int state); + void (*state)(struct uiWidgetType *, int state, int drawflag); void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); @@ -2231,7 +2231,7 @@ static void widget_active_color(char cp[3]) } /* copy colors from theme, and set changes in it based on state */ -static void widget_state(uiWidgetType *wt, int state) +static void widget_state(uiWidgetType *wt, int state, int drawflag) { uiWidgetStateColors *wcol_state = wt->wcol_state; @@ -2249,8 +2249,9 @@ static void widget_state(uiWidgetType *wt, int state) if (state & UI_SELECT) { copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); - - if (state & UI_BUT_ANIMATED_KEY) + if (drawflag & UI_BUT_ANIMATED_CHANGED) + widget_state_blend(wt->wcol.inner, wcol_state->inner_changed_sel, wcol_state->blend); + else if (state & UI_BUT_ANIMATED_KEY) widget_state_blend(wt->wcol.inner, wcol_state->inner_key_sel, wcol_state->blend); else if (state & UI_BUT_ANIMATED) widget_state_blend(wt->wcol.inner, wcol_state->inner_anim_sel, wcol_state->blend); @@ -2265,7 +2266,9 @@ static void widget_state(uiWidgetType *wt, int state) SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); } else { - if (state & UI_BUT_ANIMATED_KEY) + if (drawflag & UI_BUT_ANIMATED_CHANGED) + widget_state_blend(wt->wcol.inner, wcol_state->inner_changed, wcol_state->blend); + else if (state & UI_BUT_ANIMATED_KEY) widget_state_blend(wt->wcol.inner, wcol_state->inner_key, wcol_state->blend); else if (state & UI_BUT_ANIMATED) widget_state_blend(wt->wcol.inner, wcol_state->inner_anim, wcol_state->blend); @@ -2303,19 +2306,21 @@ static void widget_state(uiWidgetType *wt, int state) } /* sliders use special hack which sets 'item' as inner when drawing filling */ -static void widget_state_numslider(uiWidgetType *wt, int state) +static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag) { uiWidgetStateColors *wcol_state = wt->wcol_state; float blend = wcol_state->blend - 0.2f; /* XXX special tweak to make sure that bar will still be visible */ /* call this for option button */ - widget_state(wt, state); + widget_state(wt, state, drawflag); /* now, set the inner-part so that it reflects state settings too */ /* TODO: maybe we should have separate settings for the blending colors used for this case? */ if (state & UI_SELECT) { - if (state & UI_BUT_ANIMATED_KEY) + if (drawflag & UI_BUT_ANIMATED_CHANGED) + widget_state_blend(wt->wcol.item, wcol_state->inner_changed_sel, blend); + else if (state & UI_BUT_ANIMATED_KEY) widget_state_blend(wt->wcol.item, wcol_state->inner_key_sel, blend); else if (state & UI_BUT_ANIMATED) widget_state_blend(wt->wcol.item, wcol_state->inner_anim_sel, blend); @@ -2328,7 +2333,9 @@ static void widget_state_numslider(uiWidgetType *wt, int state) SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); } else { - if (state & UI_BUT_ANIMATED_KEY) + if (drawflag & UI_BUT_ANIMATED_CHANGED) + widget_state_blend(wt->wcol.item, wcol_state->inner_changed, blend); + else if (state & UI_BUT_ANIMATED_KEY) widget_state_blend(wt->wcol.item, wcol_state->inner_key, blend); else if (state & UI_BUT_ANIMATED) widget_state_blend(wt->wcol.item, wcol_state->inner_anim, blend); @@ -2340,12 +2347,12 @@ static void widget_state_numslider(uiWidgetType *wt, int state) } /* labels use theme colors for text */ -static void widget_state_option_menu(uiWidgetType *wt, int state) +static void widget_state_option_menu(uiWidgetType *wt, int state, int drawflag) { bTheme *btheme = UI_GetTheme(); /* XXX */ /* call this for option button */ - widget_state(wt, state); + widget_state(wt, state, drawflag); /* if not selected we get theme from menu back */ if (state & UI_SELECT) @@ -2355,19 +2362,19 @@ static void widget_state_option_menu(uiWidgetType *wt, int state) } -static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state)) +static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag)) { wt->wcol = *(wt->wcol_theme); } /* special case, button that calls pulldown */ -static void widget_state_pulldown(uiWidgetType *wt, int UNUSED(state)) +static void widget_state_pulldown(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag)) { wt->wcol = *(wt->wcol_theme); } /* special case, pie menu items */ -static void widget_state_pie_menu_item(uiWidgetType *wt, int state) +static void widget_state_pie_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag)) { wt->wcol = *(wt->wcol_theme); @@ -2399,7 +2406,7 @@ static void widget_state_pie_menu_item(uiWidgetType *wt, int state) } /* special case, menu items */ -static void widget_state_menu_item(uiWidgetType *wt, int state) +static void widget_state_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag)) { wt->wcol = *(wt->wcol_theme); @@ -3393,7 +3400,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat ui_but_v3_get(but, col); - if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_OVERRIDEN | UI_BUT_REDALERT)) { + if ((state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_OVERRIDEN | UI_BUT_REDALERT)) || + (but->drawflag & UI_BUT_ANIMATED_CHANGED)) { /* draw based on state - color for keyed etc */ widgetbase_draw(&wtb, wcol); @@ -3642,18 +3650,18 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN } /* labels use Editor theme colors for text */ -static void widget_state_label(uiWidgetType *wt, int state) +static void widget_state_label(uiWidgetType *wt, int state, int drawflag) { if (state & UI_BUT_LIST_ITEM) { /* Override default label theme's colors. */ bTheme *btheme = UI_GetTheme(); wt->wcol_theme = &btheme->tui.wcol_list_item; /* call this for option button */ - widget_state(wt, state); + widget_state(wt, state, drawflag); } else { /* call this for option button */ - widget_state(wt, state); + widget_state(wt, state, drawflag); if (state & UI_SELECT) UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); else @@ -4314,13 +4322,14 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct if (wt) { //rcti disablerect = *rect; /* rect gets clipped smaller for text */ - int roundboxalign, state; + int roundboxalign, state, drawflag; bool disabled = false; roundboxalign = widget_roundbox_set(but, rect); /* Mask out flags re-used for local state. */ state = but->flag & ~UI_STATE_FLAGS_ALL; + drawflag = but->drawflag; if (state & UI_SELECT_DRAW) { state |= UI_SELECT; @@ -4352,7 +4361,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct if (disabled) ui_widget_color_disabled(wt); - wt->state(wt, state); + wt->state(wt, state, drawflag); if (wt->custom) wt->custom(but, &wt->wcol, rect, state, roundboxalign); else if (wt->draw) @@ -4366,7 +4375,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct if ((state & UI_ACTIVE) && ui_but_is_popover_once_compat(but)) { uiWidgetType wt_back = *wt; uiWidgetType *wt_temp = widget_type(UI_WTYPE_MENU_ITEM); - wt_temp->state(wt_temp, state); + wt_temp->state(wt_temp, state, drawflag); copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); wt->wcol.inner[3] = 128; wt->wcol.roundness = 0.5f; @@ -4415,7 +4424,7 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) { uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK); - wt->state(wt, 0); + wt->state(wt, 0, 0); if (block) wt->draw(&wt->wcol, rect, block->flag, block->direction); else @@ -4489,7 +4498,7 @@ void ui_draw_popover_back(ARegion *ar, uiStyle *UNUSED(style), uiBlock *block, r ui_draw_popover_back_impl(wt->wcol_theme, rect, block->direction, U.widget_unit / block->aspect, mval_origin); } else { - wt->state(wt, 0); + wt->state(wt, 0, 0); wt->draw(&wt->wcol, rect, 0, 0); } @@ -4641,7 +4650,7 @@ void ui_draw_widget_back_color( } rcti rect_copy = *rect; - wt->state(wt, 0); + wt->state(wt, 0, 0); if (color) { rgba_float_to_uchar((unsigned char *)wt->wcol.inner, color); } @@ -4655,7 +4664,7 @@ void ui_draw_widget_back(uiWidgetTypeEnum type, bool use_shadow, const rcti *rec void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *UNUSED(block), rcti *rect) { uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP); - wt->state(wt, 0); + wt->state(wt, 0, 0); /* wt->draw ends up using same function to draw the tooltip as menu_back */ wt->draw(&wt->wcol, rect, 0, 0); } @@ -4668,7 +4677,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic rcti _rect = *rect; char *cpoin = NULL; - wt->state(wt, state); + wt->state(wt, state, 0); wt->draw(&wt->wcol, rect, 0, 0); UI_fontstyle_set(fstyle); @@ -4748,7 +4757,7 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM); /* drawing button background */ - wt->state(wt, state); + wt->state(wt, state, 0); wt->draw(&wt->wcol, rect, 0, 0); /* draw icon in rect above the space reserved for the label */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 2e3baa27898..a846e8f6468 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -148,6 +148,8 @@ typedef struct uiWidgetStateColors { char inner_driven_sel[4]; char inner_overridden[4]; char inner_overridden_sel[4]; + char inner_changed[4]; + char inner_changed_sel[4]; float blend, pad; } uiWidgetStateColors; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 573946e4ba1..84ce946ce19 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -997,6 +997,16 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Overridden Selected", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "inner_changed", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Changed", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "inner_changed_sel", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Changed Selected", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "blend", PROP_FLOAT, PROP_FACTOR); RNA_def_property_ui_text(prop, "Blend", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); |