From 5d109817c90f580aef9a1c2c58f5d065aed892a9 Mon Sep 17 00:00:00 2001 From: cgtinker Date: Mon, 22 May 2023 11:47:42 +0200 Subject: [PATCH 1/3] handle selection --- scripts/startup/bl_ui/space_graph.py | 4 + .../editors/space_graph/graph_intern.h | 8 ++ .../blender/editors/space_graph/graph_ops.c | 2 + .../editors/space_graph/graph_select.c | 131 +++++++++++++++++- 4 files changed, 144 insertions(+), 1 deletion(-) diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 55e5145adda..0be34e1dfe6 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -193,6 +193,10 @@ class GRAPH_MT_select(Menu): props.extend = False props.mode = 'RIGHT' + layout.separator() + # layout.operator("graph.select_handles", text="All").action = 'SELECT' + layout.operator("graph.select_handles") + layout.separator() layout.operator("graph.select_more") layout.operator("graph.select_less") diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 13ddee98051..c502b0ff657 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -74,6 +74,13 @@ enum eGraphKeys_LeftRightSelect_Mode { GRAPHKEYS_LRSEL_RIGHT, }; +/* Defines for handle selection */ +enum eGraphKey_HandleSelect_Mode { + GRAPHKEYS_HANDLESEL_LR = 0, + GRAPHKEYS_HANDLESEL_L, + GRAPHKEYS_HANDLESEL_R, +}; + /* defines for column-select mode */ enum eGraphKeys_ColumnSelect_Mode { GRAPHKEYS_COLUMNSEL_KEYS = 0, @@ -124,6 +131,7 @@ void GRAPH_OT_sound_bake(struct wmOperatorType *ot); void GRAPH_OT_smooth(struct wmOperatorType *ot); void GRAPH_OT_euler_filter(struct wmOperatorType *ot); +void GRAPH_OT_select_handles(struct wmOperatorType *ot); void GRAPH_OT_handle_type(struct wmOperatorType *ot); void GRAPH_OT_interpolation_type(struct wmOperatorType *ot); void GRAPH_OT_extrapolation_type(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index d4a5076cd7a..04382fe51ec 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -443,6 +443,8 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_select_less); WM_operatortype_append(GRAPH_OT_select_leftright); + WM_operatortype_append(GRAPH_OT_select_handles); + /* editing */ WM_operatortype_append(GRAPH_OT_snap); WM_operatortype_append(GRAPH_OT_equalize_handles); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 1793cfbf497..b91c8eb527e 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -214,7 +214,8 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L if (fcurve_handle_sel_check(sipo, bezt1)) { /* first handle only visible if previous segment had handles */ if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || - (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { + (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) + { nearest_fcurve_vert_store(matches, v2d, fcu, @@ -2035,3 +2036,131 @@ void GRAPH_OT_clickselect(wmOperatorType *ot) } /** \} */ +/* Handle selection */ + +/* defines for left-right select tool */ +static const EnumPropertyItem prop_graphkeys_leftright_handle_select_types[] = { + {GRAPHKEYS_HANDLESEL_LR, "CHECK", 0, "Select Both Handles", ""}, + {GRAPHKEYS_HANDLESEL_L, "LEFT", 0, "Select Left Handles", ""}, + {GRAPHKEYS_HANDLESEL_R, "RIGHT", 0, "Select Right Handles", ""}, + {0, NULL, 0, NULL, NULL}, +}; + +short bezt_sel_left_handles(KeyframeEditData *ked, BezTriple *bezt) +{ + if (BEZT_ISSEL_ANY(bezt)) { + BEZT_SEL_IDX(bezt, 0); + BEZT_DESEL_IDX(bezt, 2); + } + return 0; +} + +short bezt_sel_right_handles(KeyframeEditData *ked, BezTriple *bezt) +{ + if (BEZT_ISSEL_ANY(bezt)) { + BEZT_DESEL_IDX(bezt, 0); + BEZT_SEL_IDX(bezt, 2); + } + return 0; +} + +short bezt_sel_both_handles(KeyframeEditData *ked, BezTriple *bezt) +{ + if (BEZT_ISSEL_ANY(bezt)) { + BEZT_SEL_IDX(bezt, 0); + BEZT_SEL_IDX(bezt, 2); + } + return 0; +} + +short bezt_desel_keys(KeyframeEditData *ked, BezTriple *bezt) +{ + if (BEZT_ISSEL_ANY(bezt)) { + BEZT_DESEL_IDX(bezt, 1); + } + return 0; +} + +static void graphkeys_de_select_handles(bAnimContext *ac, short mode, const bool desel_kf) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + KeyframeEditData ked; + + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + FCurve *fcu = (FCurve *)ale->key_data; + + /* Only continue if F-Curve has keyframes. */ + if (fcu->bezt == NULL) { + continue; + } + switch (mode) { + case GRAPHKEYS_HANDLESEL_LR: { + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_both_handles, NULL); + } break; + case GRAPHKEYS_HANDLESEL_R: { + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_right_handles, NULL); + } break; + case GRAPHKEYS_HANDLESEL_L: { + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_left_handles, NULL); + } break; + } + if (desel_kf) { + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_desel_keys, NULL); + } + } + + /* Cleanup */ + ANIM_animdata_freelist(&anim_data); +} + +static int graphkeys_select_handles_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + + /* Get editor data. */ + if (ANIM_animdata_get_context(C, &ac) == 0) { + return OPERATOR_CANCELLED; + } + + short leftright = RNA_enum_get(op->ptr, "mode"); + bool desel_kf = RNA_boolean_get(op->ptr, "desel_kf"); + /* Perform selection changes. */ + graphkeys_de_select_handles(&ac, leftright, desel_kf); + + /* Set notifier that keyframe selection has changed. */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_select_handles(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Select Handles"; + ot->idname = "GRAPH_OT_select_handles"; + ot->description = "(De)Select handles of based on the active selection"; + + /* callbacks */ + ot->poll = graphop_visible_keyframes_poll; + ot->exec = graphkeys_select_handles_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + ot->prop = RNA_def_enum(ot->srna, + "mode", + prop_graphkeys_leftright_handle_select_types, + GRAPHKEYS_LRSEL_TEST, + "Mode", + "(De)Select handles based on selection"); + prop = RNA_def_boolean(ot->srna, "desel_kf", 1, "Deselect Keyframes", ""); +} \ No newline at end of file -- 2.30.2 From fdc17a70dbd9ac364924a4300bd018debd0171d6 Mon Sep 17 00:00:00 2001 From: cgtinker Date: Fri, 16 Jun 2023 11:19:52 +0200 Subject: [PATCH 2/3] improve pr --- scripts/startup/bl_ui/space_graph.py | 5 +- .../editors/space_graph/graph_intern.h | 2 +- .../editors/space_graph/graph_select.c | 59 +++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 0be34e1dfe6..06abe5a5722 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -194,8 +194,9 @@ class GRAPH_MT_select(Menu): props.mode = 'RIGHT' layout.separator() - # layout.operator("graph.select_handles", text="All").action = 'SELECT' - layout.operator("graph.select_handles") + layout.operator("graph.select_handles", text="Select Handles").mode = 'BOTH' + layout.operator("graph.select_handles", text="Select Handles Left").mode = 'LEFT' + layout.operator("graph.select_handles", text="Select Handles Right").mode = 'RIGHT' layout.separator() layout.operator("graph.select_more") diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index c502b0ff657..698a53911ab 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -74,7 +74,7 @@ enum eGraphKeys_LeftRightSelect_Mode { GRAPHKEYS_LRSEL_RIGHT, }; -/* Defines for handle selection */ +/* Defines for handle selection. */ enum eGraphKey_HandleSelect_Mode { GRAPHKEYS_HANDLESEL_LR = 0, GRAPHKEYS_HANDLESEL_L, diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index b91c8eb527e..ded4469fe8f 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -214,8 +214,7 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L if (fcurve_handle_sel_check(sipo, bezt1)) { /* first handle only visible if previous segment had handles */ if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || - (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) - { + (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) { nearest_fcurve_vert_store(matches, v2d, fcu, @@ -2038,15 +2037,15 @@ void GRAPH_OT_clickselect(wmOperatorType *ot) /** \} */ /* Handle selection */ -/* defines for left-right select tool */ +/* Defines for handle select tool. */ static const EnumPropertyItem prop_graphkeys_leftright_handle_select_types[] = { - {GRAPHKEYS_HANDLESEL_LR, "CHECK", 0, "Select Both Handles", ""}, + {GRAPHKEYS_HANDLESEL_LR, "BOTH", 0, "Select Both Handles", ""}, {GRAPHKEYS_HANDLESEL_L, "LEFT", 0, "Select Left Handles", ""}, {GRAPHKEYS_HANDLESEL_R, "RIGHT", 0, "Select Right Handles", ""}, {0, NULL, 0, NULL, NULL}, }; -short bezt_sel_left_handles(KeyframeEditData *ked, BezTriple *bezt) +static short bezt_sel_left_handles(KeyframeEditData *UNUSED(ked), BezTriple *bezt) { if (BEZT_ISSEL_ANY(bezt)) { BEZT_SEL_IDX(bezt, 0); @@ -2055,7 +2054,7 @@ short bezt_sel_left_handles(KeyframeEditData *ked, BezTriple *bezt) return 0; } -short bezt_sel_right_handles(KeyframeEditData *ked, BezTriple *bezt) +static short bezt_sel_right_handles(KeyframeEditData *UNUSED(ked), BezTriple *bezt) { if (BEZT_ISSEL_ANY(bezt)) { BEZT_DESEL_IDX(bezt, 0); @@ -2064,7 +2063,7 @@ short bezt_sel_right_handles(KeyframeEditData *ked, BezTriple *bezt) return 0; } -short bezt_sel_both_handles(KeyframeEditData *ked, BezTriple *bezt) +static short bezt_sel_both_handles(KeyframeEditData *UNUSED(ked), BezTriple *bezt) { if (BEZT_ISSEL_ANY(bezt)) { BEZT_SEL_IDX(bezt, 0); @@ -2073,7 +2072,7 @@ short bezt_sel_both_handles(KeyframeEditData *ked, BezTriple *bezt) return 0; } -short bezt_desel_keys(KeyframeEditData *ked, BezTriple *bezt) +static short bezt_desel_keys(KeyframeEditData *UNUSED(ked), BezTriple *bezt) { if (BEZT_ISSEL_ANY(bezt)) { BEZT_DESEL_IDX(bezt, 1); @@ -2081,19 +2080,18 @@ short bezt_desel_keys(KeyframeEditData *ked, BezTriple *bezt) return 0; } -static void graphkeys_de_select_handles(bAnimContext *ac, short mode, const bool desel_kf) +static void graphkeys_de_select_handles( + bAnimContext *ac, + const short mode, // prop_graphkeys_leftright_handle_select_types + const bool deselect_keyframe) { ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; - int filter; - KeyframeEditData ked; - - filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | - ANIMFILTER_NODUPLIS); + const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | + ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - for (ale = anim_data.first; ale; ale = ale->next) { + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { FCurve *fcu = (FCurve *)ale->key_data; /* Only continue if F-Curve has keyframes. */ @@ -2102,17 +2100,20 @@ static void graphkeys_de_select_handles(bAnimContext *ac, short mode, const bool } switch (mode) { case GRAPHKEYS_HANDLESEL_LR: { - ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_both_handles, NULL); - } break; + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_both_handles, NULL); + break; + } case GRAPHKEYS_HANDLESEL_R: { - ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_right_handles, NULL); - } break; + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_right_handles, NULL); + break; + } case GRAPHKEYS_HANDLESEL_L: { - ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_sel_left_handles, NULL); - } break; + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_left_handles, NULL); + break; + } } - if (desel_kf) { - ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_desel_keys, NULL); + if (deselect_keyframe) { + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_desel_keys, NULL); } } @@ -2130,9 +2131,9 @@ static int graphkeys_select_handles_exec(bContext *C, wmOperator *op) } short leftright = RNA_enum_get(op->ptr, "mode"); - bool desel_kf = RNA_boolean_get(op->ptr, "desel_kf"); + bool deselect_keyframe = RNA_boolean_get(op->ptr, "deselect_keyframe"); /* Perform selection changes. */ - graphkeys_de_select_handles(&ac, leftright, desel_kf); + graphkeys_de_select_handles(&ac, leftright, deselect_keyframe); /* Set notifier that keyframe selection has changed. */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); @@ -2142,8 +2143,6 @@ static int graphkeys_select_handles_exec(bContext *C, wmOperator *op) void GRAPH_OT_select_handles(wmOperatorType *ot) { - PropertyRNA *prop; - /* identifiers */ ot->name = "Select Handles"; ot->idname = "GRAPH_OT_select_handles"; @@ -2159,8 +2158,8 @@ void GRAPH_OT_select_handles(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "mode", prop_graphkeys_leftright_handle_select_types, - GRAPHKEYS_LRSEL_TEST, + GRAPHKEYS_HANDLESEL_LR, "Mode", "(De)Select handles based on selection"); - prop = RNA_def_boolean(ot->srna, "desel_kf", 1, "Deselect Keyframes", ""); + ot->prop = RNA_def_boolean(ot->srna, "deselect_keyframe", 1, "Deselect Keyframes", ""); } \ No newline at end of file -- 2.30.2 From 4870e67ee539f41138c74879fecf4b5a8a340637 Mon Sep 17 00:00:00 2001 From: cgtinker Date: Mon, 26 Jun 2023 12:58:15 +0200 Subject: [PATCH 3/3] improved descriptions and keyframe selection --- scripts/startup/bl_ui/space_graph.py | 1 + .../editors/space_graph/graph_intern.h | 5 +- .../editors/space_graph/graph_select.c | 82 ++++++++++++++----- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 06abe5a5722..101377f7ce0 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -197,6 +197,7 @@ class GRAPH_MT_select(Menu): layout.operator("graph.select_handles", text="Select Handles").mode = 'BOTH' layout.operator("graph.select_handles", text="Select Handles Left").mode = 'LEFT' layout.operator("graph.select_handles", text="Select Handles Right").mode = 'RIGHT' + layout.operator("graph.select_handles", text="Select Keyframes").mode = 'KEY' layout.separator() layout.operator("graph.select_more") diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 698a53911ab..9006866995a 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -75,10 +75,11 @@ enum eGraphKeys_LeftRightSelect_Mode { }; /* Defines for handle selection. */ -enum eGraphKey_HandleSelect_Mode { - GRAPHKEYS_HANDLESEL_LR = 0, +enum eGraphKey_HandleSelect_Side { + GRAPHKEYS_HANDLESEL_BOTH = 0, GRAPHKEYS_HANDLESEL_L, GRAPHKEYS_HANDLESEL_R, + GRAPHKEYS_HANDLESEL_KEY, }; /* defines for column-select mode */ diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index ded4469fe8f..e75e30152ca 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -29,6 +29,9 @@ #include "BKE_fcurve.h" #include "BKE_nla.h" +#include "UI_interface.h" +#include "UI_resources.h" + #include "UI_view2d.h" #include "ED_anim_api.h" @@ -2039,9 +2042,10 @@ void GRAPH_OT_clickselect(wmOperatorType *ot) /* Defines for handle select tool. */ static const EnumPropertyItem prop_graphkeys_leftright_handle_select_types[] = { - {GRAPHKEYS_HANDLESEL_LR, "BOTH", 0, "Select Both Handles", ""}, + {GRAPHKEYS_HANDLESEL_BOTH, "BOTH", 0, "Select Both Handles", ""}, {GRAPHKEYS_HANDLESEL_L, "LEFT", 0, "Select Left Handles", ""}, {GRAPHKEYS_HANDLESEL_R, "RIGHT", 0, "Select Right Handles", ""}, + {GRAPHKEYS_HANDLESEL_KEY, "KEY", 0, "Select Keyframes", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -2072,6 +2076,16 @@ static short bezt_sel_both_handles(KeyframeEditData *UNUSED(ked), BezTriple *bez return 0; } +static short bezt_sel_keys(KeyframeEditData *UNUSED(ked), BezTriple *bezt) +{ + if (BEZT_ISSEL_ANY(bezt)) { + BEZT_DESEL_IDX(bezt, 0); + BEZT_SEL_IDX(bezt, 1); + BEZT_DESEL_IDX(bezt, 2); + } + return 0; +} + static short bezt_desel_keys(KeyframeEditData *UNUSED(ked), BezTriple *bezt) { if (BEZT_ISSEL_ANY(bezt)) { @@ -2080,18 +2094,24 @@ static short bezt_desel_keys(KeyframeEditData *UNUSED(ked), BezTriple *bezt) return 0; } -static void graphkeys_de_select_handles( - bAnimContext *ac, - const short mode, // prop_graphkeys_leftright_handle_select_types - const bool deselect_keyframe) +/* + * Select keyframe handles left/right/both or keys based on the given selection. + * + * mode: Determines which handles to select - left, right, or both. + * deselect_keyframe: Specifies whether keyframes should be deselected (true) or if the current + * selection should be preserved (false). + */ +static void graph_keys_select_handles(bAnimContext *ac, + const enum eGraphKey_HandleSelect_Side mode, + const bool deselect_keyframe) { ListBase anim_data = {NULL, NULL}; const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + BLI_assert(ale->type & ANIMTYPE_FCURVE); FCurve *fcu = (FCurve *)ale->key_data; /* Only continue if F-Curve has keyframes. */ @@ -2099,7 +2119,7 @@ static void graphkeys_de_select_handles( continue; } switch (mode) { - case GRAPHKEYS_HANDLESEL_LR: { + case GRAPHKEYS_HANDLESEL_BOTH: { ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_both_handles, NULL); break; } @@ -2111,8 +2131,11 @@ static void graphkeys_de_select_handles( ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_left_handles, NULL); break; } + case GRAPHKEYS_HANDLESEL_KEY: { + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_sel_keys, NULL); + } } - if (deselect_keyframe) { + if (deselect_keyframe && (mode != GRAPHKEYS_HANDLESEL_KEY)) { ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, bezt_desel_keys, NULL); } } @@ -2130,10 +2153,10 @@ static int graphkeys_select_handles_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - short leftright = RNA_enum_get(op->ptr, "mode"); - bool deselect_keyframe = RNA_boolean_get(op->ptr, "deselect_keyframe"); + const short leftright = RNA_enum_get(op->ptr, "mode"); + const bool deselect_keyframe = RNA_boolean_get(op->ptr, "deselect_keyframe"); /* Perform selection changes. */ - graphkeys_de_select_handles(&ac, leftright, deselect_keyframe); + graph_keys_select_handles(&ac, leftright, deselect_keyframe); /* Set notifier that keyframe selection has changed. */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); @@ -2141,25 +2164,46 @@ static int graphkeys_select_handles_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void graphkeys_select_handles_ui(bContext *UNUSED(C), wmOperator *op) +{ + uiLayout *layout = op->layout; + uiLayout *row; + + bool keyframe_selection = RNA_enum_get(op->ptr, "mode") == GRAPHKEYS_HANDLESEL_KEY; + row = uiLayoutRow(layout, false); + uiItemR(row, op->ptr, "mode", 0, NULL, ICON_NONE); + + if (!keyframe_selection) { + uiItemR(layout, op->ptr, "deselect_keyframe", 0, NULL, ICON_NONE); + } +} + void GRAPH_OT_select_handles(wmOperatorType *ot) { /* identifiers */ ot->name = "Select Handles"; ot->idname = "GRAPH_OT_select_handles"; - ot->description = "(De)Select handles of based on the active selection"; + ot->description = "Select keyframe handles left/right/both or keys based on the given selection"; /* callbacks */ ot->poll = graphop_visible_keyframes_poll; ot->exec = graphkeys_select_handles_exec; + ot->ui = graphkeys_select_handles_ui; /* flags */ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; - ot->prop = RNA_def_enum(ot->srna, - "mode", - prop_graphkeys_leftright_handle_select_types, - GRAPHKEYS_HANDLESEL_LR, - "Mode", - "(De)Select handles based on selection"); - ot->prop = RNA_def_boolean(ot->srna, "deselect_keyframe", 1, "Deselect Keyframes", ""); + RNA_def_enum( + ot->srna, + "mode", + prop_graphkeys_leftright_handle_select_types, + GRAPHKEYS_HANDLESEL_BOTH, + "Mode", + "Selects corresponding keyframe handles (left, right, both or keys) based on the given " + "selection"); + RNA_def_boolean(ot->srna, + "deselect_keyframe", + 1, + "Deselect Keyframes", + "Deselect keyframes or preserve the given keyframe selection"); } \ No newline at end of file -- 2.30.2