|
Blender
V2.59
|
00001 /* 00002 * $Id: action_draw.c 35242 2011-02-27 20:29:51Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Joshua Leung 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 /* System includes ----------------------------------------------------- */ 00036 00037 #include <math.h> 00038 #include <stdlib.h> 00039 #include <string.h> 00040 #include <float.h> 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_utildefines.h" 00045 00046 /* Types --------------------------------------------------------------- */ 00047 00048 #include "DNA_anim_types.h" 00049 #include "DNA_screen_types.h" 00050 00051 #include "BKE_action.h" 00052 #include "BKE_context.h" 00053 00054 00055 /* Everything from source (BIF, BDR, BSE) ------------------------------ */ 00056 00057 #include "BIF_gl.h" 00058 00059 #include "UI_interface.h" 00060 #include "UI_resources.h" 00061 #include "UI_view2d.h" 00062 00063 #include "ED_anim_api.h" 00064 #include "ED_keyframes_draw.h" 00065 00066 #include "action_intern.h" 00067 00068 /* ************************************************************************* */ 00069 /* Channel List */ 00070 00071 /* left hand part */ 00072 void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) 00073 { 00074 ListBase anim_data = {NULL, NULL}; 00075 bAnimListElem *ale; 00076 int filter; 00077 00078 View2D *v2d= &ar->v2d; 00079 float y= 0.0f; 00080 int items, height; 00081 00082 /* build list of channels to draw */ 00083 filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS); 00084 items= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00085 00086 /* Update max-extent of channels here (taking into account scrollers): 00087 * - this is done to allow the channel list to be scrollable, but must be done here 00088 * to avoid regenerating the list again and/or also because channels list is drawn first 00089 * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for 00090 * start of list offset, and the second is as a correction for the scrollers. 00091 */ 00092 height= ((items*ACHANNEL_STEP) + (ACHANNEL_HEIGHT*2)); 00093 if (height > (v2d->mask.ymax - v2d->mask.ymin)) { 00094 /* don't use totrect set, as the width stays the same 00095 * (NOTE: this is ok here, the configuration is pretty straightforward) 00096 */ 00097 v2d->tot.ymin= (float)(-height); 00098 } 00099 /* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */ 00100 UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY); 00101 00102 /* loop through channels, and set up drawing depending on their type */ 00103 { /* first pass: just the standard GL-drawing for backdrop + text */ 00104 y= (float)ACHANNEL_FIRST; 00105 00106 for (ale= anim_data.first; ale; ale= ale->next) { 00107 float yminc= (float)(y - ACHANNEL_HEIGHT_HALF); 00108 float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF); 00109 00110 /* check if visible */ 00111 if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || 00112 IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) 00113 { 00114 /* draw all channels using standard channel-drawing API */ 00115 ANIM_channel_draw(ac, ale, yminc, ymaxc); 00116 } 00117 00118 /* adjust y-position for next one */ 00119 y -= ACHANNEL_STEP; 00120 } 00121 } 00122 { /* second pass: widgets */ 00123 uiBlock *block= uiBeginBlock(C, ar, "dopesheet channel buttons", UI_EMBOSS); 00124 00125 y= (float)ACHANNEL_FIRST; 00126 00127 for (ale= anim_data.first; ale; ale= ale->next) { 00128 float yminc= (float)(y - ACHANNEL_HEIGHT_HALF); 00129 float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF); 00130 00131 /* check if visible */ 00132 if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || 00133 IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) 00134 { 00135 /* draw all channels using standard channel-drawing API */ 00136 ANIM_channel_draw_widgets(ac, ale, block, yminc, ymaxc); 00137 } 00138 00139 /* adjust y-position for next one */ 00140 y -= ACHANNEL_STEP; 00141 } 00142 00143 uiEndBlock(C, block); 00144 uiDrawBlock(C, block); 00145 } 00146 00147 /* free tempolary channels */ 00148 BLI_freelistN(&anim_data); 00149 } 00150 00151 /* ************************************************************************* */ 00152 /* Keyframes */ 00153 00154 /* extra padding for lengths (to go under scrollers) */ 00155 #define EXTRA_SCROLL_PAD 100.0f 00156 00157 /* draw keyframes in each channel */ 00158 void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) 00159 { 00160 ListBase anim_data = {NULL, NULL}; 00161 bAnimListElem *ale; 00162 int filter; 00163 00164 View2D *v2d= &ar->v2d; 00165 bDopeSheet *ads= &saction->ads; 00166 AnimData *adt= NULL; 00167 00168 float act_start, act_end, y; 00169 int height, items; 00170 00171 unsigned char col1[3], col2[3]; 00172 unsigned char col1a[3], col2a[3]; 00173 unsigned char col1b[3], col2b[3]; 00174 00175 00176 /* get theme colors */ 00177 UI_GetThemeColor3ubv(TH_BACK, col2); 00178 UI_GetThemeColor3ubv(TH_HILITE, col1); 00179 00180 UI_GetThemeColor3ubv(TH_GROUP, col2a); 00181 UI_GetThemeColor3ubv(TH_GROUP_ACTIVE, col1a); 00182 00183 UI_GetThemeColor3ubv(TH_DOPESHEET_CHANNELOB, col1b); 00184 UI_GetThemeColor3ubv(TH_DOPESHEET_CHANNELSUBOB, col2b); 00185 00186 /* set view-mapping rect (only used for x-axis), for NLA-scaling mapping with less calculation */ 00187 00188 /* if in NLA there's a strip active, map the view */ 00189 if (ac->datatype == ANIMCONT_ACTION) { 00190 adt= ANIM_nla_mapping_get(ac, NULL); 00191 00192 /* start and end of action itself */ 00193 calc_action_range(ac->data, &act_start, &act_end, 0); 00194 } 00195 00196 /* build list of channels to draw */ 00197 filter= (ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS); 00198 items= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); 00199 00200 /* Update max-extent of channels here (taking into account scrollers): 00201 * - this is done to allow the channel list to be scrollable, but must be done here 00202 * to avoid regenerating the list again and/or also because channels list is drawn first 00203 * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for 00204 * start of list offset, and the second is as a correction for the scrollers. 00205 */ 00206 height= ((items*ACHANNEL_STEP) + (ACHANNEL_HEIGHT*2)); 00207 /* don't use totrect set, as the width stays the same 00208 * (NOTE: this is ok here, the configuration is pretty straightforward) 00209 */ 00210 v2d->tot.ymin= (float)(-height); 00211 00212 /* first backdrop strips */ 00213 y= (float)(-ACHANNEL_HEIGHT); 00214 glEnable(GL_BLEND); 00215 00216 for (ale= anim_data.first; ale; ale= ale->next) { 00217 const float yminc= (float)(y - ACHANNEL_HEIGHT_HALF); 00218 const float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF); 00219 00220 /* check if visible */ 00221 if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || 00222 IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) 00223 { 00224 bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale); 00225 int sel=0; 00226 00227 /* determine if any need to draw channel */ 00228 if (ale->datatype != ALE_NONE) { 00229 /* determine if channel is selected */ 00230 if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) 00231 sel= ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT); 00232 00233 if (ELEM3(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_SHAPEKEY)) { 00234 switch (ale->type) { 00235 case ANIMTYPE_SUMMARY: 00236 { 00237 // FIXME: hardcoded colors - reddish color from NLA 00238 glColor4f(0.8f, 0.2f, 0.0f, 0.4f); 00239 } 00240 break; 00241 00242 case ANIMTYPE_SCENE: 00243 case ANIMTYPE_OBJECT: 00244 { 00245 if (sel) glColor4ub(col1b[0], col1b[1], col1b[2], 0x45); 00246 else glColor4ub(col1b[0], col1b[1], col1b[2], 0x22); 00247 } 00248 break; 00249 00250 case ANIMTYPE_FILLACTD: 00251 case ANIMTYPE_FILLMATD: 00252 case ANIMTYPE_FILLPARTD: 00253 case ANIMTYPE_DSSKEY: 00254 case ANIMTYPE_DSWOR: 00255 { 00256 if (sel) glColor4ub(col2b[0], col2b[1], col2b[2], 0x45); 00257 else glColor4ub(col2b[0], col2b[1], col2b[2], 0x22); 00258 } 00259 break; 00260 00261 case ANIMTYPE_GROUP: 00262 { 00263 if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22); 00264 else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22); 00265 } 00266 break; 00267 00268 default: 00269 { 00270 if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22); 00271 else glColor4ub(col2[0], col2[1], col2[2], 0x22); 00272 } 00273 break; 00274 } 00275 00276 /* draw region twice: firstly backdrop, then the current range */ 00277 glRectf(v2d->cur.xmin, (float)y-ACHANNEL_HEIGHT_HALF, v2d->cur.xmax+EXTRA_SCROLL_PAD, (float)y+ACHANNEL_HEIGHT_HALF); 00278 00279 if (ac->datatype == ANIMCONT_ACTION) 00280 glRectf(act_start, (float)y-ACHANNEL_HEIGHT_HALF, act_end, (float)y+ACHANNEL_HEIGHT_HALF); 00281 } 00282 else if (ac->datatype == ANIMCONT_GPENCIL) { 00283 /* frames less than one get less saturated background */ 00284 if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22); 00285 else glColor4ub(col2[0], col2[1], col2[2], 0x22); 00286 glRectf(0.0f, (float)y-ACHANNEL_HEIGHT_HALF, v2d->cur.xmin, (float)y+ACHANNEL_HEIGHT_HALF); 00287 00288 /* frames one and higher get a saturated background */ 00289 if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44); 00290 else glColor4ub(col2[0], col2[1], col2[2], 0x44); 00291 glRectf(v2d->cur.xmin, (float)y-ACHANNEL_HEIGHT_HALF, v2d->cur.xmax+EXTRA_SCROLL_PAD, (float)y+ACHANNEL_HEIGHT_HALF); 00292 } 00293 } 00294 } 00295 00296 /* Increment the step */ 00297 y -= ACHANNEL_STEP; 00298 } 00299 glDisable(GL_BLEND); 00300 00301 /* Draw keyframes 00302 * 1) Only channels that are visible in the Action Editor get drawn/evaluated. 00303 * This is to try to optimise this for heavier data sets 00304 * 2) Keyframes which are out of view horizontally are disregarded 00305 */ 00306 y= (float)(-ACHANNEL_HEIGHT); 00307 00308 for (ale= anim_data.first; ale; ale= ale->next) { 00309 const float yminc= (float)(y - ACHANNEL_HEIGHT_HALF); 00310 const float ymaxc= (float)(y + ACHANNEL_HEIGHT_HALF); 00311 00312 /* check if visible */ 00313 if ( IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || 00314 IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) 00315 { 00316 /* check if anything to show for this channel */ 00317 if (ale->datatype != ALE_NONE) { 00318 adt= ANIM_nla_mapping_get(ac, ale); 00319 00320 /* draw 'keyframes' for each specific datatype */ 00321 switch (ale->datatype) { 00322 case ALE_ALL: 00323 draw_summary_channel(v2d, ale->data, y); 00324 break; 00325 case ALE_SCE: 00326 draw_scene_channel(v2d, ads, ale->key_data, y); 00327 break; 00328 case ALE_OB: 00329 draw_object_channel(v2d, ads, ale->key_data, y); 00330 break; 00331 case ALE_ACT: 00332 draw_action_channel(v2d, adt, ale->key_data, y); 00333 break; 00334 case ALE_GROUP: 00335 draw_agroup_channel(v2d, adt, ale->data, y); 00336 break; 00337 case ALE_FCURVE: 00338 draw_fcurve_channel(v2d, adt, ale->key_data, y); 00339 break; 00340 case ALE_GPFRAME: 00341 draw_gpl_channel(v2d, ads, ale->data, y); 00342 break; 00343 } 00344 } 00345 } 00346 00347 y-= ACHANNEL_STEP; 00348 } 00349 00350 /* free tempolary channels used for drawing */ 00351 BLI_freelistN(&anim_data); 00352 00353 /* black line marking 'current frame' for Time-Slide transform mode */ 00354 if (saction->flag & SACTION_MOVING) { 00355 glColor3f(0.0f, 0.0f, 0.0f); 00356 00357 glBegin(GL_LINES); 00358 glVertex2f(saction->timeslide, v2d->cur.ymin-EXTRA_SCROLL_PAD); 00359 glVertex2f(saction->timeslide, v2d->cur.ymax); 00360 glEnd(); 00361 } 00362 }