forked from bartvdbraak/blender
Graph Editor: Auto View
Auto View automatically adjusts the view based on selection, so that the view is always focused on the current selection. A checkbox in the header is used to access it and it works for the following selection methods: Toggle All, Border, Circle, Lasso, Left, Right, More, Less, Linked, Column (so all except of single selection, in which this can be a bit annoying) Reviewed by @Aligorith (thanks for that :) )
This commit is contained in:
parent
31170ec19e
commit
dffdde4cdc
@ -41,6 +41,8 @@ class GRAPH_HT_header(Header):
|
|||||||
|
|
||||||
dopesheet_filter(layout, context)
|
dopesheet_filter(layout, context)
|
||||||
|
|
||||||
|
layout.prop(st, "use_auto_view", text="Auto View")
|
||||||
|
|
||||||
layout.prop(st, "use_normalization", text="Normalize")
|
layout.prop(st, "use_normalization", text="Normalize")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.active = st.use_normalization
|
row.active = st.use_normalization
|
||||||
|
@ -66,6 +66,14 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* KEYFRAMES STUFF */
|
/* KEYFRAMES STUFF */
|
||||||
|
|
||||||
|
static void graphkeys_auto_view(bContext *C)
|
||||||
|
{
|
||||||
|
const SpaceIpo *sipo = CTX_wm_space_graph(C);
|
||||||
|
|
||||||
|
if (sipo && sipo->flag & SIPO_AUTOVIEW)
|
||||||
|
WM_operator_name_call(C, "GRAPH_OT_view_selected", WM_OP_INVOKE_DEFAULT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* ******************** Deselect All Operator ***************************** */
|
/* ******************** Deselect All Operator ***************************** */
|
||||||
/* This operator works in one of three ways:
|
/* This operator works in one of three ways:
|
||||||
* 1) (de)select all (AKEY) - test if select all or deselect all
|
* 1) (de)select all (AKEY) - test if select all or deselect all
|
||||||
@ -83,7 +91,7 @@
|
|||||||
* 2 = invert
|
* 2 = invert
|
||||||
* - do_channels: whether to affect selection status of channels
|
* - do_channels: whether to affect selection status of channels
|
||||||
*/
|
*/
|
||||||
static void deselect_graph_keys(bAnimContext *ac, short test, short sel, short do_channels)
|
static short deselect_graph_keys(bAnimContext *ac, short test, short sel, short do_channels)
|
||||||
{
|
{
|
||||||
ListBase anim_data = {NULL, NULL};
|
ListBase anim_data = {NULL, NULL};
|
||||||
bAnimListElem *ale;
|
bAnimListElem *ale;
|
||||||
@ -142,6 +150,8 @@ static void deselect_graph_keys(bAnimContext *ac, short test, short sel, short d
|
|||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
ANIM_animdata_freelist(&anim_data);
|
ANIM_animdata_freelist(&anim_data);
|
||||||
|
|
||||||
|
return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------- */
|
/* ------------------- */
|
||||||
@ -150,6 +160,7 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
|
|||||||
{
|
{
|
||||||
bAnimContext ac;
|
bAnimContext ac;
|
||||||
bAnimListElem *ale_active = NULL;
|
bAnimListElem *ale_active = NULL;
|
||||||
|
short sel;
|
||||||
|
|
||||||
/* get editor data */
|
/* get editor data */
|
||||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||||
@ -163,9 +174,9 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
/* 'standard' behavior - check if selected, then apply relevant selection */
|
/* 'standard' behavior - check if selected, then apply relevant selection */
|
||||||
if (RNA_boolean_get(op->ptr, "invert"))
|
if (RNA_boolean_get(op->ptr, "invert"))
|
||||||
deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
|
sel = deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
|
||||||
else
|
else
|
||||||
deselect_graph_keys(&ac, 1, SELECT_ADD, true);
|
sel = deselect_graph_keys(&ac, 1, SELECT_ADD, true);
|
||||||
|
|
||||||
/* restore active F-Curve... */
|
/* restore active F-Curve... */
|
||||||
if (ale_active) {
|
if (ale_active) {
|
||||||
@ -180,6 +191,9 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
|
|||||||
ale_active = NULL;
|
ale_active = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sel != SELECT_SUBTRACT)
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* set notifier that things have changed */
|
/* set notifier that things have changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
|
|
||||||
@ -374,6 +388,8 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
|
|||||||
/* apply borderselect action */
|
/* apply borderselect action */
|
||||||
borderselect_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
|
borderselect_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
|
||||||
|
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* send notifier that keyframe selection has changed */
|
/* send notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
|
|
||||||
@ -461,6 +477,8 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
|
|||||||
MEM_freeN((void *)data_lasso.mcords);
|
MEM_freeN((void *)data_lasso.mcords);
|
||||||
|
|
||||||
|
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* send notifier that keyframe selection has changed */
|
/* send notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
|
|
||||||
@ -491,6 +509,14 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot)
|
|||||||
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
|
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int graph_circle_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type == EVT_MODAL_MAP && event->val == GESTURE_MODAL_NOP)
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
|
return WM_gesture_circle_modal(C, op, event);
|
||||||
|
}
|
||||||
|
|
||||||
static int graph_circle_select_exec(bContext *C, wmOperator *op)
|
static int graph_circle_select_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
bAnimContext ac;
|
bAnimContext ac;
|
||||||
@ -552,7 +578,7 @@ void GRAPH_OT_select_circle(wmOperatorType *ot)
|
|||||||
ot->idname = "GRAPH_OT_select_circle";
|
ot->idname = "GRAPH_OT_select_circle";
|
||||||
|
|
||||||
ot->invoke = WM_gesture_circle_invoke;
|
ot->invoke = WM_gesture_circle_invoke;
|
||||||
ot->modal = WM_gesture_circle_modal;
|
ot->modal = graph_circle_select_modal;
|
||||||
ot->exec = graph_circle_select_exec;
|
ot->exec = graph_circle_select_exec;
|
||||||
ot->poll = graphop_visible_keyframes_poll;
|
ot->poll = graphop_visible_keyframes_poll;
|
||||||
ot->cancel = WM_gesture_circle_cancel;
|
ot->cancel = WM_gesture_circle_cancel;
|
||||||
@ -725,6 +751,8 @@ static int graphkeys_columnselect_exec(bContext *C, wmOperator *op)
|
|||||||
else
|
else
|
||||||
columnselect_graph_keys(&ac, mode);
|
columnselect_graph_keys(&ac, mode);
|
||||||
|
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* set notifier that keyframe selection has changed */
|
/* set notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
|
|
||||||
@ -783,6 +811,8 @@ static int graphkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
ANIM_animdata_freelist(&anim_data);
|
ANIM_animdata_freelist(&anim_data);
|
||||||
|
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* set notifier that keyframe selection has changed */
|
/* set notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
|
|
||||||
@ -807,12 +837,13 @@ void GRAPH_OT_select_linked(wmOperatorType *ot)
|
|||||||
/* ******************** Select More/Less Operators *********************** */
|
/* ******************** Select More/Less Operators *********************** */
|
||||||
|
|
||||||
/* Common code to perform selection */
|
/* Common code to perform selection */
|
||||||
static void select_moreless_graph_keys(bAnimContext *ac, short mode)
|
static void select_moreless_graph_keys(bContext *C, bAnimContext *ac, short mode)
|
||||||
{
|
{
|
||||||
ListBase anim_data = {NULL, NULL};
|
ListBase anim_data = {NULL, NULL};
|
||||||
bAnimListElem *ale;
|
bAnimListElem *ale;
|
||||||
int filter;
|
int filter;
|
||||||
|
|
||||||
|
const SpaceIpo *sipo = (SpaceIpo *)ac->sl;
|
||||||
KeyframeEditData ked;
|
KeyframeEditData ked;
|
||||||
KeyframeEditFunc build_cb;
|
KeyframeEditFunc build_cb;
|
||||||
|
|
||||||
@ -842,6 +873,24 @@ static void select_moreless_graph_keys(bAnimContext *ac, short mode)
|
|||||||
/* free the selmap used here */
|
/* free the selmap used here */
|
||||||
MEM_freeN(ked.data);
|
MEM_freeN(ked.data);
|
||||||
ked.data = NULL;
|
ked.data = NULL;
|
||||||
|
|
||||||
|
/* only do auto view if a bezier point is selected */
|
||||||
|
if (sipo->flag & SIPO_AUTOVIEW) {
|
||||||
|
const FCurve *fcu = (FCurve *)ale->key_data;
|
||||||
|
const BezTriple *bezt;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* only continue if F-Curve has keyframes */
|
||||||
|
if (fcu->bezt == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
|
||||||
|
if (BEZSELECTED(bezt)) {
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
@ -859,7 +908,7 @@ static int graphkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
/* perform select changes */
|
/* perform select changes */
|
||||||
select_moreless_graph_keys(&ac, SELMAP_MORE);
|
select_moreless_graph_keys(C, &ac, SELMAP_MORE);
|
||||||
|
|
||||||
/* set notifier that keyframe selection has changed */
|
/* set notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
@ -893,7 +942,7 @@ static int graphkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
|
|||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
|
|
||||||
/* perform select changes */
|
/* perform select changes */
|
||||||
select_moreless_graph_keys(&ac, SELMAP_LESS);
|
select_moreless_graph_keys(C, &ac, SELMAP_LESS);
|
||||||
|
|
||||||
/* set notifier that keyframe selection has changed */
|
/* set notifier that keyframe selection has changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||||
@ -1008,6 +1057,8 @@ static int graphkeys_select_leftright_exec(bContext *C, wmOperator *op)
|
|||||||
/* do the selecting now */
|
/* do the selecting now */
|
||||||
graphkeys_select_leftright(&ac, leftright, selectmode);
|
graphkeys_select_leftright(&ac, leftright, selectmode);
|
||||||
|
|
||||||
|
graphkeys_auto_view(C);
|
||||||
|
|
||||||
/* set notifier that keyframe selection (and channels too) have changed */
|
/* set notifier that keyframe selection (and channels too) have changed */
|
||||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | ND_ANIMCHAN | NA_SELECTED, NULL);
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | ND_ANIMCHAN | NA_SELECTED, NULL);
|
||||||
|
|
||||||
|
@ -370,6 +370,8 @@ typedef enum eGraphEdit_Flag {
|
|||||||
/* normalize curves on display */
|
/* normalize curves on display */
|
||||||
SIPO_NORMALIZE = (1 << 14),
|
SIPO_NORMALIZE = (1 << 14),
|
||||||
SIPO_NORMALIZE_FREEZE = (1 << 15),
|
SIPO_NORMALIZE_FREEZE = (1 << 15),
|
||||||
|
/* automatically set view on selection */
|
||||||
|
SIPO_AUTOVIEW = (1 << 16),
|
||||||
} eGraphEdit_Flag;
|
} eGraphEdit_Flag;
|
||||||
|
|
||||||
/* SpaceIpo->mode (Graph Editor Mode) */
|
/* SpaceIpo->mode (Graph Editor Mode) */
|
||||||
|
@ -3003,6 +3003,12 @@ static void rna_def_space_graph(BlenderRNA *brna)
|
|||||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
RNA_def_property_ui_text(prop, "Has Ghost Curves", "Graph Editor instance has some ghost curves stored");
|
RNA_def_property_ui_text(prop, "Has Ghost Curves", "Graph Editor instance has some ghost curves stored");
|
||||||
|
|
||||||
|
/* auto view */
|
||||||
|
prop = RNA_def_property(srna, "use_auto_view", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_AUTOVIEW);
|
||||||
|
RNA_def_property_ui_text(prop, "Use Auto View", "Automatically adjust view based on selection");
|
||||||
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
|
||||||
|
|
||||||
/* nromalize curves */
|
/* nromalize curves */
|
||||||
prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
|
prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NORMALIZE);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_NORMALIZE);
|
||||||
|
Loading…
Reference in New Issue
Block a user