This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/src/drawnla.c
Daniel Dunbar 1f3f52f5e4 Update space dispatch:
- drawXXXspace, changeXXXspace, and winqreadXXXspace now receive the area
     and spacedata as explicit arguments, allowing them to access private
     data w/o going through globals.
 - pass the new BWinEvent through to the winqreadXXXspace, allowing future
     access to extended event data.

Removed direct calls to winqreadXXXspace to simulate user actions, replaced
by calls to action functions in edit.c or the appropriate handler.
2003-03-24 01:46:05 +00:00

528 lines
14 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 *****
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef _WIN32
#pragma warning (once : 4761)
#include "BLI_winstuff.h"
#endif
#include "BMF_Api.h"
#include <stdlib.h>
#include <stdio.h>
#include "BSE_drawnla.h"
#include "BSE_drawipo.h"
#include "BSE_editnla_types.h"
#include "BIF_gl.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_mywindow.h"
#include "BIF_glutil.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_action_types.h"
#include "DNA_nla_types.h"
#include "DNA_constraint_types.h"
#include "BLI_blenlib.h"
#include "MEM_guardedalloc.h"
#include "BKE_global.h"
#include "BDR_drawaction.h"
#include "BDR_editcurve.h"
#include "blendef.h"
#include "interface.h"
/* Local function prototypes */
static void draw_nlastrips(SpaceNla *snla);
static void draw_nlatree(void);
int count_nla_levels(void);
int nla_filter (Base* base, int flags);
#define TESTBASE_SAFE(base) ((base)->flag & SELECT)
/* Implementation */
static void draw_nlatree(void)
{
short ofsx, ofsy = 0;
Base *base;
float x, y;
bActionStrip *strip;
bConstraintChannel *conchan;
myortho2 (0, NLAWIDTH, 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, NLAWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));
glScissor(ofsx, ofsy+G.v2d->mask.ymin-SCROLLB, NLAWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));
}
}
glClearColor(.6, .6, .6, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* Clip to the scrollable area */
glColor3ub(0x00, 0x00, 0x00);
x = 0.0;
y = count_nla_levels();
y*= (NLACHANNELHEIGHT+NLACHANNELSKIP);
for (base=G.scene->base.first; base; base=base->next){
if (nla_filter(base, 0)){
cpack (0xAAAAAA);
glRectf(x, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2);
/* Draw the name / ipo timeline*/
if (TESTBASE_SAFE(base))
cpack(0xFFFFFF);
else
cpack (0x000000);
glRasterPos2f(x+16, y-4);
BMF_DrawString(G.font, base->object->id.name+2);
/* Draw the constraint ipos */
for (conchan = base->object->constraintChannels.first; conchan; conchan=conchan->next){
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
cpack (0x888888);
glRectf(x+16, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2);
if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
cpack(0xFFFFFF);
else
cpack (0x000000);
glRasterPos2f(x+32, y-4);
BMF_DrawString(G.font, conchan->name);
}
/* Draw the action timeline */
if (ACTIVE_ARMATURE(base)){
glRasterPos2f(x, y-8);
BIF_draw_icon(ICON_DOWNARROW_HLT);
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
if (base->object->action){
cpack (0x888888);
glRectf(x+16, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2);
if (TESTBASE_SAFE(base))
cpack(0xFFFFFF);
else
cpack (0x000000);
glRasterPos2f(x+32, y-4);
BMF_DrawString(G.font, base->object->action->id.name+2);
}
}
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
/* Draw the nla strips */
if (base->object->type==OB_ARMATURE){
for (strip = base->object->nlastrips.first; strip; strip=strip->next){
cpack (0x666666);
glRectf(x+32, y-NLACHANNELHEIGHT/2, (float)NLAWIDTH, y+NLACHANNELHEIGHT/2);
if (TESTBASE_SAFE(base))
cpack(0xFFFFFF);
else
cpack (0x000000);
glRasterPos2f(x+48, y-4);
BMF_DrawString(G.font, strip->act->id.name+2);
y-=(NLACHANNELHEIGHT+NLACHANNELSKIP);
}
}
}
}
myortho2 (0, NLAWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); // Scaling
glShadeModel(GL_SMOOTH);
y=9;
#if 1
/* Draw sexy shaded block thingies */
glEnable (GL_BLEND);
glBegin(GL_QUAD_STRIP);
glColor4ub (0x99,0x99,0x99,0x00);
glVertex2f (0,SCROLLB*2-y);
glVertex2f (NLAWIDTH,SCROLLB*2-y);
glColor4ub (0x99,0x99,0x99,0xFF);
glVertex2f (0,SCROLLB-y);
glVertex2f (NLAWIDTH,SCROLLB-y);
glColor4ub (0x99,0x99,0x99,0xFF);
glVertex2f (0,0-y);
glVertex2f (NLAWIDTH,0-y);
glEnd();
glDisable (GL_BLEND);
#endif
glShadeModel(GL_FLAT);
}
static void draw_nlastrips(SpaceNla *snla)
{
rcti scr_rct;
gla2DDrawInfo *di;
Base *base;
bConstraintChannel *conchan;
float y;
/* Draw strips */
scr_rct.xmin= snla->area->winrct.xmin + NLAWIDTH;
scr_rct.ymin= snla->area->winrct.ymin + snla->v2d.mask.ymin-SCROLLB;
scr_rct.xmax= snla->area->winrct.xmin + snla->v2d.hor.xmax;
scr_rct.ymax= snla->area->winrct.ymin + snla->v2d.mask.ymax;
di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
y=count_nla_levels();
y*= (NLACHANNELHEIGHT+NLACHANNELSKIP);
for (base=G.scene->base.first; base; base=base->next){
Object *ob;
bActionStrip *strip;
int frame1_x, channel_y;
ob=base->object;
if (nla_filter(base, 0)){
/* Draw the field */
glEnable (GL_BLEND);
if (TESTBASE_SAFE(base))
glColor4b (0x11, 0x22, 0x55, 0x22);
else
glColor4b (0x55, 0x22, 0x11, 0x22);
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
glRectf(0, channel_y-NLACHANNELHEIGHT/2, frame1_x, channel_y+NLACHANNELHEIGHT/2);
if (TESTBASE_SAFE(base))
glColor4b (0x11, 0x22, 0x55, 0x44);
else
glColor4b (0x55, 0x22, 0x11, 0x44);
glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2);
glDisable (GL_BLEND);
/* Draw the ipo */
draw_object_channel(di, ob, 0, y);
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
/* Draw the constraints */
for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){
glEnable (GL_BLEND);
if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
glColor4b (0x11, 0x22, 0x55, 0x22);
else
glColor4b (0x55, 0x22, 0x11, 0x22);
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
glRectf(0, channel_y-NLACHANNELHEIGHT/2+4, frame1_x, channel_y+NLACHANNELHEIGHT/2-4);
if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
glColor4b (0x11, 0x22, 0x55, 0x44);
else
glColor4b (0x55, 0x22, 0x11, 0x44);
glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-4);
glDisable (GL_BLEND);
/* Draw the ipo */
draw_ipo_channel(di, conchan->ipo, 0, y);
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
}
}
/* Draw the action strip */
if (ACTIVE_ARMATURE(base)){
/* Draw the field */
glEnable (GL_BLEND);
if (TESTBASE_SAFE(base))
glColor4ub (0x11, 0x22, 0x55, 0x22);
else
glColor4ub (0x55, 0x22, 0x11, 0x22);
gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
glRectf(0, channel_y-NLACHANNELHEIGHT/2+4, frame1_x, channel_y+NLACHANNELHEIGHT/2-4);
if (TESTBASE_SAFE(base))
glColor4ub (0x11, 0x22, 0x55, 0x44);
else
glColor4ub (0x55, 0x22, 0x11, 0x44);
glRectf(frame1_x, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-4);
glDisable (GL_BLEND);
/* Draw the action keys */
draw_action_channel(di, ob->action, 0, y);
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
}
/* Draw the nla strips */
if (ob->type==OB_ARMATURE){
for (strip=ob->nlastrips.first; strip; strip=strip->next){
int stripstart, stripend;
int blendstart, blendend;
unsigned char r,g,b;
/* Draw rect */
if (strip->flag & ACTSTRIP_SELECT){
r = 0xFF; g=0xFF; b=0xAA;
}
else{
r = 0xE4; g=0x9C; b=0xC6;
}
glColor4ub (r, g, b, 0xFF);
gla2DDrawTranslatePt(di, strip->start+strip->blendin, y, &stripstart, &channel_y);
gla2DDrawTranslatePt(di, strip->end-strip->blendout, y, &stripend, &channel_y);
glRectf(stripstart, channel_y-NLACHANNELHEIGHT/2+3, stripend, channel_y+NLACHANNELHEIGHT/2-3);
/* Draw blendin */
if (strip->blendin>0){
glBegin(GL_TRIANGLES);
gla2DDrawTranslatePt(di, strip->start, y, &blendstart, &channel_y);
glColor4ub (r*0.75, g*0.75, b*0.75, 0xFF);
glVertex2f(blendstart, channel_y-NLACHANNELHEIGHT/2+3);
glVertex2f(stripstart, channel_y+NLACHANNELHEIGHT/2-3);
glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3);
glEnd();
}
if (strip->blendout>0){
glBegin(GL_TRIANGLES);
gla2DDrawTranslatePt(di, strip->end, y, &blendend, &channel_y);
glColor4ub (r*0.75, g*0.75, b*0.75, 0xFF);
glVertex2f(blendend, channel_y-NLACHANNELHEIGHT/2+3);
glVertex2f(stripend, channel_y+NLACHANNELHEIGHT/2-3);
glVertex2f(stripend, channel_y-NLACHANNELHEIGHT/2+3);
glEnd();
}
/* Draw border */
glBegin(GL_LINE_STRIP);
glColor4f(1, 1, 1, 0.5);
gla2DDrawTranslatePt(di, strip->start, y, &stripstart, &channel_y);
gla2DDrawTranslatePt(di, strip->end, y, &stripend, &channel_y);
glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3);
glVertex2f(stripstart, channel_y+NLACHANNELHEIGHT/2-3);
glVertex2f(stripend, channel_y+NLACHANNELHEIGHT/2-3);
glColor4f(0, 0, 0, 0.5);
glVertex2f(stripend, channel_y-NLACHANNELHEIGHT/2+3);
glVertex2f(stripstart, channel_y-NLACHANNELHEIGHT/2+3);
glEnd();
glEnable (GL_BLEND);
/* Show strip extension */
if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
glColor4ub (r, g, b, 0x55);
glRectf(stripend, channel_y-NLACHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+NLACHANNELHEIGHT/2-2);
}
/* Show repeat */
if (strip->repeat > 1.0 && !(strip->flag & ACTSTRIP_USESTRIDE)){
float rep = 1;
glBegin(GL_LINES);
while (rep<strip->repeat){
/* Draw line */
glColor4f(0, 0, 0, 0.5);
gla2DDrawTranslatePt(di, strip->start+(rep*((strip->end-strip->start)/strip->repeat)), y, &frame1_x, &channel_y);
glVertex2f(frame1_x, channel_y-NLACHANNELHEIGHT/2+4);
glVertex2f(frame1_x, channel_y+NLACHANNELHEIGHT/2-2);
glColor4f(1.0, 1.0, 1.0, 0.5);
gla2DDrawTranslatePt(di, strip->start+(rep*((strip->end-strip->start)/strip->repeat)), y, &frame1_x, &channel_y);
glVertex2f(frame1_x+1, channel_y-NLACHANNELHEIGHT/2+4);
glVertex2f(frame1_x+1, channel_y+NLACHANNELHEIGHT/2-2);
rep+=1.0;
}
glEnd();
}
glDisable (GL_BLEND);
y-=(NLACHANNELHEIGHT+NLACHANNELSKIP);
}
}
}
glaEnd2DDraw(di);
}
void drawnlaspace(ScrArea *sa, void *spacedata)
{
short ofsx = 0, ofsy = 0;
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);
}
}
glClearColor(.45, .45, .45, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
/* Draw backdrop */
calc_ipogrid();
draw_ipogrid();
/* Draw channel strips */
draw_nlastrips(G.snla);
/* 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);
if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
if(G.v2d->scroll) drawscroll(0);
}
/* Draw channel names */
draw_nlatree();
curarea->win_swap= WIN_BACK_OK;
}
int count_nla_levels(void)
{
Base *base;
int y=0;
for (y=0, base=G.scene->base.first; base; base=base->next)
{
if (nla_filter(base,0 )){
/* Ipo */
y++;
/* Constraint channels */
y+=BLI_countlist(&base->object->constraintChannels);
if (base->object->type==OB_ARMATURE){
/* Action */
if(base->object->action){
// bActionChannel *achan;
y++;
// for (achan=base->object->action->chanbase.first; achan; achan=achan->next){
// y+=BLI_countlist(&achan->constraintChannels);
// }
}
/* Nla strips */
y+= BLI_countlist(&base->object->nlastrips);
}
}
}
return y;
}
int nla_filter (Base* base, int flags)
{
Object *ob = base->object;
/* Only objects with ipos */
if (ob->ipo)
return 1;
if (ob->constraintChannels.first)
return 1;
/* Only armatures */
if (ob->type==OB_ARMATURE)
return 1;
else return 0;
}