diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-10-20 16:04:56 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-10-20 16:04:56 +0400 |
commit | 00f3d83b6ab5f4f9ee4f69457e492db72a03cf30 (patch) | |
tree | dd57f5d8b0bb859a0403225a11d118844a728c68 | |
parent | ec6bccfad1609fa09a703d7496310da246fd5825 (diff) |
Graph Editor: Added 2D Cursor
I've finally given in, and implemented a '2d-cursor' for the Graph Editor. This is simply represented as an additional horizontal line that meets with the current frame indicator, forming a cross-hair. It can be disabled from the View menu.
Currently, the only tool which takes this into account is the Snapping tools (Shift-S), where I've hooked up a tool I added some time ago.
TODO:
- expose this cursor to the transform tools for scaling/rotation options...
-rw-r--r-- | source/blender/editors/animation/anim_draw.c | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 26 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 63 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 7 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_header.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_ops.c | 136 | ||||
-rw-r--r-- | source/blender/editors/space_graph/space_graph.c | 21 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 11 |
10 files changed, 202 insertions, 75 deletions
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 2dc4aa09407..aa581a7d15a 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -156,7 +156,7 @@ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) glScalef(xscale, 1.0, 1.0); } -/* General call for drawing current frame indicator in a */ +/* General call for drawing current frame indicator in animation editor */ void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag) { Scene *scene= CTX_data_scene(C); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 35eac6d23f1..33eed1ff2a4 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -62,6 +62,18 @@ /* ********************** frame change operator ***************************/ +/* Check if the operator can be run from the current context */ +static int change_frame_poll(bContext *C) +{ + ScrArea *curarea= CTX_wm_area(C); + + /* as long as there is an active area, and it isn't a Graph Editor + * (since the Graph Editor has its own version which does extra stuff), + * we're fine + */ + return ((curarea) && (curarea->spacetype != SPACE_IPO)); +} + /* Set any flags that are necessary to indicate modal time-changing operation */ static int change_frame_init(bContext *C, wmOperator *op) { @@ -85,18 +97,12 @@ static int change_frame_init(bContext *C, wmOperator *op) static void change_frame_apply(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - int cfra; - - /* get frame, and clamp to MINAFRAME - * - not MINFRAME, since it's useful to be able to key a few-frames back - */ - cfra= RNA_int_get(op->ptr, "frame"); - if (cfra < MINAFRAME) cfra= MINAFRAME; - CFRA= cfra; + /* set the new frame number */ + CFRA= RNA_int_get(op->ptr, "frame"); + /* do updates */ sound_scrub(C); - WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); } @@ -210,12 +216,14 @@ void ANIM_OT_change_frame(wmOperatorType *ot) /* identifiers */ ot->name= "Change frame"; ot->idname= "ANIM_OT_change_frame"; + ot->description= "Interactively change the current frame number."; /* api callbacks */ ot->exec= change_frame_exec; ot->invoke= change_frame_invoke; ot->cancel= change_frame_cancel; ot->modal= change_frame_modal; + ot->poll= change_frame_poll; /* flags */ ot->flag= OPTYPE_BLOCKING; diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index b92b69c4e8e..f379ff6c395 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5037,11 +5037,11 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) /* Set the flags */ CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) { - /* select pchan, only if selectable */ - if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { - if (sel==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); - else pchan->bone->flag |= BONE_SELECTED; - } + /* select pchan only if selectable, but deselect works always */ + if (sel==0) + pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); + else if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) + pchan->bone->flag |= BONE_SELECTED; } CTX_DATA_END; @@ -5313,21 +5313,7 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) /* we have the object using the armature */ if (arm==ob->data) { Object *cob; - //bAction *act; - //bActionChannel *achan; - //bActionStrip *strip; - /* Rename action channel if necessary */ -#if 0 // XXX old animation system - act = ob->action; - if (act && !act->id.lib) { - /* Find the appropriate channel */ - achan= get_action_channel(act, oldname); - if (achan) - BLI_strncpy(achan->name, newname, MAXBONENAME); - } -#endif // XXX old animation system - /* Rename the pose channel, if it exists */ if (ob->pose) { bPoseChannel *pchan = get_pose_channel(ob->pose, oldname); @@ -5335,20 +5321,6 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) BLI_strncpy(pchan->name, newname, MAXBONENAME); } - /* check all nla-strips too */ -#if 0 // XXX old animation system - for (strip= ob->nlastrips.first; strip; strip= strip->next) { - /* Rename action channel if necessary */ - act = strip->act; - if (act && !act->id.lib) { - /* Find the appropriate channel */ - achan= get_action_channel(act, oldname); - if (achan) - BLI_strncpy(achan->name, newname, MAXBONENAME); - } - } -#endif // XXX old animation system - /* Update any object constraints to use the new bone name */ for (cob= G.main->object.first; cob; cob= cob->id.next) { if (cob->constraints.first) @@ -5381,35 +5353,12 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) } /* Fix animation data attached to this object */ + // TODO: should we be using the database wide version instead (since drivers may break) if (ob->adt) { /* posechannels only... */ BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.pose_channels", oldname, newname); } } - - /* do entire db - ipo's for the drivers */ -#if 0 // XXX old animation system - for (ipo= G.main->ipo.first; ipo; ipo= ipo->id.next) { - IpoCurve *icu; - - /* check each curve's driver */ - for (icu= ipo->curve.first; icu; icu= icu->next) { - IpoDriver *icd= icu->driver; - - if ((icd) && (icd->ob)) { - ob= icd->ob; - - if (icu->driver->type == IPO_DRIVER_TYPE_NORMAL) { - if (!strcmp(oldname, icd->name)) - BLI_strncpy(icd->name, newname, MAXBONENAME); - } - else { - /* TODO: pydrivers need to be treated differently */ - } - } - } - } -#endif // XXX old animation system } } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 22272479e4a..bcd57aa233f 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1450,7 +1450,8 @@ void GRAPH_OT_frame_jump (wmOperatorType *ot) /* defines for snap keyframes tool */ EnumPropertyItem prop_graphkeys_snap_types[] = { - {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""}, + {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", ""}, + {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", ""}, {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, @@ -1481,6 +1482,10 @@ static void snap_graph_keys(bAnimContext *ac, short mode) bed.list.first= (ac->markers) ? ac->markers->first : NULL; bed.list.last= (ac->markers) ? ac->markers->last : NULL; } + else if (mode == GRAPHKEYS_SNAP_VALUE) { + SpaceIpo *sipo= (SpaceIpo *)ac->sa->spacedata.first; + bed.f1= (sipo) ? sipo->cursorVal : 0.0f; + } /* snap keyframes */ for (ale= anim_data.first; ale; ale= ale->next) { diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c index 8d8c8702987..a52ab8beaca 100644 --- a/source/blender/editors/space_graph/graph_header.c +++ b/source/blender/editors/space_graph/graph_header.c @@ -81,6 +81,7 @@ static void graph_viewmenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); uiItemR(layout, NULL, 0, &spaceptr, "show_cframe_indicator", 0); + uiItemR(layout, NULL, 0, &spaceptr, "show_cursor", 0); uiItemR(layout, NULL, 0, &spaceptr, "show_sliders", 0); uiItemR(layout, NULL, 0, &spaceptr, "automerge_keyframes", 0); @@ -162,6 +163,7 @@ static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused) { uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_CFRA); + uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_VALUE); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_FRAME); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_SECOND); uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_MARKER); diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 9b7c2eb3656..f03c9ece262 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -119,6 +119,7 @@ enum { GRAPHKEYS_SNAP_NEAREST_SECOND, GRAPHKEYS_SNAP_NEAREST_MARKER, GRAPHKEYS_SNAP_HORIZONTAL, + GRAPHKEYS_SNAP_VALUE, } eGraphKeys_Snap_Mode; /* defines for mirror keyframes diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index ab35bda0e2f..1780942a123 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -41,6 +41,7 @@ #include "BLI_blenlib.h" #include "BKE_context.h" +#include "BKE_sound.h" #include "BKE_utildefines.h" #include "UI_interface.h" @@ -57,12 +58,133 @@ #include "WM_api.h" #include "WM_types.h" -/* ************************** poll callbacks **********************************/ +/* ************************** view-based operators **********************************/ +// XXX should these really be here? +/* Set Cursor --------------------------------------------------------------------- */ +/* The 'cursor' in the Graph Editor consists of two parts: + * 1) Current Frame Indicator (as per ANIM_OT_change_frame) + * 2) Value Indicator (stored per Graph Editor instance) + */ +/* Set the new frame number */ +static void graphview_cursor_apply(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceIpo *sipo= CTX_wm_space_graph(C); + + /* adjust the frame + * NOTE: sync this part of the code with ANIM_OT_change_frame + */ + CFRA= RNA_int_get(op->ptr, "frame"); + sound_scrub(C); + + /* set the cursor value */ + sipo->cursorVal= RNA_float_get(op->ptr, "value"); + + /* send notifiers - notifiers for frame should force an update for both vars ok... */ + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); +} -/* ************************** view-based operators **********************************/ -// XXX this probably shouldn't be here.. +/* ... */ + +/* Non-modal callback for running operator without user input */ +static int graphview_cursor_exec(bContext *C, wmOperator *op) +{ + graphview_cursor_apply(C, op); + return OPERATOR_FINISHED; +} + +/* ... */ + +/* set the operator properties from the initial event */ +static void graphview_cursor_setprops(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + float viewx, viewy; + int x, y; + + /* abort if not active region (should not really be possible) */ + if (ar == NULL) + return; + + /* convert screen coordinates to region coordinates */ + x= event->x - ar->winrct.xmin; + y= event->y - ar->winrct.ymin; + + /* convert from region coordinates to View2D 'tot' space */ + UI_view2d_region_to_view(&ar->v2d, x, y, &viewx, &viewy); + + /* store the values in the operator properties */ + /* frame is rounded to the nearest int, since frames are ints */ + RNA_int_set(op->ptr, "frame", (int)floor(viewx+0.5f)); + RNA_float_set(op->ptr, "value", viewy); +} + +/* Modal Operator init */ +static int graphview_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + /* Change to frame that mouse is over before adding modal handler, + * as user could click on a single frame (jump to frame) as well as + * click-dragging over a range (modal scrubbing). + */ + graphview_cursor_setprops(C, op, event); + + /* apply these changes first */ + graphview_cursor_apply(C, op); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; +} + +/* Modal event handling of cursor changing */ +static int graphview_cursor_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + /* execute the events */ + switch (event->type) { + case ESCKEY: + return OPERATOR_FINISHED; + + case MOUSEMOVE: + /* set the new values */ + graphview_cursor_setprops(C, op, event); + graphview_cursor_apply(C, op); + break; + + case LEFTMOUSE: + case RIGHTMOUSE: + /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init + * the modal op) doesn't work for some reason + */ + if (event->val==KM_RELEASE) + return OPERATOR_FINISHED; + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void GRAPH_OT_cursor_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Cursor"; + ot->idname= "GRAPH_OT_cursor_set"; + ot->description= "Interactively set the current frame number and value cursor"; + + /* api callbacks */ + ot->exec= graphview_cursor_exec; + ot->invoke= graphview_cursor_invoke; + ot->modal= graphview_cursor_modal; + ot->poll= ED_operator_ipo_active; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; + + /* rna */ + RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); + RNA_def_float(ot->srna, "value", 0, FLT_MIN, FLT_MAX, "Value", "", -100.0f, 100.0f); +} /* Toggle Handles ----------------------------------------------------------------- */ @@ -100,6 +222,8 @@ void graphedit_operatortypes(void) { /* view */ WM_operatortype_append(GRAPH_OT_view_togglehandles); + WM_operatortype_append(GRAPH_OT_cursor_set); + WM_operatortype_append(GRAPH_OT_previewrange_set); WM_operatortype_append(GRAPH_OT_view_all); WM_operatortype_append(GRAPH_OT_properties); @@ -147,6 +271,11 @@ static void graphedit_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) /* view */ WM_keymap_add_item(keymap, "GRAPH_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0); + /* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons + * This keymap is supposed to override ANIM_OT_change_frame, which does the same except it doesn't do y-values + */ + WM_keymap_add_item(keymap, "GRAPH_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0); + /* graph_select.c - selection tools */ /* click-select */ @@ -175,7 +304,6 @@ static void graphedit_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1); /* column select */ - // XXX KKEY would be nice to keep for 'keyframe' lines RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS); RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA); RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 1f65a8cd7ea..b4b06844d13 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -261,6 +261,27 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) /* only free grid after drawing data, as we need to use it to determine sampling rate */ UI_view2d_grid_free(grid); + /* horizontal component of value-cursor (value line before the current frame line) */ + if ((sipo->flag & SIPO_NODRAWCURSOR)==0) { + float vec[2]; + + /* Draw a green line to indicate the cursor value */ + vec[1]= sipo->cursorVal; + + UI_ThemeColorShadeAlpha(TH_CFRAME, -10, -50); + glLineWidth(2.0); + + glEnable(GL_BLEND); + glBegin(GL_LINE_STRIP); + vec[0]= v2d->cur.xmin; + glVertex2fv(vec); + + vec[0]= v2d->cur.xmax; + glVertex2fv(vec); + glEnd(); // GL_LINE_STRIP + glDisable(GL_BLEND); + } + /* current frame */ if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS; if ((sipo->flag & SIPO_NODRAWCFRANUM)==0) flag |= DRAWCFRA_SHOW_NUMBOX; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d7793b88bea..8de701d9109 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -86,7 +86,6 @@ typedef struct SpaceInfo { } SpaceInfo; /* 'Graph' Editor (formerly known as the IPO Editor) */ -/* XXX for now, we keep all old data... */ typedef struct SpaceIpo { SpaceLink *next, *prev; ListBase regionbase; /* storage of regions for inactive spaces */ @@ -101,9 +100,11 @@ typedef struct SpaceIpo { ListBase ghostCurves; /* sampled snapshots of F-Curves used as in-session guides */ short mode; /* mode for the Graph editor (eGraphEdit_Mode) */ - short flag; /* settings for Graph editor */ short autosnap; /* time-transform autosnapping settings for Graph editor (eAnimEdit_AutoSnap in DNA_action_types.h) */ - char pin, lock; // XXX old, unused vars that are probably going to be depreceated soon... + int flag; /* settings for Graph editor */ + + float cursorVal; /* cursor value (y-value, x-value is current frame) */ + int pad; } SpaceIpo; typedef struct SpaceButs { @@ -723,6 +724,7 @@ enum FileSortTypeE { #define SIPO_SELCUVERTSONLY (1<<5) #define SIPO_DRAWNAMES (1<<6) #define SIPO_SLIDERS (1<<7) +#define SIPO_NODRAWCURSOR (1<<8) /* SpaceIpo->mode (Graph Editor Mode) */ enum { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 72856e54bdf..b989c83fbc3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1241,6 +1241,17 @@ static void rna_def_space_graph(BlenderRNA *brna) RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Show handles of Bezier control points."); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); + /* cursor */ + prop= RNA_def_property(srna, "show_cursor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NODRAWCURSOR); + RNA_def_property_ui_text(prop, "Show Cursor", "Show 2D cursor."); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); + + prop= RNA_def_property(srna, "cursor_value", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "cursorVal"); + RNA_def_property_ui_text(prop, "Cursor Y-Value", "Graph Editor 2D-Value cursor - Y-Value component"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL); + // TODO... autosnap, dopesheet? } |