Graph Editor: Pivot Modes for Transform
It is now possible to choose from 'Bounding Box' (default), '2D-Cursor', and 'Individual Centers' as the pivot point(s) that rotation/scaling is performed around.
This commit is contained in:
@@ -250,17 +250,30 @@ static void do_graph_buttons(bContext *C, void *arg, int event)
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
}
|
||||
|
||||
static char *garound_pup(const bContext *C)
|
||||
{
|
||||
static char string[512];
|
||||
char *str = string;
|
||||
|
||||
str += sprintf(str, "%s", "Pivot: %t");
|
||||
str += sprintf(str, "%s", "|Bounding Box Center %x0");
|
||||
//str += sprintf(str, "%s", "|Median Point %x3");
|
||||
str += sprintf(str, "%s", "|2D Cursor %x1");
|
||||
str += sprintf(str, "%s", "|Individual Centers %x2");
|
||||
return string;
|
||||
}
|
||||
|
||||
void graph_header_buttons(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
SpaceIpo *sipo= CTX_wm_space_graph(C);
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
uiBlock *block;
|
||||
int xco, yco= 3;
|
||||
|
||||
block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
|
||||
uiBlockSetHandleFunc(block, do_graph_buttons, NULL);
|
||||
|
||||
/* standard buttosn in header - viewtype selector and menus */
|
||||
xco= ED_area_header_standardbuttons(C, block, yco);
|
||||
|
||||
if ((sa->flag & HEADER_NO_PULLDOWN)==0) {
|
||||
@@ -310,6 +323,10 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
|
||||
}
|
||||
xco += 98;
|
||||
|
||||
/* pivot mode setting */
|
||||
uiDefIconTextButI(block, ICONTEXTROW,B_REDR, ICON_ROTATE, garound_pup(C), xco,yco,XIC+10,YIC, &(sipo->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot");
|
||||
xco+= XIC+10;
|
||||
|
||||
/* copy + paste */
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefIconButO(block, BUT, "GRAPH_OT_copy", WM_OP_INVOKE_REGION_WIN, ICON_COPYDOWN, xco+=XIC,yco,XIC,YIC, "Copies the selected keyframes from the selected channel(s) to the buffer");
|
||||
|
||||
@@ -3344,6 +3344,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
|
||||
|
||||
static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceIpo *sipo= CTX_wm_space_graph(C);
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
View2D *v2d= &ar->v2d;
|
||||
@@ -3375,7 +3376,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
/* only side on which mouse is gets transformed */
|
||||
float xmouse, ymouse;
|
||||
|
||||
UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
|
||||
UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
|
||||
side = (xmouse > CFRA) ? 'R' : 'L'; // XXX use t->frame_side
|
||||
}
|
||||
else {
|
||||
@@ -3403,7 +3404,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
|
||||
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
|
||||
if (v2d->around == V3D_LOCAL) {
|
||||
if (sipo->around == V3D_LOCAL) {
|
||||
/* for local-pivot we only need to count the number of selected handles only, so that centerpoints don't
|
||||
* don't get moved wrong
|
||||
*/
|
||||
@@ -3482,7 +3483,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
/* only include main vert if selected */
|
||||
if (bezt->f2 & SELECT) {
|
||||
/* if scaling around individuals centers, do not include keyframes */
|
||||
if (v2d->around != V3D_LOCAL) {
|
||||
if (sipo->around != V3D_LOCAL) {
|
||||
/* if handles were not selected, store their selection status */
|
||||
if (!(bezt->f1 & SELECT) && !(bezt->f3 & SELECT)) {
|
||||
if (hdata == NULL)
|
||||
|
||||
@@ -952,11 +952,17 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
|
||||
t->view = &ar->v2d;
|
||||
t->around = sima->around;
|
||||
}
|
||||
else if(t->spacetype==SPACE_IPO)
|
||||
{
|
||||
SpaceIpo *sipo= sa->spacedata.first;
|
||||
t->view = &ar->v2d;
|
||||
t->around = sipo->around;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX for now, get View2D from the active region
|
||||
t->view = &ar->v2d;
|
||||
|
||||
// XXX for now, the center point is the midpoint of the data
|
||||
t->around = V3D_CENTER;
|
||||
}
|
||||
|
||||
@@ -1196,6 +1202,18 @@ void calculateCenterCursor2D(TransInfo *t)
|
||||
calculateCenter2D(t);
|
||||
}
|
||||
|
||||
void calculateCenterCursorGraph2D(TransInfo *t)
|
||||
{
|
||||
SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
|
||||
Scene *scene= t->scene;
|
||||
|
||||
/* cursor is combination of current frame, and graph-editor cursor value */
|
||||
t->center[0]= (float)(scene->r.cfra);
|
||||
t->center[1]= sipo->cursorVal;
|
||||
|
||||
calculateCenter2D(t);
|
||||
}
|
||||
|
||||
void calculateCenterMedian(TransInfo *t)
|
||||
{
|
||||
float partial[3] = {0.0f, 0.0f, 0.0f};
|
||||
@@ -1267,6 +1285,8 @@ void calculateCenter(TransInfo *t)
|
||||
case V3D_CURSOR:
|
||||
if(t->spacetype==SPACE_IMAGE)
|
||||
calculateCenterCursor2D(t);
|
||||
else if(t->spacetype==SPACE_IPO)
|
||||
calculateCenterCursorGraph2D(t);
|
||||
else
|
||||
calculateCenterCursor(t);
|
||||
break;
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef struct SpaceIpo {
|
||||
int flag; /* settings for Graph editor */
|
||||
|
||||
float cursorVal; /* cursor value (y-value, x-value is current frame) */
|
||||
int pad;
|
||||
int around; /* pivot point for transforms */
|
||||
} SpaceIpo;
|
||||
|
||||
typedef struct SpaceButs {
|
||||
|
||||
@@ -1195,6 +1195,15 @@ static void rna_def_space_graph(BlenderRNA *brna)
|
||||
{SIPO_MODE_ANIMATION, "FCURVES", 0, "F-Curves", ""},
|
||||
{SIPO_MODE_DRIVERS, "DRIVERS", 0, "Drivers", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* this is basically the same as the one for the 3D-View, but with some entries ommitted */
|
||||
static EnumPropertyItem gpivot_items[] = {
|
||||
{V3D_CENTER, "BOUNDING_BOX_CENTER", 0, "Bounding Box Center", ""},
|
||||
{V3D_CURSOR, "CURSOR", 0, "2D Cursor", ""},
|
||||
{V3D_LOCAL, "INDIVIDUAL_CENTERS", 0, "Individual Centers", ""},
|
||||
//{V3D_CENTROID, "MEDIAN_POINT", 0, "Median Point", ""},
|
||||
//{V3D_ACTIVE, "ACTIVE_ELEMENT", 0, "Active Element", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
|
||||
srna= RNA_def_struct(brna, "SpaceGraphEditor", "Space");
|
||||
@@ -1252,6 +1261,12 @@ static void rna_def_space_graph(BlenderRNA *brna)
|
||||
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);
|
||||
|
||||
prop= RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "around");
|
||||
RNA_def_property_enum_items(prop, gpivot_items);
|
||||
RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling.");
|
||||
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_GRAPH, NULL);
|
||||
|
||||
// TODO... autosnap, dopesheet?
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user