921 lines
23 KiB
C
921 lines
23 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
* Drawing routines for the Action window type
|
|
*/
|
|
|
|
/* System includes ----------------------------------------------------- */
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BMF_Api.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_arithb.h"
|
|
|
|
/* Types --------------------------------------------------------------- */
|
|
#include "DNA_action_types.h"
|
|
#include "DNA_curve_types.h"
|
|
#include "DNA_ipo_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_constraint_types.h"
|
|
#include "DNA_key_types.h"
|
|
|
|
#include "BKE_action.h"
|
|
#include "BKE_global.h"
|
|
|
|
/* Everything from source (BIF, BDR, BSE) ------------------------------ */
|
|
|
|
#include "BIF_gl.h"
|
|
#include "BIF_glutil.h"
|
|
#include "BIF_resources.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_interface.h"
|
|
#include "BIF_mywindow.h"
|
|
#include "BIF_space.h"
|
|
|
|
#include "BDR_editcurve.h"
|
|
#include "BSE_view.h"
|
|
#include "BSE_drawipo.h"
|
|
#include "BSE_editaction.h"
|
|
#include "BSE_editaction_types.h"
|
|
#include "BDR_drawaction.h"
|
|
|
|
/* 'old' stuff": defines and types, and own include -------------------- */
|
|
|
|
#include "blendef.h"
|
|
#include "mydevice.h"
|
|
|
|
#include "BKE_ipo.h"
|
|
|
|
/* local functions ----------------------------------------------------- */
|
|
void drawactionspace(ScrArea *sa, void *spacedata);
|
|
static void draw_channel_names(void);
|
|
static void draw_channel_strips(SpaceAction *saction);
|
|
int count_action_levels(bAction *act);
|
|
static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert);
|
|
static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert);
|
|
static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert);
|
|
static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert);
|
|
static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
|
|
void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos);
|
|
static void draw_action_mesh_names(Key *key);
|
|
|
|
/* implementation ------------------------------------------------------ */
|
|
|
|
extern void make_rvk_slider(uiBlock *block, Key *key, int i,
|
|
int x, int y, int w, int h); /* editkey.c */
|
|
extern short showsliders; /* editaction .c */
|
|
extern short ACTWIDTH;
|
|
|
|
void meshactionbuts(SpaceAction *saction, Key *key)
|
|
{
|
|
int i;
|
|
char str[64];
|
|
float x, y;
|
|
uiBlock *block;
|
|
uiBut *but;
|
|
|
|
#define XIC 20
|
|
#define YIC 20
|
|
|
|
/* lets make the rvk sliders */
|
|
|
|
/* reset the damn myortho2 or the sliders won't draw/redraw
|
|
* correctly *grumble*
|
|
*/
|
|
mywinset(curarea->win);
|
|
myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
|
|
|
|
sprintf(str, "actionbuttonswin %d", curarea->win);
|
|
block= uiNewBlock (&curarea->uiblocks, str,
|
|
UI_EMBOSS, UI_HELV, curarea->win);
|
|
|
|
x = NAMEWIDTH + 1;
|
|
y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP)
|
|
- CHANNELHEIGHT/2 - G.v2d->cur.ymin;
|
|
|
|
/* make the little 'open the sliders' widget */
|
|
BIF_ThemeColor(TH_FACE); // this slot was open...
|
|
glRects(2, y + 2*CHANNELHEIGHT - 2,
|
|
ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
|
|
glColor3ub(0, 0, 0);
|
|
glRasterPos2f(4, y + CHANNELHEIGHT + 6);
|
|
BMF_DrawString(G.font, "Sliders");
|
|
|
|
uiBlockSetEmboss(block, UI_EMBOSSN);
|
|
|
|
if (!showsliders) {
|
|
ACTWIDTH = NAMEWIDTH;
|
|
but=uiDefIconButS(block, TOG, B_REDR,
|
|
ICON_DISCLOSURE_TRI_RIGHT,
|
|
NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
|
|
XIC,YIC-2,
|
|
&(showsliders), 0, 0, 0, 0,
|
|
"Show action window sliders");
|
|
// no hilite, the winmatrix is not correct later on...
|
|
uiButSetFlag(but, UI_NO_HILITE);
|
|
|
|
}
|
|
else {
|
|
but= uiDefIconButS(block, TOG, B_REDR,
|
|
ICON_DISCLOSURE_TRI_DOWN,
|
|
NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
|
|
XIC,YIC-2,
|
|
&(showsliders), 0, 0, 0, 0,
|
|
"Hide action window sliders");
|
|
// no hilite, the winmatrix is not correct later on...
|
|
uiButSetFlag(but, UI_NO_HILITE);
|
|
|
|
ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
|
|
|
|
/* sliders are open so draw them */
|
|
BIF_ThemeColor(TH_FACE);
|
|
|
|
glRects(NAMEWIDTH, 0, NAMEWIDTH+SLIDERWIDTH, curarea->winy);
|
|
uiBlockSetEmboss(block, UI_EMBOSS);
|
|
for (i=1 ; i < key->totkey ; ++ i) {
|
|
make_rvk_slider(block, key, i,
|
|
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1);
|
|
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
|
|
}
|
|
}
|
|
uiDrawBlock(block);
|
|
|
|
}
|
|
|
|
void draw_cfra_action(void)
|
|
{
|
|
Object *ob;
|
|
float vec[2];
|
|
|
|
vec[0]= (G.scene->r.cfra);
|
|
vec[0]*= G.scene->r.framelen;
|
|
|
|
vec[1]= G.v2d->cur.ymin;
|
|
glColor3ub(0x60, 0xc0, 0x40);
|
|
glLineWidth(2.0);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex2fv(vec);
|
|
vec[1]= G.v2d->cur.ymax;
|
|
glVertex2fv(vec);
|
|
glEnd();
|
|
|
|
ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
|
|
if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
|
|
vec[0]-= ob->sf;
|
|
|
|
glColor3ub(0x10, 0x60, 0);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex2fv(vec);
|
|
vec[1]= G.v2d->cur.ymin;
|
|
glVertex2fv(vec);
|
|
glEnd();
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
}
|
|
|
|
|
|
static void draw_action_channel_names(bAction *act)
|
|
{
|
|
bActionChannel *chan;
|
|
bConstraintChannel *conchan;
|
|
float x, y;
|
|
|
|
x = 0.0;
|
|
y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
|
|
|
|
for (chan=act->chanbase.first; chan; chan=chan->next){
|
|
BIF_ThemeColorShade(TH_HEADER, 20);
|
|
glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
|
|
|
|
if (chan->flag & ACHAN_SELECTED)
|
|
BIF_ThemeColor(TH_TEXT_HI);
|
|
else
|
|
BIF_ThemeColor(TH_TEXT);
|
|
glRasterPos2f(x+8, y-4);
|
|
BMF_DrawString(G.font, chan->name);
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
|
|
/* Draw constraint channels */
|
|
for (conchan=chan->constraintChannels.first;
|
|
conchan; conchan=conchan->next){
|
|
if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
|
|
BIF_ThemeColor(TH_TEXT_HI);
|
|
else
|
|
BIF_ThemeColor(TH_TEXT);
|
|
|
|
glRasterPos2f(x+32, y-4);
|
|
BMF_DrawString(G.font, conchan->name);
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void draw_action_mesh_names(Key *key)
|
|
{
|
|
/* draws the names of the rvk keys in the
|
|
* left side of the action window
|
|
*/
|
|
int i;
|
|
char keyname[32];
|
|
float x, y;
|
|
KeyBlock *kb;
|
|
|
|
x = 0.0;
|
|
y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
|
|
|
|
kb= key->block.first;
|
|
|
|
for (i=1 ; i < key->totkey ; ++ i) {
|
|
glColor3ub(0xAA, 0xAA, 0xAA);
|
|
glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
|
|
|
|
glColor3ub(0, 0, 0);
|
|
|
|
glRasterPos2f(x+8, y-4);
|
|
kb = kb->next;
|
|
/* Blender now has support for named
|
|
* key blocks. If a name hasn't
|
|
* been set for an key block then
|
|
* just display the key number --
|
|
* otherwise display the name stored
|
|
* in the keyblock.
|
|
*/
|
|
if (kb->name[0] == '\0') {
|
|
sprintf(keyname, "Key %d", i);
|
|
BMF_DrawString(G.font, keyname);
|
|
}
|
|
else {
|
|
BMF_DrawString(G.font, kb->name);
|
|
}
|
|
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
|
|
}
|
|
}
|
|
|
|
static void draw_channel_names(void)
|
|
{
|
|
short ofsx, ofsy = 0;
|
|
bAction *act;
|
|
Key *key;
|
|
float col[3];
|
|
|
|
myortho2(0, NAMEWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling
|
|
|
|
/* Blank out the area */
|
|
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
|
|
if(G.v2d->scroll) {
|
|
ofsx= curarea->winrct.xmin;
|
|
ofsy= curarea->winrct.ymin;
|
|
glViewport(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH,
|
|
(ofsy+G.v2d->mask.ymax) -
|
|
(ofsy+G.v2d->mask.ymin-SCROLLB));
|
|
glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH,
|
|
(ofsy+G.v2d->mask.ymax) -
|
|
(ofsy+G.v2d->mask.ymin-SCROLLB));
|
|
}
|
|
}
|
|
|
|
BIF_GetThemeColor3fv(TH_HEADER, col);
|
|
glClearColor(col[0], col[1], col[2], 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
/* Clip to the scrollable area */
|
|
|
|
glColor3ub(0x00, 0x00, 0x00);
|
|
|
|
act=G.saction->action;
|
|
|
|
if (act) {
|
|
/* if there is a selected action then
|
|
* draw the channel names
|
|
*/
|
|
draw_action_channel_names(act);
|
|
}
|
|
if ( (key = get_action_mesh_key()) ) {
|
|
/* if there is a mesh selected with rvk's,
|
|
* then draw the RVK names
|
|
*/
|
|
draw_action_mesh_names(key);
|
|
}
|
|
|
|
myortho2(0, NAMEWIDTH, 0, (ofsy+G.v2d->mask.ymax) -
|
|
(ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling
|
|
|
|
}
|
|
|
|
int count_action_levels(bAction *act)
|
|
{
|
|
int y=0;
|
|
bActionChannel *achan;
|
|
|
|
if (!act)
|
|
return 0;
|
|
|
|
for (achan=act->chanbase.first; achan; achan=achan->next){
|
|
y+=1;
|
|
y+=BLI_countlist(&achan->constraintChannels);
|
|
}
|
|
|
|
return y;
|
|
}
|
|
/** Draw a nicely beveled button (in screen space) */
|
|
void draw_bevel_but(int x, int y, int w, int h, int sel)
|
|
{
|
|
int xmin= x, ymin= y;
|
|
int xmax= x+w-1, ymax= y+h-1;
|
|
int i;
|
|
|
|
glColor3ub(0,0,0);
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex2i(xmin, ymin);
|
|
glVertex2i(xmax, ymin);
|
|
glVertex2i(xmax, ymax);
|
|
glVertex2i(xmin, ymax);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
if (sel) glColor3ub(0xD0, 0x7E, 0x06);
|
|
else glColor3ub(0x8C, 0x8C, 0x8C);
|
|
glVertex2i(xmax-1, ymin+1);
|
|
glVertex2i(xmax-1, ymax-1);
|
|
if (sel) glColor3ub(0xF4, 0xEE, 0x8E);
|
|
else glColor3ub(0xDF, 0xDF, 0xDF);
|
|
glVertex2i(xmin+1, ymax-1);
|
|
glVertex2i(xmin+1, ymin+1);
|
|
glEnd();
|
|
|
|
if (sel) glColor3ub(0xF1, 0xCA, 0x13);
|
|
else glColor3ub(0xAC, 0xAC, 0xAC);
|
|
glBegin(GL_LINES);
|
|
for (i=xmin+2; i<=xmax-2; i++) {
|
|
glVertex2f(i, ymin+2);
|
|
glVertex2f(i, ymax-1);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
static void draw_channel_strips(SpaceAction *saction)
|
|
{
|
|
rcti scr_rct;
|
|
gla2DDrawInfo *di;
|
|
bAction *act;
|
|
bActionChannel *chan;
|
|
bConstraintChannel *conchan;
|
|
float y;
|
|
char col1[3], col2[3];
|
|
|
|
BIF_GetThemeColor3ubv(TH_SHADE2, col2);
|
|
BIF_GetThemeColor3ubv(TH_HILITE, col1);
|
|
|
|
act= saction->action;
|
|
if (!act)
|
|
return;
|
|
|
|
scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
|
|
scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin-SCROLLB;
|
|
scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
|
|
scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
|
|
di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
|
|
|
|
y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
|
|
|
|
for (chan=act->chanbase.first; chan; chan=chan->next){
|
|
int frame1_x, channel_y;
|
|
|
|
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
|
|
|
|
glEnable(GL_BLEND);
|
|
if (chan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x22);
|
|
else glColor4b(col2[0], col2[1], col2[2], 0x22);
|
|
glRectf(0, channel_y-CHANNELHEIGHT/2, frame1_x, channel_y+CHANNELHEIGHT/2);
|
|
|
|
if (chan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x44);
|
|
else glColor4b(col2[0], col2[1], col2[2], 0x44);
|
|
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
|
|
glDisable(GL_BLEND);
|
|
|
|
draw_ipo_channel(di, chan->ipo, 0, y);
|
|
|
|
/* Increment the step */
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
|
|
|
|
/* Draw constraint channels */
|
|
for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
|
|
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
|
|
glEnable(GL_BLEND);
|
|
if (conchan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x22);
|
|
else glColor4b(col2[0], col2[1], col2[2], 0x22);
|
|
glRectf(0, channel_y-CHANNELHEIGHT/2+4, frame1_x, channel_y+CHANNELHEIGHT/2-4);
|
|
|
|
if (conchan->flag & ACHAN_SELECTED) glColor4b(col1[0], col1[1], col1[2], 0x44);
|
|
else glColor4b(col2[0], col2[1], col2[2], 0x44);
|
|
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
|
|
glDisable(GL_BLEND);
|
|
|
|
draw_ipo_channel(di, conchan->ipo, 0, y);
|
|
y-=CHANNELHEIGHT+CHANNELSKIP;
|
|
}
|
|
}
|
|
|
|
glaEnd2DDraw(di);
|
|
}
|
|
|
|
static void draw_mesh_strips(SpaceAction *saction, Key *key)
|
|
{
|
|
/* draw the RVK keyframes as those little square button things
|
|
*/
|
|
rcti scr_rct;
|
|
gla2DDrawInfo *di;
|
|
float y, ybase;
|
|
IpoCurve *icu;
|
|
char col1[3], col2[3];
|
|
|
|
BIF_GetThemeColor3ubv(TH_SHADE2, col2);
|
|
BIF_GetThemeColor3ubv(TH_HILITE, col1);
|
|
|
|
if (!key->ipo) return;
|
|
|
|
scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
|
|
scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin-SCROLLB;
|
|
scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
|
|
scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
|
|
di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
|
|
|
|
ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
|
|
|
|
for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
|
|
|
|
int frame1_x, channel_y;
|
|
|
|
/* lets not deal with the "speed" Ipo
|
|
*/
|
|
if (icu->adrcode==0) continue;
|
|
|
|
y = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
|
|
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
|
|
|
|
/* all frames that have a frame number less than one
|
|
* get a desaturated orange background
|
|
*/
|
|
glEnable(GL_BLEND);
|
|
glColor4b(col2[0], col2[1], col2[2], 0x22);
|
|
glRectf(0, channel_y-CHANNELHEIGHT/2,
|
|
frame1_x, channel_y+CHANNELHEIGHT/2);
|
|
|
|
/* frames one and higher get a saturated orange background
|
|
*/
|
|
glColor4b(col2[0], col2[1], col2[2], 0x44);
|
|
glRectf(frame1_x, channel_y-CHANNELHEIGHT/2,
|
|
G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
|
|
glDisable(GL_BLEND);
|
|
|
|
/* draw the little squares
|
|
*/
|
|
draw_icu_channel(di, icu, 0, y);
|
|
}
|
|
|
|
glaEnd2DDraw(di);
|
|
}
|
|
|
|
/* ********* action panel *********** */
|
|
|
|
|
|
void do_actionbuts(unsigned short event)
|
|
{
|
|
switch(event) {
|
|
case REDRAWVIEW3D:
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
break;
|
|
case B_REDR:
|
|
allqueue(REDRAWACTION, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
|
|
{
|
|
uiBlock *block;
|
|
|
|
block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
|
|
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
|
|
uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc
|
|
if(uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0) return;
|
|
|
|
uiDefBut(block, LABEL, 0, "test text", 10,180,300,19, 0, 0, 0, 0, 0, "");
|
|
|
|
}
|
|
|
|
static void action_blockhandlers(ScrArea *sa)
|
|
{
|
|
SpaceAction *sact= sa->spacedata.first;
|
|
short a;
|
|
|
|
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
|
|
switch(sact->blockhandler[a]) {
|
|
|
|
case ACTION_HANDLER_PROPERTIES:
|
|
action_panel_properties(sact->blockhandler[a+1]);
|
|
break;
|
|
|
|
}
|
|
/* clear action value for event */
|
|
sact->blockhandler[a+1]= 0;
|
|
}
|
|
uiDrawBlocksPanels(sa, 0);
|
|
}
|
|
|
|
void drawactionspace(ScrArea *sa, void *spacedata)
|
|
{
|
|
short ofsx = 0, ofsy = 0;
|
|
Key *key;
|
|
float col[3];
|
|
short maxymin;
|
|
|
|
if (!G.saction)
|
|
return;
|
|
|
|
/* warning; blocks need to be freed each time, handlers dont remove */
|
|
uiFreeBlocksWin(&sa->uiblocks, sa->win);
|
|
|
|
if (!G.saction->pin) {
|
|
if (OBACT)
|
|
G.saction->action = OBACT->action;
|
|
else
|
|
G.saction->action=NULL;
|
|
}
|
|
key = get_action_mesh_key();
|
|
|
|
/* Damn I hate hunting to find my rvk's because
|
|
* they have scrolled off of the screen ... this
|
|
* oughta fix it
|
|
*/
|
|
|
|
if (key) {
|
|
if (G.v2d->cur.ymin < -CHANNELHEIGHT)
|
|
G.v2d->cur.ymin = -CHANNELHEIGHT;
|
|
|
|
maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
|
|
if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
|
|
}
|
|
|
|
/* Lets make sure the width of the left hand of the screen
|
|
* is set to an appropriate value based on whether sliders
|
|
* are showing of not
|
|
*/
|
|
if (key && showsliders) ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
|
|
else ACTWIDTH = NAMEWIDTH;
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
|
|
|
|
calc_scrollrcts(G.v2d, curarea->winx, curarea->winy);
|
|
|
|
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
|
|
if(G.v2d->scroll) {
|
|
ofsx= curarea->winrct.xmin;
|
|
ofsy= curarea->winrct.ymin;
|
|
glViewport(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin,
|
|
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
|
|
( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
|
|
glScissor(ofsx+G.v2d->mask.xmin, ofsy+G.v2d->mask.ymin,
|
|
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
|
|
( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
|
|
}
|
|
}
|
|
|
|
BIF_GetThemeColor3fv(TH_BACK, col);
|
|
glClearColor(col[0], col[1], col[2], 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
|
|
bwin_clear_viewmat(sa->win); /* clear buttons view */
|
|
glLoadIdentity();
|
|
|
|
/* Draw backdrop */
|
|
calc_ipogrid();
|
|
draw_ipogrid();
|
|
|
|
/* Draw channel strips */
|
|
draw_channel_strips(G.saction);
|
|
|
|
if (key) {
|
|
/* if there is a mesh with rvk's selected,
|
|
* then draw the key frames in the action window
|
|
*/
|
|
draw_mesh_strips(G.saction, key);
|
|
/*meshactionbuts(G.saction, key);*/
|
|
}
|
|
|
|
|
|
/* Draw current frame */
|
|
glViewport(ofsx+G.v2d->mask.xmin,
|
|
ofsy+G.v2d->mask.ymin,
|
|
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
|
|
( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
|
|
glScissor(ofsx+G.v2d->mask.xmin,
|
|
ofsy+G.v2d->mask.ymin,
|
|
( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1,
|
|
( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
|
|
myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
|
|
draw_cfra_action();
|
|
|
|
/* Draw scroll */
|
|
mywinset(curarea->win); // reset scissor too
|
|
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
|
|
myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
|
|
if(G.v2d->scroll) drawscroll(0);
|
|
}
|
|
|
|
/* Draw channel names */
|
|
draw_channel_names();
|
|
|
|
if ( key ) {
|
|
/* if there is a mesh with rvk's selected,
|
|
* then draw the key frames in the action window
|
|
*/
|
|
meshactionbuts(G.saction, key);
|
|
}
|
|
|
|
mywinset(curarea->win); // reset scissor too
|
|
myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
|
|
draw_area_emboss(sa);
|
|
|
|
/* it is important to end a view in a transform compatible with buttons */
|
|
bwin_scalematrix(sa->win, G.saction->blockscale, G.saction->blockscale, G.saction->blockscale);
|
|
action_blockhandlers(sa);
|
|
|
|
curarea->win_swap= WIN_BACK_OK;
|
|
}
|
|
|
|
|
|
void draw_channel_name(const char* name, short type, float ypos, int selected)
|
|
{
|
|
}
|
|
|
|
static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos)
|
|
{
|
|
int v;
|
|
|
|
if (!blist)
|
|
return;
|
|
|
|
for (v = 0; v<totvert; v++){
|
|
if (v==0 || (blist[v]->vec[1][0] != blist[v-1]->vec[1][0])){
|
|
int sc_x, sc_y;
|
|
gla2DDrawTranslatePt(di, blist[v]->vec[1][0], ypos, &sc_x, &sc_y);
|
|
draw_bevel_but(sc_x-2, sc_y-5, 7, 13, (blist[v]->f2 & 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_object_channel(gla2DDrawInfo *di, Object *ob, int flags, float ypos)
|
|
{
|
|
BezTriple **blist;
|
|
int totvert;
|
|
|
|
blist = ob_to_keylist(ob, flags, &totvert);
|
|
if (blist){
|
|
draw_keylist(di,totvert, blist, ypos);
|
|
MEM_freeN(blist);
|
|
}
|
|
}
|
|
|
|
void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos)
|
|
{
|
|
BezTriple **blist;
|
|
int totvert;
|
|
|
|
blist = ipo_to_keylist(ipo, flags, &totvert);
|
|
if (blist){
|
|
draw_keylist(di,totvert, blist, ypos);
|
|
MEM_freeN(blist);
|
|
}
|
|
}
|
|
|
|
void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos)
|
|
{
|
|
/* draw the keys for an IpoCurve
|
|
*/
|
|
BezTriple **blist;
|
|
int totvert;
|
|
|
|
blist = icu_to_keylist(icu, flags, &totvert);
|
|
if (blist){
|
|
draw_keylist(di,totvert, blist, ypos);
|
|
MEM_freeN(blist);
|
|
}
|
|
}
|
|
|
|
void draw_action_channel(gla2DDrawInfo *di, bAction *act, int flags, float ypos)
|
|
{
|
|
BezTriple **blist;
|
|
int totvert;
|
|
|
|
blist = action_to_keylist(act, flags, &totvert);
|
|
if (blist){
|
|
draw_keylist(di,totvert, blist, ypos);
|
|
MEM_freeN(blist);
|
|
}
|
|
}
|
|
|
|
static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert)
|
|
{
|
|
IpoCurve *icu;
|
|
int v, count=0;
|
|
|
|
BezTriple **list = NULL;
|
|
|
|
if (ob){
|
|
|
|
/* Count Object Keys */
|
|
if (ob->ipo){
|
|
for (icu=ob->ipo->curve.first; icu; icu=icu->next){
|
|
count+=icu->totvert;
|
|
}
|
|
}
|
|
|
|
/* Count Constraint Keys */
|
|
/* Count object data keys */
|
|
|
|
/* Build the list */
|
|
if (count){
|
|
list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
|
|
count=0;
|
|
|
|
/* Add object keyframes */
|
|
for (icu=ob->ipo->curve.first; icu; icu=icu->next){
|
|
for (v=0; v<icu->totvert; v++){
|
|
list[count++]=&icu->bezt[v];
|
|
}
|
|
}
|
|
|
|
/* Add constraint keyframes */
|
|
/* Add object data keyframes */
|
|
|
|
/* Sort */
|
|
qsort(list, count, sizeof(BezTriple*), bezt_compare);
|
|
}
|
|
}
|
|
(*totvert)=count;
|
|
return list;
|
|
}
|
|
|
|
static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert)
|
|
{
|
|
/* compile a list of all bezier triples in an
|
|
* IpoCurve.
|
|
*/
|
|
int v, count = 0;
|
|
|
|
BezTriple **list = NULL;
|
|
|
|
count=icu->totvert;
|
|
|
|
if (count){
|
|
list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
|
|
count=0;
|
|
|
|
for (v=0; v<icu->totvert; v++){
|
|
list[count++]=&icu->bezt[v];
|
|
}
|
|
qsort(list, count, sizeof(BezTriple*), bezt_compare);
|
|
}
|
|
(*totvert)=count;
|
|
return list;
|
|
|
|
}
|
|
|
|
static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert)
|
|
{
|
|
IpoCurve *icu;
|
|
int v, count=0;
|
|
|
|
BezTriple **list = NULL;
|
|
|
|
if (ipo){
|
|
/* Count required keys */
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
count+=icu->totvert;
|
|
}
|
|
|
|
/* Build the list */
|
|
if (count){
|
|
list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
|
|
count=0;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (v=0; v<icu->totvert; v++){
|
|
list[count++]=&icu->bezt[v];
|
|
}
|
|
}
|
|
qsort(list, count, sizeof(BezTriple*), bezt_compare);
|
|
}
|
|
}
|
|
(*totvert)=count;
|
|
return list;
|
|
}
|
|
|
|
static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert)
|
|
{
|
|
IpoCurve *icu;
|
|
bActionChannel *achan;
|
|
bConstraintChannel *conchan;
|
|
int v, count=0;
|
|
|
|
BezTriple **list = NULL;
|
|
|
|
if (act){
|
|
/* Count required keys */
|
|
for (achan=act->chanbase.first; achan; achan=achan->next){
|
|
/* Count transformation keys */
|
|
for (icu=achan->ipo->curve.first; icu; icu=icu->next)
|
|
count+=icu->totvert;
|
|
|
|
/* Count constraint keys */
|
|
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
|
|
for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
|
|
count+=icu->totvert;
|
|
|
|
|
|
}
|
|
|
|
/* Build the list */
|
|
if (count){
|
|
list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
|
|
count=0;
|
|
|
|
for (achan=act->chanbase.first; achan; achan=achan->next){
|
|
/* Add transformation keys */
|
|
for (icu=achan->ipo->curve.first; icu; icu=icu->next){
|
|
for (v=0; v<icu->totvert; v++)
|
|
list[count++]=&icu->bezt[v];
|
|
}
|
|
|
|
/* Add constraint keys */
|
|
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
|
|
for (icu=conchan->ipo->curve.first; icu; icu=icu->next)
|
|
for (v=0; v<icu->totvert; v++)
|
|
list[count++]=&icu->bezt[v];
|
|
}
|
|
|
|
}
|
|
qsort(list, count, sizeof(BezTriple*), bezt_compare);
|
|
|
|
}
|
|
}
|
|
(*totvert)=count;
|
|
return list;
|
|
}
|
|
|