Animato/2.5 - Graph Editor (i.e. the new 'IPO Editor')
This commit brings back the drawing code for the 'Graph Editor'. I've decided to call it this, as currently it can show either F-Curves for Animation stored in Actions, or F-Curves for Drivers. Currently, it shows all curves, since some of the necessary filtering code (i.e. for limiting curve visibility) hasn't been put in place yet. At least this serves as good proof that we can have F-Curves from multiple sources at least. It should be noted that the code still has to be modified to work with some of the new Animato features, such as F-Curve Modifiers (cycles are an example of one of the features that use this). Also, a nicer way to set the colours of the curves needs to be investigated. Notes: * Fixed a few bugs in RNA User-Preferences wrapping * The keyframe drawing uses the new-style drawing for handles from AnimSys2. There's a minor bug that sometimes occurs, where a distorted handle gets drawn at the origin of the grid on the first run. Hints anyone? * Removed most of the old data from SpaceIpo struct, as the new code uses that. Maybe later, the directories/files at least should get renamed. * Removed ancient hack for NVidia/TNT drivers. It is probably no longer needed, but could be restored if someone needs it.
This commit is contained in:
@@ -95,6 +95,8 @@ void testhandles_fcurve(struct FCurve *fcu);
|
||||
void sort_time_fcurve(struct FCurve *fcu);
|
||||
short test_time_fcurve(struct FCurve *fcu);
|
||||
|
||||
void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
|
||||
|
||||
/* -------- Evaluation -------- */
|
||||
|
||||
/* evaluate fcurve */
|
||||
|
||||
@@ -1065,8 +1065,6 @@ void do_versions_ipos_to_animato(Main *main)
|
||||
* are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop?
|
||||
*/
|
||||
if (key->ipo) {
|
||||
printf("\t\tconverting key->ipo %s -> %s \n", id->name+2, key->ipo->id.name+2);
|
||||
|
||||
/* Add AnimData block */
|
||||
adt= BKE_id_add_animdata(id);
|
||||
|
||||
|
||||
@@ -3932,63 +3932,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
|
||||
}
|
||||
|
||||
/* Nasty exception; IpoWindow stores a non-ID pointer in *from for sequence
|
||||
strips... bad code warning!
|
||||
|
||||
We work around it by retrieving the missing pointer from the corresponding
|
||||
Sequence-structure.
|
||||
|
||||
This is needed, to make Ipo-Pinning work for Sequence-Ipos...
|
||||
*/
|
||||
// XXX old animation system - depreceated stuff...
|
||||
static Sequence * find_sequence_from_ipo_helper(Main * main, Ipo * ipo)
|
||||
{
|
||||
Sequence *seq;
|
||||
Scene *sce;
|
||||
|
||||
for(sce=main->scene.first; sce; sce=sce->id.next) {
|
||||
int found = 0;
|
||||
|
||||
SEQ_BEGIN(sce->ed, seq) {
|
||||
if (seq->ipo == ipo) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SEQ_END
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
seq = NULL;
|
||||
}
|
||||
|
||||
if (seq)
|
||||
return seq;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void lib_link_screen_sequence_ipos(Main *main)
|
||||
{
|
||||
bScreen *sc;
|
||||
ScrArea *sa;
|
||||
|
||||
for(sc= main->screen.first; sc; sc= sc->id.next) {
|
||||
for(sa= sc->areabase.first; sa; sa= sa->next) {
|
||||
SpaceLink *sl;
|
||||
for (sl= sa->spacedata.first; sl; sl= sl->next) {
|
||||
if(sl->spacetype == SPACE_IPO) {
|
||||
SpaceIpo *sipo= (SpaceIpo *)sl;
|
||||
if(sipo->blocktype==ID_SEQ) {
|
||||
sipo->from = (ID*) find_sequence_from_ipo_helper(main, sipo->ipo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************ READ WM ***************** */
|
||||
|
||||
static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
||||
@@ -4123,13 +4066,9 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
}
|
||||
else if(sl->spacetype==SPACE_IPO) {
|
||||
SpaceIpo *sipo= (SpaceIpo *)sl;
|
||||
sipo->editipo= 0;
|
||||
|
||||
if(sipo->blocktype==ID_SEQ) sipo->from= NULL; // no libdata
|
||||
else sipo->from= newlibadr(fd, sc->id.lib, sipo->from);
|
||||
|
||||
sipo->ipokey.first= sipo->ipokey.last= 0;
|
||||
sipo->ipo= newlibadr(fd, sc->id.lib, sipo->ipo);
|
||||
if(sipo->ads)
|
||||
sipo->ads->source= newlibadr(fd, sc->id.lib, sipo->ads->source);
|
||||
}
|
||||
else if(sl->spacetype==SPACE_BUTS) {
|
||||
SpaceButs *sbuts= (SpaceButs *)sl;
|
||||
@@ -4325,17 +4264,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
|
||||
if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
|
||||
|
||||
}
|
||||
else if(sl->spacetype==SPACE_IPO) {
|
||||
SpaceIpo *sipo= (SpaceIpo *)sl;
|
||||
|
||||
if(sipo->blocktype==ID_SEQ) sipo->from= NULL; // no libdata
|
||||
else sipo->from= restore_pointer_by_name(newmain, (ID *)sipo->from, 0);
|
||||
|
||||
// not free sipo->ipokey, creates dependency with src/
|
||||
sipo->ipo= restore_pointer_by_name(newmain, (ID *)sipo->ipo, 0);
|
||||
if(sipo->editipo) MEM_freeN(sipo->editipo);
|
||||
sipo->editipo= NULL;
|
||||
}
|
||||
else if(sl->spacetype==SPACE_BUTS) {
|
||||
SpaceButs *sbuts= (SpaceButs *)sl;
|
||||
sbuts->lockpoin= NULL;
|
||||
@@ -4574,6 +4502,11 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
|
||||
|
||||
view3d_split_250(v3d, &sl->regionbase);
|
||||
}
|
||||
else if (sl->spacetype==SPACE_IPO) {
|
||||
SpaceIpo *sipo= (SpaceIpo*)sl;
|
||||
|
||||
sipo->ads= newdataadr(fd, sipo->ads);
|
||||
}
|
||||
else if (sl->spacetype==SPACE_OOPS) {
|
||||
SpaceOops *soops= (SpaceOops*) sl;
|
||||
|
||||
@@ -5518,8 +5451,14 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
|
||||
SpaceIpo *sipo= (SpaceIpo *)sl;
|
||||
memcpy(&ar->v2d, &sipo->v2d, sizeof(View2D));
|
||||
|
||||
/* init mainarea view2d */
|
||||
ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
|
||||
ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
|
||||
|
||||
/* init dopesheet */
|
||||
// XXX move this elsewhere instead?
|
||||
sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
|
||||
|
||||
//ar->v2d.flag |= V2D_IS_INITIALISED;
|
||||
break;
|
||||
}
|
||||
@@ -8861,7 +8800,6 @@ static void lib_link_all(FileData *fd, Main *main)
|
||||
lib_link_armature(fd, main);
|
||||
lib_link_action(fd, main);
|
||||
lib_link_vfont(fd, main);
|
||||
lib_link_screen_sequence_ipos(main);
|
||||
lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */
|
||||
lib_link_brush(fd, main);
|
||||
lib_link_particlesettings(fd, main);
|
||||
|
||||
@@ -193,25 +193,15 @@ Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
return NULL;
|
||||
|
||||
/* handling depends on the type of animation-context we've got */
|
||||
if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_IPO)) {
|
||||
/* Action Editor (action mode) or Ipo Editor (ipo mode):
|
||||
if (ac->datatype == ANIMCONT_ACTION) {
|
||||
/* Action Editor (action mode) or Graph Editor (ipo mode):
|
||||
* Only use if editor is not pinned, and active object has action
|
||||
*/
|
||||
if (ac->obact && ac->obact->action) {
|
||||
/* Action Editor */
|
||||
if (ac->datatype == ANIMCONT_ACTION) {
|
||||
SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
|
||||
|
||||
if (saction->pin == 0)
|
||||
return ac->obact;
|
||||
}
|
||||
/* IPO Editor */
|
||||
else if (ac->datatype == ANIMCONT_IPO) {
|
||||
SpaceIpo *sipo= (SpaceIpo *)ac->sa->spacedata.first;
|
||||
|
||||
if (sipo->pin == 0)
|
||||
return ac->obact;
|
||||
}
|
||||
SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
|
||||
|
||||
if (saction->pin == 0)
|
||||
return ac->obact;
|
||||
}
|
||||
}
|
||||
else if ((ac->datatype == ANIMCONT_DOPESHEET) && (ale)) {
|
||||
@@ -225,6 +215,7 @@ Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
return ob;
|
||||
}
|
||||
}
|
||||
// XXX todo: add F-Curves mode (Graph Editor) ...
|
||||
|
||||
/* no appropriate object found */
|
||||
return NULL;
|
||||
|
||||
@@ -196,11 +196,40 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
|
||||
|
||||
/* ----------- Private Stuff - IPO Editor ------------- */
|
||||
|
||||
/* Get data being edited in IPO Editor (depending on current 'mode') */
|
||||
static short ipoedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
|
||||
/* Get data being edited in Graph Editor (depending on current 'mode') */
|
||||
static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
|
||||
{
|
||||
// XXX FIXME...
|
||||
return 0;
|
||||
/* sync settings with current view status, then return appropriate data */
|
||||
switch (sipo->mode) {
|
||||
case SIPO_MODE_ANIMATION: /* Animation F-Curve Editor */
|
||||
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
|
||||
sipo->ads->source= (ID *)ac->scene;
|
||||
sipo->ads->filterflag &= ~ADS_FILTER_ONLYDRIVERS;
|
||||
|
||||
ac->datatype= ANIMCONT_FCURVES;
|
||||
ac->data= sipo->ads;
|
||||
|
||||
ac->mode= sipo->mode;
|
||||
return 1;
|
||||
|
||||
case SIPO_MODE_DRIVERS: /* Driver F-Curve Editor */
|
||||
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
|
||||
sipo->ads->source= (ID *)ac->scene;
|
||||
sipo->ads->filterflag |= ADS_FILTER_ONLYDRIVERS;
|
||||
|
||||
ac->datatype= ANIMCONT_FCURVES;
|
||||
ac->data= sipo->ads;
|
||||
|
||||
ac->mode= sipo->mode;
|
||||
return 1;
|
||||
|
||||
default: /* unhandled yet */
|
||||
ac->datatype= ANIMCONT_NONE;
|
||||
ac->data= NULL;
|
||||
|
||||
ac->mode= -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------- Public API --------------- */
|
||||
@@ -227,7 +256,7 @@ short ANIM_animdata_context_getdata (bAnimContext *ac)
|
||||
case SPACE_IPO:
|
||||
{
|
||||
SpaceIpo *sipo= (SpaceIpo *)sa->spacedata.first;
|
||||
ok= ipoedit_get_context(ac, sipo);
|
||||
ok= graphedit_get_context(ac, sipo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -436,16 +465,19 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG
|
||||
* NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
|
||||
*/
|
||||
for (fcu= first; ((fcu) && (fcu->grp==grp)); fcu= fcu->next) {
|
||||
/* only work with this channel and its subchannels if it is editable */
|
||||
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
|
||||
/* only include this curve if selected */
|
||||
if (!(filter_mode & ANIMFILTER_SEL) || (SEL_FCU(fcu))) {
|
||||
/* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */
|
||||
ale= make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
|
||||
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
/* only include if visible (Graph Editor check, not channels check) */
|
||||
if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
|
||||
/* only work with this channel and its subchannels if it is editable */
|
||||
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
|
||||
/* only include this curve if selected */
|
||||
if (!(filter_mode & ANIMFILTER_SEL) || (SEL_FCU(fcu))) {
|
||||
/* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */
|
||||
ale= make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
|
||||
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -985,7 +1017,7 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
|
||||
/* This function filters the active data source to leave only animation channels suitable for
|
||||
* usage by the caller. It will return the length of the list
|
||||
*
|
||||
* *act_data: is a pointer to a ListBase, to which the filtered animation channels
|
||||
* *anim_data: is a pointer to a ListBase, to which the filtered animation channels
|
||||
* will be placed for use.
|
||||
* filter_mode: how should the data be filtered - bitmapping accessed flags
|
||||
*/
|
||||
@@ -1003,19 +1035,19 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
|
||||
case ANIMCONT_ACTION:
|
||||
items= animdata_filter_action(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
|
||||
break;
|
||||
|
||||
case ANIMCONT_SHAPEKEY:
|
||||
items= animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
|
||||
break;
|
||||
|
||||
case ANIMCONT_GPENCIL:
|
||||
//items= animdata_filter_gpencil(anim_data, data, filter_mode);
|
||||
break;
|
||||
case ANIMCONT_DOPESHEET:
|
||||
items= animdata_filter_dopesheet(anim_data, data, filter_mode);
|
||||
break;
|
||||
|
||||
case ANIMCONT_IPO:
|
||||
// FIXME: this will be used for showing a single IPO-block (not too useful from animator perspective though!)
|
||||
//items= 0;
|
||||
case ANIMCONT_DOPESHEET:
|
||||
case ANIMCONT_FCURVES:
|
||||
case ANIMCONT_DRIVERS:
|
||||
items= animdata_filter_dopesheet(anim_data, data, filter_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,8 @@ typedef enum eAnimCont_Types {
|
||||
ANIMCONT_SHAPEKEY, /* shapekey (Key) */
|
||||
ANIMCONT_GPENCIL, /* grease pencil (screen) */
|
||||
ANIMCONT_DOPESHEET, /* dopesheet (bDopesheet) */
|
||||
ANIMCONT_IPO, /* single IPO (Ipo) */ // XXX
|
||||
ANIMCONT_FCURVES, /* animation F-Curves (bDopesheet) */ // XXX
|
||||
ANIMCONT_DRIVERS, /* drivers (bDopesheet) */
|
||||
} eAnimCont_Types;
|
||||
|
||||
/* --------------- Channels -------------------- */
|
||||
@@ -142,12 +143,13 @@ typedef enum eAnim_KeyType {
|
||||
/* filtering flags - under what circumstances should a channel be added */
|
||||
// XXX was ACTFILTER_*
|
||||
typedef enum eAnimFilter_Flags {
|
||||
ANIMFILTER_VISIBLE = (1<<0), /* should channels be visible */
|
||||
ANIMFILTER_VISIBLE = (1<<0), /* should channels be visible (in terms of hierarchy only) */
|
||||
ANIMFILTER_SEL = (1<<1), /* should channels be selected */
|
||||
ANIMFILTER_FOREDIT = (1<<2), /* does editable status matter */
|
||||
ANIMFILTER_CURVESONLY = (1<<3), /* don't include summary-channels, etc. */
|
||||
ANIMFILTER_CHANNELS = (1<<4), /* make list for interface drawing */
|
||||
ANIMFILTER_ACTGROUPED = (1<<5), /* belongs to the active actiongroup */
|
||||
ANIMFILTER_CURVEVISIBLE = (1<<6), /* F-Curve is visible for editing/viewing in Graph Editor */
|
||||
} eAnimFilter_Flags;
|
||||
|
||||
|
||||
|
||||
@@ -449,6 +449,9 @@ void ui_theme_init_userdef(void)
|
||||
SETCOL(btheme->tipo.handle_vertex, 0xff, 0x70, 0xff, 255);
|
||||
SETCOL(btheme->tipo.handle_vertex_select, 0xff, 0xff, 0x70, 255);
|
||||
btheme->tipo.handle_vertex_size= 3;
|
||||
|
||||
SETCOL(btheme->tipo.ds_channel, 0x36, 0x13, 0xca, 255);
|
||||
SETCOL(btheme->tipo.ds_subchannel, 0x60, 0x43, 0xd2, 255);
|
||||
|
||||
/* space file */
|
||||
/* to have something initialized */
|
||||
|
||||
@@ -630,6 +630,7 @@ void draw_channel_names(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
|
||||
|
||||
case ANIMTYPE_DSMAT: /* for now, this is special case for materials */
|
||||
offset= 21;
|
||||
indent= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_anim_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_types.h"
|
||||
#include "ED_util.h"
|
||||
@@ -57,6 +59,15 @@
|
||||
|
||||
#include "ipo_intern.h"
|
||||
|
||||
/* ********************************************************* */
|
||||
/* Menu Defines... */
|
||||
|
||||
/* button events */
|
||||
enum {
|
||||
B_REDR = 0,
|
||||
B_GRAPHCOPYKEYS,
|
||||
B_GRAPHPASTEKEYS,
|
||||
} eActHeader_ButEvents;
|
||||
|
||||
/* ************************ header area region *********************** */
|
||||
|
||||
@@ -91,25 +102,29 @@ static uiBlock *dummy_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *arg
|
||||
return block;
|
||||
}
|
||||
|
||||
static void do_ipo_buttons(bContext *C, void *arg, int event)
|
||||
static void do_graph_buttons(bContext *C, void *arg, int event)
|
||||
{
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
case B_REDR:
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ipo_header_buttons(const bContext *C, ARegion *ar)
|
||||
void graph_header_buttons(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
|
||||
uiBlock *block;
|
||||
int xco, yco= 3;
|
||||
|
||||
block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS, UI_HELV);
|
||||
uiBlockSetHandleFunc(block, do_ipo_buttons, NULL);
|
||||
uiBlockSetHandleFunc(block, do_graph_buttons, NULL);
|
||||
|
||||
xco= ED_area_header_standardbuttons(C, block, yco);
|
||||
|
||||
if((sa->flag & HEADER_NO_PULLDOWN)==0) {
|
||||
if ((sa->flag & HEADER_NO_PULLDOWN)==0) {
|
||||
int xmax;
|
||||
|
||||
/* pull down menus */
|
||||
@@ -118,10 +133,17 @@ void ipo_header_buttons(const bContext *C, ARegion *ar)
|
||||
xmax= GetButStringLength("View");
|
||||
uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C),
|
||||
"View", xco, yco-2, xmax-3, 24, "");
|
||||
xco+= xmax;
|
||||
}
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
|
||||
/* mode selector */
|
||||
uiDefButS(block, MENU, B_REDR,
|
||||
"Editor Mode %t|F-Curve Editor %x0|Drivers %x1",
|
||||
xco,yco,90,YIC, &sipo->mode, 0, 1, 0, 0,
|
||||
"Editing modes for this editor");
|
||||
|
||||
/* always as last */
|
||||
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
|
||||
|
||||
|
||||
@@ -28,11 +28,19 @@
|
||||
#ifndef ED_IPO_INTERN_H
|
||||
#define ED_IPO_INTERN_H
|
||||
|
||||
struct bContext;
|
||||
struct bAnimContext;
|
||||
struct SpaceIpo;
|
||||
struct ARegion;
|
||||
|
||||
/* internal exports only */
|
||||
|
||||
/* ipo_draw.c */
|
||||
void graph_draw_channel_names(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar);
|
||||
void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar);
|
||||
|
||||
/* ipo_header.c */
|
||||
void ipo_header_buttons(const bContext *C, ARegion *ar);
|
||||
void graph_header_buttons(const bContext *C, struct ARegion *ar);
|
||||
|
||||
|
||||
#endif /* ED_IPO_INTERN_H */
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@@ -62,25 +62,27 @@
|
||||
|
||||
/* ******************** default callbacks for ipo space ***************** */
|
||||
|
||||
static SpaceLink *ipo_new(const bContext *C)
|
||||
static SpaceLink *graph_new(const bContext *C)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
ARegion *ar;
|
||||
SpaceIpo *sipo;
|
||||
|
||||
sipo= MEM_callocN(sizeof(SpaceIpo), "initipo");
|
||||
sipo= MEM_callocN(sizeof(SpaceIpo), "init graphedit");
|
||||
sipo->spacetype= SPACE_IPO;
|
||||
sipo->blocktype= ID_OB;
|
||||
|
||||
/* allocate DopeSheet data for Graph Editor */
|
||||
sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
|
||||
|
||||
/* header */
|
||||
ar= MEM_callocN(sizeof(ARegion), "header for ipo");
|
||||
ar= MEM_callocN(sizeof(ARegion), "header for graphedit");
|
||||
|
||||
BLI_addtail(&sipo->regionbase, ar);
|
||||
ar->regiontype= RGN_TYPE_HEADER;
|
||||
ar->alignment= RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* channels */
|
||||
ar= MEM_callocN(sizeof(ARegion), "main area for ipo");
|
||||
ar= MEM_callocN(sizeof(ARegion), "main area for graphedit");
|
||||
|
||||
BLI_addtail(&sipo->regionbase, ar);
|
||||
ar->regiontype= RGN_TYPE_CHANNELS;
|
||||
@@ -89,7 +91,7 @@ static SpaceLink *ipo_new(const bContext *C)
|
||||
ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
|
||||
|
||||
/* main area */
|
||||
ar= MEM_callocN(sizeof(ARegion), "main area for ipo");
|
||||
ar= MEM_callocN(sizeof(ARegion), "main area for graphedit");
|
||||
|
||||
BLI_addtail(&sipo->regionbase, ar);
|
||||
ar->regiontype= RGN_TYPE_WINDOW;
|
||||
@@ -112,42 +114,41 @@ static SpaceLink *ipo_new(const bContext *C)
|
||||
|
||||
ar->v2d.keeptot= 0;
|
||||
|
||||
/* channel list region XXX */
|
||||
|
||||
|
||||
return (SpaceLink *)sipo;
|
||||
}
|
||||
|
||||
/* not spacelink itself */
|
||||
static void ipo_free(SpaceLink *sl)
|
||||
static void graph_free(SpaceLink *sl)
|
||||
{
|
||||
SpaceIpo *si= (SpaceIpo*) sl;
|
||||
SpaceIpo *si= (SpaceIpo *)sl;
|
||||
|
||||
if(si->editipo) MEM_freeN(si->editipo);
|
||||
// XXX free_ipokey(&si->ipokey);
|
||||
|
||||
if (si->ads) {
|
||||
BLI_freelistN(&si->ads->chanbase);
|
||||
MEM_freeN(si->ads);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* spacetype; init callback */
|
||||
static void ipo_init(struct wmWindowManager *wm, ScrArea *sa)
|
||||
static void graph_init(struct wmWindowManager *wm, ScrArea *sa)
|
||||
{
|
||||
|
||||
//SpaceIpo *si= (SpaceIpo *)sa->spacedata.first;
|
||||
|
||||
}
|
||||
|
||||
static SpaceLink *ipo_duplicate(SpaceLink *sl)
|
||||
static SpaceLink *graph_duplicate(SpaceLink *sl)
|
||||
{
|
||||
SpaceIpo *sipon= MEM_dupallocN(sl);
|
||||
|
||||
/* clear or remove stuff from old */
|
||||
sipon->editipo= NULL;
|
||||
sipon->ipokey.first= sipon->ipokey.last= NULL;
|
||||
//sipon->ipokey.first= sipon->ipokey.last= NULL;
|
||||
sipon->ads= MEM_dupallocN(sipon->ads);
|
||||
|
||||
return (SpaceLink *)sipon;
|
||||
}
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void ipo_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
static void graph_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ListBase *keymap;
|
||||
|
||||
@@ -158,15 +159,16 @@ static void ipo_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
}
|
||||
|
||||
static void ipo_main_area_draw(const bContext *C, ARegion *ar)
|
||||
static void graph_main_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
/* draw entirely, view changes should be handled here */
|
||||
SpaceIpo *sipo= (SpaceIpo*)CTX_wm_space_data(C);
|
||||
bAnimContext ac;
|
||||
View2D *v2d= &ar->v2d;
|
||||
View2DGrid *grid;
|
||||
View2DScrollers *scrollers;
|
||||
float col[3];
|
||||
short unit=0, flag=0;
|
||||
short unitx=0, unity=V2D_UNIT_VALUES, flag=0;
|
||||
|
||||
/* clear and setup matrix */
|
||||
UI_GetThemeColor3fv(TH_BACK, col);
|
||||
@@ -176,12 +178,15 @@ static void ipo_main_area_draw(const bContext *C, ARegion *ar)
|
||||
UI_view2d_view_ortho(C, v2d);
|
||||
|
||||
/* grid */
|
||||
unit= (sipo->flag & SIPO_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
|
||||
grid= UI_view2d_grid_calc(C, v2d, unit, V2D_GRID_NOCLAMP, V2D_UNIT_VALUES/*unit-y*/, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
|
||||
unitx= (sipo->flag & SIPO_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
|
||||
grid= UI_view2d_grid_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
|
||||
UI_view2d_grid_draw(C, v2d, grid, V2D_GRIDLINES_ALL);
|
||||
UI_view2d_grid_free(grid);
|
||||
|
||||
/* data... */
|
||||
/* draw data */
|
||||
if (ANIM_animdata_get_context(C, &ac)) {
|
||||
graph_draw_curves(&ac, sipo, ar);
|
||||
}
|
||||
|
||||
/* current frame */
|
||||
if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS;
|
||||
@@ -201,27 +206,34 @@ static void ipo_main_area_draw(const bContext *C, ARegion *ar)
|
||||
|
||||
/* scrollers */
|
||||
// FIXME: args for scrollers depend on the type of data being shown...
|
||||
scrollers= UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_NOCLAMP, V2D_UNIT_VALUES/*unit-y*/, V2D_GRID_NOCLAMP);
|
||||
scrollers= UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
|
||||
UI_view2d_scrollers_draw(C, v2d, scrollers);
|
||||
UI_view2d_scrollers_free(scrollers);
|
||||
}
|
||||
|
||||
void ipo_operatortypes(void)
|
||||
void graph_operatortypes(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ipo_keymap(struct wmWindowManager *wm)
|
||||
void graph_keymap(struct wmWindowManager *wm)
|
||||
{
|
||||
}
|
||||
|
||||
static void ipo_channel_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
static void graph_channel_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ListBase *keymap;
|
||||
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
|
||||
|
||||
/* own keymap */
|
||||
keymap= WM_keymap_listbase(wm, "Animation_Channels", 0, 0); /* XXX weak? */
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
}
|
||||
|
||||
static void ipo_channel_area_draw(const bContext *C, ARegion *ar)
|
||||
static void graph_channel_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
//SpaceIpo *sipo= C->area->spacedata.first;
|
||||
SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
|
||||
bAnimContext ac;
|
||||
View2D *v2d= &ar->v2d;
|
||||
View2DScrollers *scrollers;
|
||||
float col[3];
|
||||
@@ -233,7 +245,10 @@ static void ipo_channel_area_draw(const bContext *C, ARegion *ar)
|
||||
|
||||
UI_view2d_view_ortho(C, v2d);
|
||||
|
||||
/* data... */
|
||||
/* draw channels */
|
||||
if (ANIM_animdata_get_context(C, &ac)) {
|
||||
graph_draw_channel_names(&ac, sipo, ar);
|
||||
}
|
||||
|
||||
/* reset view matrix */
|
||||
UI_view2d_view_restore(C);
|
||||
@@ -245,12 +260,12 @@ static void ipo_channel_area_draw(const bContext *C, ARegion *ar)
|
||||
}
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void ipo_header_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
static void graph_header_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
|
||||
}
|
||||
|
||||
static void ipo_header_area_draw(const bContext *C, ARegion *ar)
|
||||
static void graph_header_area_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
float col[3];
|
||||
|
||||
@@ -266,28 +281,88 @@ static void ipo_header_area_draw(const bContext *C, ARegion *ar)
|
||||
/* set view2d view matrix for scrolling (without scrollers) */
|
||||
UI_view2d_view_ortho(C, &ar->v2d);
|
||||
|
||||
ipo_header_buttons(C, ar);
|
||||
graph_header_buttons(C, ar);
|
||||
|
||||
/* restore view matrix? */
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
static void ipo_main_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
static void graph_main_area_listener(ARegion *ar, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
switch(wmn->category) {
|
||||
|
||||
case NC_SCENE:
|
||||
switch(wmn->data) {
|
||||
case ND_OB_ACTIVE:
|
||||
case ND_FRAME:
|
||||
case ND_MARKERS:
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NC_OBJECT:
|
||||
switch(wmn->data) {
|
||||
case ND_BONE_ACTIVE:
|
||||
case ND_BONE_SELECT:
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* editor level listener */
|
||||
static void graph_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
{
|
||||
/* context changes */
|
||||
switch (wmn->category) {
|
||||
case NC_SCENE:
|
||||
/*switch (wmn->data) {
|
||||
case ND_OB_ACTIVE:
|
||||
case ND_OB_SELECT:
|
||||
ED_area_tag_refresh(sa);
|
||||
break;
|
||||
}*/
|
||||
ED_area_tag_refresh(sa);
|
||||
break;
|
||||
case NC_OBJECT:
|
||||
/*switch (wmn->data) {
|
||||
case ND_BONE_SELECT:
|
||||
case ND_BONE_ACTIVE:
|
||||
ED_area_tag_refresh(sa);
|
||||
break;
|
||||
}*/
|
||||
ED_area_tag_refresh(sa);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void graph_refresh(const bContext *C, ScrArea *sa)
|
||||
{
|
||||
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
|
||||
|
||||
/* updates to data needed depends on Graph Editor mode... */
|
||||
switch (sipo->mode) {
|
||||
case SIPO_MODE_ANIMATION: /* all animation */
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SIPO_MODE_DRIVERS: /* drivers only */
|
||||
{
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
|
||||
/* sync changes to bones to the corresponding action channels */
|
||||
ANIM_pose_to_action_sync(ob, sa);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* region updates? */
|
||||
// XXX resizing y-extents of tot should go here?
|
||||
}
|
||||
|
||||
/* only called once, from space/spacetypes.c */
|
||||
void ED_spacetype_ipo(void)
|
||||
{
|
||||
@@ -296,42 +371,44 @@ void ED_spacetype_ipo(void)
|
||||
|
||||
st->spaceid= SPACE_IPO;
|
||||
|
||||
st->new= ipo_new;
|
||||
st->free= ipo_free;
|
||||
st->init= ipo_init;
|
||||
st->duplicate= ipo_duplicate;
|
||||
st->operatortypes= ipo_operatortypes;
|
||||
st->keymap= ipo_keymap;
|
||||
st->new= graph_new;
|
||||
st->free= graph_free;
|
||||
st->init= graph_init;
|
||||
st->duplicate= graph_duplicate;
|
||||
st->operatortypes= graph_operatortypes;
|
||||
st->keymap= graph_keymap;
|
||||
st->listener= graph_listener;
|
||||
st->refresh= graph_refresh;
|
||||
|
||||
/* regions: main window */
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype ipo region");
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
|
||||
art->regionid = RGN_TYPE_WINDOW;
|
||||
art->init= ipo_main_area_init;
|
||||
art->draw= ipo_main_area_draw;
|
||||
art->listener= ipo_main_area_listener;
|
||||
art->init= graph_main_area_init;
|
||||
art->draw= graph_main_area_draw;
|
||||
art->listener= graph_main_area_listener;
|
||||
art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_ANIMATION;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: header */
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype ipo region");
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
|
||||
art->regionid = RGN_TYPE_HEADER;
|
||||
art->minsizey= HEADERY;
|
||||
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
|
||||
|
||||
art->init= ipo_header_area_init;
|
||||
art->draw= ipo_header_area_draw;
|
||||
art->init= graph_header_area_init;
|
||||
art->draw= graph_header_area_draw;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: channels */
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype ipo region");
|
||||
art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
|
||||
art->regionid = RGN_TYPE_CHANNELS;
|
||||
art->minsizex= 200;
|
||||
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
|
||||
|
||||
art->init= ipo_channel_area_init;
|
||||
art->draw= ipo_channel_area_draw;
|
||||
art->init= graph_channel_area_init;
|
||||
art->draw= graph_channel_area_draw;
|
||||
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
|
||||
@@ -287,10 +287,12 @@ typedef struct bDopeSheet {
|
||||
typedef enum DOPESHEET_FILTERFLAG {
|
||||
/* general filtering */
|
||||
ADS_FILTER_ONLYSEL = (1<<0),
|
||||
ADS_FILTER_ONLYDRIVERS = (1<<1),
|
||||
|
||||
/* datatype-based filtering */
|
||||
ADS_FILTER_NOOBJ = (1<<4), // XXX
|
||||
ADS_FILTER_NOARM = (1<<5), // XXX
|
||||
|
||||
ADS_FILTER_NOSHAPEKEYS = (1<<6),
|
||||
ADS_FILTER_NOCAM = (1<<10),
|
||||
ADS_FILTER_NOMAT = (1<<11),
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
/* Hum ... Not really nice... but needed for spacebuts. */
|
||||
#include "DNA_view2d_types.h"
|
||||
|
||||
struct Ipo;
|
||||
struct ID;
|
||||
struct Text;
|
||||
struct Script;
|
||||
@@ -51,6 +50,7 @@ struct bNodeTree;
|
||||
struct uiBlock;
|
||||
struct FileList;
|
||||
struct bGPdata;
|
||||
struct bDopeSheet;
|
||||
struct FileSelectParams;
|
||||
struct wmOperator;
|
||||
struct wmTimer;
|
||||
@@ -78,6 +78,8 @@ typedef struct SpaceInfo {
|
||||
short blockhandler[8];
|
||||
} 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 */
|
||||
@@ -85,25 +87,18 @@ typedef struct SpaceIpo {
|
||||
float blockscale;
|
||||
|
||||
short blockhandler[8];
|
||||
|
||||
unsigned int rowbut, pad2;
|
||||
View2D v2d; /* depricated, copied to region */
|
||||
|
||||
void *editipo;
|
||||
ListBase ipokey;
|
||||
// 'IPO keys' - vertical lines for
|
||||
//ListBase ipokey; // XXX it's not clear how these will come back yet
|
||||
//short showkey; // XXX this doesn't need to be restored until ipokeys come back
|
||||
|
||||
/* the ipo context we need to store */
|
||||
struct Ipo *ipo;
|
||||
struct ID *from;
|
||||
char actname[32], constname[32], bonename[32];
|
||||
|
||||
short totipo, pin;
|
||||
short butofs, channel;
|
||||
short showkey, blocktype;
|
||||
short menunr, lock;
|
||||
short flag, autosnap;
|
||||
float median[3];
|
||||
rctf tot;
|
||||
struct bDopeSheet *ads; /* settings for filtering animation data (NOTE: we use a pointer due to code-linking issues) */
|
||||
|
||||
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;
|
||||
} SpaceIpo;
|
||||
|
||||
typedef struct SpaceButs {
|
||||
@@ -588,13 +583,21 @@ typedef struct SpaceImaSel {
|
||||
#define SI_DRAW_STRETCH 1<<21
|
||||
#define SI_DISPGP 1<<22
|
||||
|
||||
/* SpaceIpo->flag */
|
||||
/* SpaceIpo->flag (Graph Editor Settings) */
|
||||
#define SIPO_LOCK_VIEW (1<<0)
|
||||
#define SIPO_NOTRANSKEYCULL (1<<1)
|
||||
#define SIPO_NOHANDLES (1<<2)
|
||||
#define SIPO_NODRAWCFRANUM (1<<3)
|
||||
#define SIPO_DRAWTIME (1<<4)
|
||||
|
||||
/* SpaceIpo->mode (Graph Editor Mode) */
|
||||
enum {
|
||||
/* all animation curves (from all over Blender) */
|
||||
SIPO_MODE_ANIMATION = 0,
|
||||
/* drivers only */
|
||||
SIPO_MODE_DRIVERS,
|
||||
} eGraphEdit_Mode;
|
||||
|
||||
/* SpaceText flags (moved from DNA_text_types.h) */
|
||||
|
||||
#define ST_SCROLL_SELECT 0x0001 // scrollable
|
||||
|
||||
@@ -398,8 +398,8 @@ static void rna_def_userdef_theme_space_ipo(BlenderRNA *brna)
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_ui_text(prop, "Handle Vertex Select", "");
|
||||
|
||||
prop= RNA_def_property(srna, "handle_vertex_size", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
prop= RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 255);
|
||||
RNA_def_property_ui_text(prop, "Handle Vertex Size", "");
|
||||
}
|
||||
|
||||
@@ -1320,10 +1320,10 @@ static void rna_def_userdef_edit(StructRNA *srna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_AUTOMATKEY);
|
||||
RNA_def_property_ui_text(prop, "Use Visual Keying", "Use Visual keying automatically for constrained objects.");
|
||||
|
||||
prop= RNA_def_property(srna, "new_ipo_curve_type", PROP_ENUM, PROP_NONE);
|
||||
prop= RNA_def_property(srna, "new_interpolation_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, new_ipo_curve_types);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "ipo_new");
|
||||
RNA_def_property_ui_text(prop, "New Ipo Curve Type", "");
|
||||
RNA_def_property_ui_text(prop, "New Interpolation Type", "");
|
||||
|
||||
prop= RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist");
|
||||
|
||||
@@ -327,6 +327,10 @@ static void init_userdef_themes(void)
|
||||
/* DopeSheet - (Object) Channel color */
|
||||
SETCOL(btheme->tact.ds_channel, 0x36, 0x13, 0xca, 255);
|
||||
SETCOL(btheme->tact.ds_subchannel, 0x60, 0x43, 0xd2, 255);
|
||||
|
||||
/* Graph Editor - (Object) Channel color */
|
||||
SETCOL(btheme->tipo.ds_channel, 0x36, 0x13, 0xca, 255);
|
||||
SETCOL(btheme->tipo.ds_subchannel, 0x60, 0x43, 0xd2, 255);
|
||||
}
|
||||
|
||||
/* adjust grease-pencil distances */
|
||||
|
||||
Reference in New Issue
Block a user