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...
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,20 +5313,6 @@ 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) {
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 this probably shouldn't be here..
|
||||
// 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);
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
/* 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user