Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-10-20 16:04:56 +0400
committerJoshua Leung <aligorith@gmail.com>2009-10-20 16:04:56 +0400
commit00f3d83b6ab5f4f9ee4f69457e492db72a03cf30 (patch)
treedd57f5d8b0bb859a0403225a11d118844a728c68
parentec6bccfad1609fa09a703d7496310da246fd5825 (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.c2
-rw-r--r--source/blender/editors/animation/anim_ops.c26
-rw-r--r--source/blender/editors/armature/editarmature.c63
-rw-r--r--source/blender/editors/space_graph/graph_edit.c7
-rw-r--r--source/blender/editors/space_graph/graph_header.c2
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c136
-rw-r--r--source/blender/editors/space_graph/space_graph.c21
-rw-r--r--source/blender/makesdna/DNA_space_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_space.c11
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?
}