Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <math.h> 00033 00034 #include "MEM_guardedalloc.h" 00035 00036 #include "DNA_scene_types.h" 00037 #include "DNA_object_types.h" 00038 00039 #include "RNA_access.h" 00040 #include "RNA_define.h" 00041 #include "RNA_enum_types.h" 00042 00043 #include "BLI_blenlib.h" 00044 #include "BLI_utildefines.h" 00045 00046 #include "BKE_context.h" 00047 #include "BKE_fcurve.h" 00048 #include "BKE_main.h" 00049 #include "BKE_report.h" 00050 #include "BKE_scene.h" 00051 #include "BKE_screen.h" 00052 00053 #include "WM_api.h" 00054 #include "WM_types.h" 00055 00056 #include "BIF_gl.h" 00057 #include "BIF_glutil.h" 00058 00059 #include "UI_interface.h" 00060 #include "UI_interface_icons.h" 00061 #include "UI_view2d.h" 00062 #include "UI_resources.h" 00063 00064 #include "ED_anim_api.h" 00065 #include "ED_markers.h" 00066 #include "ED_screen.h" 00067 #include "ED_util.h" 00068 #include "ED_numinput.h" 00069 #include "ED_object.h" 00070 #include "ED_transform.h" 00071 #include "ED_types.h" 00072 00073 /* ************* Marker API **************** */ 00074 00075 /* helper function for getting the list of markers to work on */ 00076 static ListBase *context_get_markers(Scene *scene, ScrArea *sa) 00077 { 00078 /* local marker sets... */ 00079 if (sa) { 00080 if (sa->spacetype == SPACE_ACTION) { 00081 SpaceAction *saction = (SpaceAction *)sa->spacedata.first; 00082 00083 /* local markers can only be shown when there's only a single active action to grab them from 00084 * - flag only takes effect when there's an action, otherwise it can get too confusing? 00085 */ 00086 if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) 00087 { 00088 if (saction->flag & SACTION_POSEMARKERS_SHOW) 00089 return &saction->action->markers; 00090 } 00091 } 00092 } 00093 00094 /* default to using the scene's markers */ 00095 return &scene->markers; 00096 } 00097 00098 /* ............. */ 00099 00100 /* public API for getting markers from context */ 00101 ListBase *ED_context_get_markers(const bContext *C) 00102 { 00103 return context_get_markers(CTX_data_scene(C), CTX_wm_area(C)); 00104 } 00105 00106 /* public API for getting markers from "animation" context */ 00107 ListBase *ED_animcontext_get_markers(const bAnimContext *ac) 00108 { 00109 if (ac) 00110 return context_get_markers(ac->scene, ac->sa); 00111 else 00112 return NULL; 00113 } 00114 00115 /* --------------------------------- */ 00116 00117 /* Apply some transformation to markers after the fact 00118 * < markers: list of markers to affect - this may or may not be the scene markers list, so don't assume anything 00119 * < scene: current scene (for getting current frame) 00120 * < mode: (TfmMode) transform mode that this transform is for 00121 * < value: from the transform code, this is t->vec[0] (which is delta transform for grab/extend, and scale factor for scale) 00122 * < side: (B/L/R) for 'extend' functionality, which side of current frame to use 00123 */ 00124 int ED_markers_post_apply_transform (ListBase *markers, Scene *scene, int mode, float value, char side) 00125 { 00126 TimeMarker *marker; 00127 float cfra = (float)CFRA; 00128 int changed = 0; 00129 00130 /* sanity check */ 00131 if (markers == NULL) 00132 return changed; 00133 00134 /* affect selected markers - it's unlikely that we will want to affect all in this way? */ 00135 for (marker = markers->first; marker; marker = marker->next) { 00136 if (marker->flag & SELECT) { 00137 switch (mode) { 00138 case TFM_TIME_TRANSLATE: 00139 case TFM_TIME_EXTEND: 00140 { 00141 /* apply delta if marker is on the right side of the current frame */ 00142 if ((side=='B') || 00143 (side=='L' && marker->frame < cfra) || 00144 (side=='R' && marker->frame >= cfra)) 00145 { 00146 marker->frame += (int)floorf(value + 0.5f); 00147 changed++; 00148 } 00149 } 00150 break; 00151 00152 case TFM_TIME_SCALE: 00153 { 00154 /* rescale the distance between the marker and the current frame */ 00155 marker->frame= cfra + (int)floorf(((float)(marker->frame - cfra) * value) + 0.5f); 00156 changed++; 00157 } 00158 break; 00159 } 00160 } 00161 } 00162 00163 return changed; 00164 } 00165 00166 /* --------------------------------- */ 00167 00168 /* Get the marker that is closest to this point */ 00169 /* XXX for select, the min_dist should be small */ 00170 TimeMarker *ED_markers_find_nearest_marker (ListBase *markers, float x) 00171 { 00172 TimeMarker *marker, *nearest=NULL; 00173 float dist, min_dist= 1000000; 00174 00175 if (markers) { 00176 for (marker= markers->first; marker; marker= marker->next) { 00177 dist = ABS((float)marker->frame - x); 00178 00179 if (dist < min_dist) { 00180 min_dist= dist; 00181 nearest= marker; 00182 } 00183 } 00184 } 00185 00186 return nearest; 00187 } 00188 00189 /* Return the time of the marker that occurs on a frame closest to the given time */ 00190 int ED_markers_find_nearest_marker_time (ListBase *markers, float x) 00191 { 00192 TimeMarker *nearest= ED_markers_find_nearest_marker(markers, x); 00193 return (nearest) ? (nearest->frame) : (int)floor(x + 0.5f); 00194 } 00195 00196 00197 void ED_markers_get_minmax (ListBase *markers, short sel, float *first, float *last) 00198 { 00199 TimeMarker *marker; 00200 float min, max; 00201 int selcount = 0; 00202 00203 /* sanity check */ 00204 //printf("markers = %p - %p, %p \n", markers, markers->first, markers->last); 00205 if (markers == NULL) { 00206 *first = 0.0f; 00207 *last = 0.0f; 00208 return; 00209 } 00210 00211 if (markers->first && markers->last) { 00212 TimeMarker *fm= markers->first; 00213 TimeMarker *lm= markers->last; 00214 00215 min= (float)fm->frame; 00216 max= (float)lm->frame; 00217 } 00218 else { 00219 *first = 0.0f; 00220 *last = 0.0f; 00221 return; 00222 } 00223 00224 /* count how many markers are usable - see later */ 00225 if (sel) { 00226 for (marker= markers->first; marker; marker= marker->next) { 00227 if (marker->flag & SELECT) 00228 selcount++; 00229 } 00230 } 00231 else 00232 selcount= BLI_countlist(markers); 00233 00234 /* if only selected are to be considered, only consider the selected ones 00235 * (optimisation for not searching list) 00236 */ 00237 if (selcount > 1) { 00238 for (marker= markers->first; marker; marker= marker->next) { 00239 if (sel) { 00240 if (marker->flag & SELECT) { 00241 if (marker->frame < min) 00242 min= (float)marker->frame; 00243 if (marker->frame > max) 00244 max= (float)marker->frame; 00245 } 00246 } 00247 else { 00248 if (marker->frame < min) 00249 min= (float)marker->frame; 00250 if (marker->frame > max) 00251 max= (float)marker->frame; 00252 } 00253 } 00254 } 00255 00256 /* set the min/max values */ 00257 *first= min; 00258 *last= max; 00259 } 00260 00261 /* --------------------------------- */ 00262 00263 /* Adds a marker to list of cfra elems */ 00264 static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel) 00265 { 00266 CfraElem *ce, *cen; 00267 00268 /* should this one only be considered if it is selected? */ 00269 if ((only_sel) && ((marker->flag & SELECT)==0)) 00270 return; 00271 00272 /* insertion sort - try to find a previous cfra elem */ 00273 for (ce= lb->first; ce; ce= ce->next) { 00274 if (ce->cfra == marker->frame) { 00275 /* do because of double keys */ 00276 if (marker->flag & SELECT) 00277 ce->sel= marker->flag; 00278 return; 00279 } 00280 else if (ce->cfra > marker->frame) break; 00281 } 00282 00283 cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); 00284 if (ce) BLI_insertlinkbefore(lb, ce, cen); 00285 else BLI_addtail(lb, cen); 00286 00287 cen->cfra= marker->frame; 00288 cen->sel= marker->flag; 00289 } 00290 00291 /* This function makes a list of all the markers. The only_sel 00292 * argument is used to specify whether only the selected markers 00293 * are added. 00294 */ 00295 void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel) 00296 { 00297 TimeMarker *marker; 00298 00299 if (markers == NULL) 00300 return; 00301 00302 for (marker= markers->first; marker; marker= marker->next) 00303 add_marker_to_cfra_elem(lb, marker, only_sel); 00304 } 00305 00306 /* --------------------------------- */ 00307 00308 /* Get the first selected marker */ 00309 TimeMarker *ED_markers_get_first_selected(ListBase *markers) 00310 { 00311 TimeMarker *marker; 00312 00313 if (markers) { 00314 for (marker = markers->first; marker; marker = marker->next) { 00315 if (marker->flag & SELECT) 00316 return marker; 00317 } 00318 } 00319 00320 return NULL; 00321 } 00322 00323 /* --------------------------------- */ 00324 00325 /* Print debugging prints of list of markers 00326 * BSI's: do NOT make static or put in if-defs as "unused code". That's too much trouble when we need to use for quick debuggging! 00327 */ 00328 void debug_markers_print_list(ListBase *markers) 00329 { 00330 TimeMarker *marker; 00331 00332 if (markers == NULL) { 00333 printf("No markers list to print debug for\n"); 00334 return; 00335 } 00336 00337 printf("List of markers follows: -----\n"); 00338 00339 for (marker = markers->first; marker; marker = marker->next) { 00340 printf("\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag); 00341 } 00342 00343 printf("End of list ------------------\n"); 00344 } 00345 00346 /* ************* Marker Drawing ************ */ 00347 00348 /* function to draw markers */ 00349 static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) 00350 { 00351 float xpos, ypixels, xscale, yscale; 00352 int icon_id= 0; 00353 00354 xpos = marker->frame; 00355 00356 /* no time correction for framelen! space is drawn with old values */ 00357 ypixels= v2d->mask.ymax-v2d->mask.ymin; 00358 UI_view2d_getscale(v2d, &xscale, &yscale); 00359 00360 glScalef(1.0f/xscale, 1.0f, 1.0f); 00361 00362 glEnable(GL_BLEND); 00363 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00364 00365 /* vertical line - dotted */ 00366 #ifdef DURIAN_CAMERA_SWITCH 00367 if ((marker->camera) || (flag & DRAW_MARKERS_LINES)) 00368 #else 00369 if (flag & DRAW_MARKERS_LINES) 00370 #endif 00371 { 00372 setlinestyle(3); 00373 00374 if (marker->flag & SELECT) 00375 glColor4ub(255, 255, 255, 96); 00376 else 00377 glColor4ub(0, 0, 0, 96); 00378 00379 glBegin(GL_LINES); 00380 glVertex2f((xpos*xscale)+0.5f, 12.0f); 00381 glVertex2f((xpos*xscale)+0.5f, (v2d->cur.ymax+12.0f)*yscale); 00382 glEnd(); 00383 00384 setlinestyle(0); 00385 } 00386 00387 /* 5 px to offset icon to align properly, space / pixels corrects for zoom */ 00388 if (flag & DRAW_MARKERS_LOCAL) { 00389 icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT : 00390 (marker->flag & SELECT) ? ICON_PMARKER_SEL : 00391 ICON_PMARKER; 00392 } 00393 else { 00394 icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT : 00395 ICON_MARKER; 00396 } 00397 00398 UI_icon_draw(xpos*xscale-5.0f, 16.0f, icon_id); 00399 00400 glDisable(GL_BLEND); 00401 00402 /* and the marker name too, shifted slightly to the top-right */ 00403 if (marker->name && marker->name[0]) { 00404 float x, y; 00405 00406 if (marker->flag & SELECT) { 00407 UI_ThemeColor(TH_TEXT_HI); 00408 x= xpos*xscale + 4.0f; 00409 y= (ypixels <= 39.0f)? (ypixels-10.0f) : 29.0f; 00410 } 00411 else { 00412 UI_ThemeColor(TH_TEXT); 00413 if((marker->frame <= cfra) && (marker->frame+5 > cfra)) { 00414 x= xpos*xscale + 4.0f; 00415 y= (ypixels <= 39.0f)? (ypixels - 10.0f) : 29.0f; 00416 } 00417 else { 00418 x= xpos*xscale + 4.0f; 00419 y= 17.0f; 00420 } 00421 } 00422 00423 #ifdef DURIAN_CAMERA_SWITCH 00424 if(marker->camera && (marker->camera->restrictflag & OB_RESTRICT_RENDER)) { 00425 float col[4]; 00426 glGetFloatv(GL_CURRENT_COLOR, col); 00427 col[3]= 0.4; 00428 glColor4fv(col); 00429 } 00430 #endif 00431 00432 UI_DrawString(x, y, marker->name); 00433 } 00434 00435 glScalef(xscale, 1.0f, 1.0f); 00436 } 00437 00438 /* Draw Scene-Markers in time window */ 00439 void draw_markers_time(const bContext *C, int flag) 00440 { 00441 ListBase *markers= ED_context_get_markers(C); 00442 View2D *v2d= UI_view2d_fromcontext(C); 00443 TimeMarker *marker; 00444 00445 if (markers == NULL) 00446 return; 00447 00448 /* unselected markers are drawn at the first time */ 00449 for (marker= markers->first; marker; marker= marker->next) { 00450 if ((marker->flag & SELECT) == 0) 00451 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag); 00452 } 00453 00454 /* selected markers are drawn later */ 00455 for (marker= markers->first; marker; marker= marker->next) { 00456 if (marker->flag & SELECT) 00457 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag); 00458 } 00459 } 00460 00461 /* ************************ Marker Wrappers API ********************* */ 00462 /* These wrappers allow marker operators to function within the confines 00463 * of standard animation editors, such that they can coexist with the 00464 * primary operations of those editors. 00465 */ 00466 00467 /* ------------------------ */ 00468 00469 /* special poll() which checks if there are selected markers first */ 00470 static int ed_markers_poll_selected_markers(bContext *C) 00471 { 00472 ListBase *markers = ED_context_get_markers(C); 00473 00474 /* first things first: markers can only exist in timeline views */ 00475 if (ED_operator_animview_active(C) == 0) 00476 return 0; 00477 00478 /* check if some marker is selected */ 00479 return ED_markers_get_first_selected(markers) != NULL; 00480 } 00481 00482 /* special poll() which checks if there are any markers at all first */ 00483 static int ed_markers_poll_markers_exist(bContext *C) 00484 { 00485 ListBase *markers = ED_context_get_markers(C); 00486 00487 /* first things first: markers can only exist in timeline views */ 00488 if (ED_operator_animview_active(C) == 0) 00489 return 0; 00490 00491 /* list of markers must exist, as well as some markers in it! */ 00492 return (markers && markers->first); 00493 } 00494 00495 /* ------------------------ */ 00496 00497 /* Second-tier invoke() callback that performs context validation before running the 00498 * "custom"/third-tier invoke() callback supplied as the last arg (which would normally 00499 * be the operator's invoke() callback elsewhere) 00500 * 00501 * < invoke_func: (fn(bContext*, wmOperator*, wmEvent*)=int) "standard" invoke function 00502 * that operator would otherwise have used. If NULL, the operator's standard 00503 * exec() callback will be called instead in the appropriate places. 00504 */ 00505 static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent *evt, 00506 int (*invoke_func)(bContext*,wmOperator*,wmEvent*)) 00507 { 00508 ScrArea *sa = CTX_wm_area(C); 00509 int retval = OPERATOR_PASS_THROUGH; 00510 00511 /* removed check for Y coord of event, keymap has bounbox now */ 00512 00513 /* allow operator to run now */ 00514 if (invoke_func) 00515 retval = invoke_func(C, op, evt); 00516 else if (op->type->exec) 00517 retval = op->type->exec(C, op); 00518 else 00519 BKE_report(op->reports, RPT_ERROR, "Programming error: operator doesn't actually have code to do anything!"); 00520 00521 /* return status modifications - for now, make this spacetype dependent as above */ 00522 if (sa->spacetype != SPACE_TIME) { 00523 /* unless successful, must add "pass-through" to let normal operator's have a chance at tackling this event */ 00524 if (retval != OPERATOR_FINISHED) 00525 retval |= OPERATOR_PASS_THROUGH; 00526 } 00527 00528 return retval; 00529 } 00530 00531 /* standard wrapper - first-tier invoke() callback to be directly assigned to operator typedata 00532 * for operators which don't need any special invoke calls. Any operators with special invoke calls 00533 * though will need to implement their own wrapper which calls the second-tier callback themselves 00534 * (passing through the custom invoke function they use) 00535 */ 00536 static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, wmEvent *evt) 00537 { 00538 return ed_markers_opwrap_invoke_custom(C, op, evt, NULL); 00539 } 00540 00541 /* ************************** add markers *************************** */ 00542 00543 /* add TimeMarker at curent frame */ 00544 static int ed_marker_add(bContext *C, wmOperator *UNUSED(op)) 00545 { 00546 ListBase *markers= ED_context_get_markers(C); 00547 TimeMarker *marker; 00548 int frame= CTX_data_scene(C)->r.cfra; 00549 00550 if (markers == NULL) 00551 return OPERATOR_CANCELLED; 00552 00553 /* two markers can't be at the same place */ 00554 for (marker= markers->first; marker; marker= marker->next) { 00555 if (marker->frame == frame) 00556 return OPERATOR_CANCELLED; 00557 } 00558 00559 /* deselect all */ 00560 for (marker= markers->first; marker; marker= marker->next) 00561 marker->flag &= ~SELECT; 00562 00563 marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker"); 00564 marker->flag= SELECT; 00565 marker->frame= frame; 00566 BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); // XXX - temp code only 00567 BLI_addtail(markers, marker); 00568 00569 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 00570 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 00571 00572 return OPERATOR_FINISHED; 00573 } 00574 00575 static void MARKER_OT_add(wmOperatorType *ot) 00576 { 00577 /* identifiers */ 00578 ot->name= "Add Time Marker"; 00579 ot->description= "Add a new time marker"; 00580 ot->idname= "MARKER_OT_add"; 00581 00582 /* api callbacks */ 00583 ot->exec= ed_marker_add; 00584 ot->invoke = ed_markers_opwrap_invoke; 00585 ot->poll= ED_operator_animview_active; 00586 00587 /* flags */ 00588 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00589 } 00590 00591 /* ************************** transform markers *************************** */ 00592 00593 00594 /* operator state vars used: 00595 frs: delta movement 00596 00597 functions: 00598 00599 init() check selection, add customdata with old values and some lookups 00600 00601 apply() do the actual movement 00602 00603 exit() cleanup, send notifier 00604 00605 cancel() to escape from modal 00606 00607 callbacks: 00608 00609 exec() calls init, apply, exit 00610 00611 invoke() calls init, adds modal handler 00612 00613 modal() accept modal events while doing it, ends with apply and exit, or cancel 00614 00615 */ 00616 00617 typedef struct MarkerMove { 00618 SpaceLink *slink; 00619 ListBase *markers; 00620 int event_type; /* store invoke-event, to verify */ 00621 int *oldframe, evtx, firstx; 00622 NumInput num; 00623 } MarkerMove; 00624 00625 /* copy selection to temp buffer */ 00626 /* return 0 if not OK */ 00627 static int ed_marker_move_init(bContext *C, wmOperator *op) 00628 { 00629 ListBase *markers= ED_context_get_markers(C); 00630 MarkerMove *mm; 00631 TimeMarker *marker; 00632 int totmark=0; 00633 int a; 00634 00635 if(markers == NULL) return 0; 00636 00637 for (marker= markers->first; marker; marker= marker->next) 00638 if (marker->flag & SELECT) totmark++; 00639 00640 if (totmark==0) return 0; 00641 00642 op->customdata= mm= MEM_callocN(sizeof(MarkerMove), "Markermove"); 00643 mm->slink= CTX_wm_space_data(C); 00644 mm->markers= markers; 00645 mm->oldframe= MEM_callocN(totmark*sizeof(int), "MarkerMove oldframe"); 00646 00647 initNumInput(&mm->num); 00648 mm->num.idx_max = 0; /* one axis */ 00649 mm->num.flag |= NUM_NO_FRACTION; 00650 mm->num.increment = 1.0f; 00651 00652 for (a=0, marker= markers->first; marker; marker= marker->next) { 00653 if (marker->flag & SELECT) { 00654 mm->oldframe[a]= marker->frame; 00655 a++; 00656 } 00657 } 00658 00659 return 1; 00660 } 00661 00662 /* free stuff */ 00663 static void ed_marker_move_exit(bContext *C, wmOperator *op) 00664 { 00665 MarkerMove *mm= op->customdata; 00666 00667 /* free data */ 00668 MEM_freeN(mm->oldframe); 00669 MEM_freeN(op->customdata); 00670 op->customdata= NULL; 00671 00672 /* clear custom header prints */ 00673 ED_area_headerprint(CTX_wm_area(C), NULL); 00674 } 00675 00676 static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt) 00677 { 00678 if(ed_marker_move_init(C, op)) { 00679 MarkerMove *mm= op->customdata; 00680 00681 mm->evtx= evt->x; 00682 mm->firstx= evt->x; 00683 mm->event_type= evt->type; 00684 00685 /* add temp handler */ 00686 WM_event_add_modal_handler(C, op); 00687 00688 /* reset frs delta */ 00689 RNA_int_set(op->ptr, "frames", 0); 00690 00691 return OPERATOR_RUNNING_MODAL; 00692 } 00693 00694 return OPERATOR_CANCELLED; 00695 } 00696 00697 static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 00698 { 00699 return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_move_invoke); 00700 } 00701 00702 /* note, init has to be called succesfully */ 00703 static void ed_marker_move_apply(wmOperator *op) 00704 { 00705 MarkerMove *mm= op->customdata; 00706 TimeMarker *marker; 00707 int a, offs; 00708 00709 offs= RNA_int_get(op->ptr, "frames"); 00710 for (a=0, marker= mm->markers->first; marker; marker= marker->next) { 00711 if (marker->flag & SELECT) { 00712 marker->frame= mm->oldframe[a] + offs; 00713 a++; 00714 } 00715 } 00716 } 00717 00718 /* only for modal */ 00719 static int ed_marker_move_cancel(bContext *C, wmOperator *op) 00720 { 00721 RNA_int_set(op->ptr, "frames", 0); 00722 ed_marker_move_apply(op); 00723 ed_marker_move_exit(C, op); 00724 00725 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 00726 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 00727 00728 return OPERATOR_CANCELLED; 00729 } 00730 00731 00732 00733 static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) 00734 { 00735 Scene *scene= CTX_data_scene(C); 00736 MarkerMove *mm= op->customdata; 00737 View2D *v2d= UI_view2d_fromcontext(C); 00738 TimeMarker *marker, *selmarker=NULL; 00739 float dx, fac; 00740 char str[256]; 00741 00742 switch(evt->type) { 00743 case ESCKEY: 00744 ed_marker_move_cancel(C, op); 00745 return OPERATOR_CANCELLED; 00746 00747 case RIGHTMOUSE: 00748 /* press = user manually demands transform to be cancelled */ 00749 if (evt->val == KM_PRESS) { 00750 ed_marker_move_cancel(C, op); 00751 return OPERATOR_CANCELLED; 00752 } 00753 /* else continue; <--- see if release event should be caught for tweak-end */ 00754 00755 case RETKEY: 00756 case PADENTER: 00757 case LEFTMOUSE: 00758 case MIDDLEMOUSE: 00759 if (WM_modal_tweak_exit(evt, mm->event_type)) { 00760 ed_marker_move_exit(C, op); 00761 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 00762 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 00763 return OPERATOR_FINISHED; 00764 } 00765 break; 00766 case MOUSEMOVE: 00767 if (hasNumInput(&mm->num)) 00768 break; 00769 00770 dx= v2d->mask.xmax-v2d->mask.xmin; 00771 dx= (v2d->cur.xmax-v2d->cur.xmin)/dx; 00772 00773 if (evt->x != mm->evtx) { /* XXX maybe init for firsttime */ 00774 int a, offs, totmark=0; 00775 00776 mm->evtx= evt->x; 00777 00778 fac= ((float)(evt->x - mm->firstx)*dx); 00779 00780 if (mm->slink->spacetype == SPACE_TIME) 00781 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0); 00782 else 00783 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/); 00784 00785 offs= (int)fac; 00786 RNA_int_set(op->ptr, "frames", offs); 00787 ed_marker_move_apply(op); 00788 00789 /* cruft below is for header print */ 00790 for (a=0, marker= mm->markers->first; marker; marker= marker->next) { 00791 if (marker->flag & SELECT) { 00792 selmarker= marker; 00793 a++; totmark++; 00794 } 00795 } 00796 00797 if (totmark==1) { 00798 /* we print current marker value */ 00799 if (mm->slink->spacetype == SPACE_TIME) { 00800 SpaceTime *stime= (SpaceTime *)mm->slink; 00801 if (stime->flag & TIME_DRAWFRAMES) 00802 BLI_snprintf(str, sizeof(str), "Marker %d offset %d", selmarker->frame, offs); 00803 else 00804 BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); 00805 } 00806 else if (mm->slink->spacetype == SPACE_ACTION) { 00807 SpaceAction *saction= (SpaceAction *)mm->slink; 00808 if (saction->flag & SACTION_DRAWTIME) 00809 BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs)); 00810 else 00811 BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); 00812 } 00813 else { 00814 BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs)); 00815 } 00816 } 00817 else { 00818 /* we only print the offset */ 00819 if (mm->slink->spacetype == SPACE_TIME) { 00820 SpaceTime *stime= (SpaceTime *)mm->slink; 00821 if (stime->flag & TIME_DRAWFRAMES) 00822 BLI_snprintf(str, sizeof(str), "Marker offset %d ", offs); 00823 else 00824 BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs)); 00825 } 00826 else if (mm->slink->spacetype == SPACE_ACTION) { 00827 SpaceAction *saction= (SpaceAction *)mm->slink; 00828 if (saction->flag & SACTION_DRAWTIME) 00829 BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs)); 00830 else 00831 BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs)); 00832 } 00833 else { 00834 BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs)); 00835 } 00836 } 00837 00838 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 00839 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 00840 ED_area_headerprint(CTX_wm_area(C), str); 00841 } 00842 } 00843 00844 if (evt->val==KM_PRESS) { 00845 float vec[3]; 00846 char str_tx[256]; 00847 00848 if (handleNumInput(&mm->num, evt)) 00849 { 00850 applyNumInput(&mm->num, vec); 00851 outputNumInput(&mm->num, str_tx); 00852 00853 RNA_int_set(op->ptr, "frames", vec[0]); 00854 ed_marker_move_apply(op); 00855 // ed_marker_header_update(C, op, str, (int)vec[0]); 00856 // strcat(str, str_tx); 00857 BLI_snprintf(str, sizeof(str), "Marker offset %s", str_tx); 00858 ED_area_headerprint(CTX_wm_area(C), str); 00859 00860 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 00861 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 00862 } 00863 } 00864 00865 return OPERATOR_RUNNING_MODAL; 00866 } 00867 00868 static int ed_marker_move_exec(bContext *C, wmOperator *op) 00869 { 00870 if(ed_marker_move_init(C, op)) { 00871 ed_marker_move_apply(op); 00872 ed_marker_move_exit(C, op); 00873 return OPERATOR_FINISHED; 00874 } 00875 return OPERATOR_PASS_THROUGH; 00876 } 00877 00878 static void MARKER_OT_move(wmOperatorType *ot) 00879 { 00880 /* identifiers */ 00881 ot->name= "Move Time Marker"; 00882 ot->description= "Move selected time marker(s)"; 00883 ot->idname= "MARKER_OT_move"; 00884 00885 /* api callbacks */ 00886 ot->exec= ed_marker_move_exec; 00887 ot->invoke= ed_marker_move_invoke_wrapper; 00888 ot->modal= ed_marker_move_modal; 00889 ot->poll= ed_markers_poll_selected_markers; 00890 ot->cancel= ed_marker_move_cancel; 00891 00892 /* flags */ 00893 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; 00894 00895 /* rna storage */ 00896 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX); 00897 } 00898 00899 /* ************************** duplicate markers *************************** */ 00900 00901 /* operator state vars used: 00902 frs: delta movement 00903 00904 functions: 00905 00906 apply() do the actual duplicate 00907 00908 callbacks: 00909 00910 exec() calls apply, move_exec 00911 00912 invoke() calls apply, move_invoke 00913 00914 modal() uses move_modal 00915 00916 */ 00917 00918 00919 /* duplicate selected TimeMarkers */ 00920 static void ed_marker_duplicate_apply(bContext *C) 00921 { 00922 ListBase *markers= ED_context_get_markers(C); 00923 TimeMarker *marker, *newmarker; 00924 00925 if (markers == NULL) 00926 return; 00927 00928 /* go through the list of markers, duplicate selected markers and add duplicated copies 00929 * to the begining of the list (unselect original markers) 00930 */ 00931 for (marker= markers->first; marker; marker= marker->next) { 00932 if (marker->flag & SELECT) { 00933 /* unselect selected marker */ 00934 marker->flag &= ~SELECT; 00935 00936 /* create and set up new marker */ 00937 newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker"); 00938 newmarker->flag= SELECT; 00939 newmarker->frame= marker->frame; 00940 BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name)); 00941 00942 #ifdef DURIAN_CAMERA_SWITCH 00943 newmarker->camera= marker->camera; 00944 #endif 00945 00946 /* new marker is added to the begining of list */ 00947 // FIXME: bad ordering! 00948 BLI_addhead(markers, newmarker); 00949 } 00950 } 00951 } 00952 00953 static int ed_marker_duplicate_exec(bContext *C, wmOperator *op) 00954 { 00955 ed_marker_duplicate_apply(C); 00956 ed_marker_move_exec(C, op); /* assumes frs delta set */ 00957 00958 return OPERATOR_FINISHED; 00959 00960 } 00961 00962 static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt) 00963 { 00964 ed_marker_duplicate_apply(C); 00965 return ed_marker_move_invoke(C, op, evt); 00966 } 00967 00968 static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 00969 { 00970 return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_duplicate_invoke); 00971 } 00972 00973 static void MARKER_OT_duplicate(wmOperatorType *ot) 00974 { 00975 /* identifiers */ 00976 ot->name= "Duplicate Time Marker"; 00977 ot->description= "Duplicate selected time marker(s)"; 00978 ot->idname= "MARKER_OT_duplicate"; 00979 00980 /* api callbacks */ 00981 ot->exec= ed_marker_duplicate_exec; 00982 ot->invoke= ed_marker_duplicate_invoke_wrapper; 00983 ot->modal= ed_marker_move_modal; 00984 ot->poll= ed_markers_poll_selected_markers; 00985 ot->cancel= ed_marker_move_cancel; 00986 00987 /* flags */ 00988 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00989 00990 /* rna storage */ 00991 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX); 00992 } 00993 00994 /* ************************** selection ************************************/ 00995 00996 /* select/deselect TimeMarker at current frame */ 00997 static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned char shift) 00998 { 00999 TimeMarker *marker; 01000 int select=0; 01001 01002 for (marker= markers->first; marker; marker= marker->next) { 01003 /* if Shift is not set, then deselect Markers */ 01004 if (!shift) marker->flag &= ~SELECT; 01005 01006 /* this way a not-shift select will allways give 1 selected marker */ 01007 if ((marker->frame == frame) && (!select)) { 01008 if (marker->flag & SELECT) 01009 marker->flag &= ~SELECT; 01010 else 01011 marker->flag |= SELECT; 01012 select = 1; 01013 } 01014 } 01015 } 01016 01017 static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera) 01018 { 01019 ListBase *markers= ED_context_get_markers(C); 01020 View2D *v2d= UI_view2d_fromcontext(C); 01021 float viewx; 01022 int x, y, cfra; 01023 01024 if (markers == NULL) 01025 return OPERATOR_PASS_THROUGH; 01026 01027 x= evt->x - CTX_wm_region(C)->winrct.xmin; 01028 y= evt->y - CTX_wm_region(C)->winrct.ymin; 01029 01030 UI_view2d_region_to_view(v2d, x, y, &viewx, NULL); 01031 01032 cfra= ED_markers_find_nearest_marker_time(markers, viewx); 01033 01034 if (extend) 01035 select_timeline_marker_frame(markers, cfra, 1); 01036 else 01037 select_timeline_marker_frame(markers, cfra, 0); 01038 01039 #ifdef DURIAN_CAMERA_SWITCH 01040 01041 if (camera) { 01042 Scene *scene= CTX_data_scene(C); 01043 Base *base; 01044 TimeMarker *marker; 01045 int sel= 0; 01046 01047 if (!extend) 01048 scene_deselect_all(scene); 01049 01050 for (marker= markers->first; marker; marker= marker->next) { 01051 if(marker->frame==cfra) { 01052 sel= (marker->flag & SELECT); 01053 break; 01054 } 01055 } 01056 01057 for (marker= markers->first; marker; marker= marker->next) { 01058 if (marker->camera) { 01059 if (marker->frame==cfra) { 01060 base= object_in_scene(marker->camera, scene); 01061 if (base) { 01062 ED_base_object_select(base, sel); 01063 if(sel) 01064 ED_base_object_activate(C, base); 01065 } 01066 } 01067 } 01068 } 01069 01070 WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); 01071 } 01072 #else 01073 (void)camera; 01074 #endif 01075 01076 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01077 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01078 01079 /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails... [#25987] */ 01080 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; 01081 } 01082 01083 static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt) 01084 { 01085 short extend= RNA_boolean_get(op->ptr, "extend"); 01086 short camera= 0; 01087 #ifdef DURIAN_CAMERA_SWITCH 01088 camera= RNA_boolean_get(op->ptr, "camera"); 01089 #endif 01090 return ed_marker_select(C, evt, extend, camera); 01091 } 01092 01093 static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 01094 { 01095 return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_select_invoke); 01096 } 01097 01098 static void MARKER_OT_select(wmOperatorType *ot) 01099 { 01100 /* identifiers */ 01101 ot->name= "Select Time Marker"; 01102 ot->description= "Select time marker(s)"; 01103 ot->idname= "MARKER_OT_select"; 01104 01105 /* api callbacks */ 01106 ot->invoke= ed_marker_select_invoke_wrapper; 01107 ot->poll= ed_markers_poll_markers_exist; 01108 01109 /* flags */ 01110 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01111 01112 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "extend the selection"); 01113 #ifdef DURIAN_CAMERA_SWITCH 01114 RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera"); 01115 #endif 01116 } 01117 01118 /* *************************** border select markers **************** */ 01119 01120 /* operator state vars used: (added by default WM callbacks) 01121 xmin, ymin 01122 xmax, ymax 01123 01124 customdata: the wmGesture pointer, with subwindow 01125 01126 callbacks: 01127 01128 exec() has to be filled in by user 01129 01130 invoke() default WM function 01131 adds modal handler 01132 01133 modal() default WM function 01134 accept modal events while doing it, calls exec(), handles ESC and border drawing 01135 01136 poll() has to be filled in by user for context 01137 */ 01138 01139 static int ed_marker_border_select_exec(bContext *C, wmOperator *op) 01140 { 01141 View2D *v2d= UI_view2d_fromcontext(C); 01142 ListBase *markers= ED_context_get_markers(C); 01143 TimeMarker *marker; 01144 float xminf, xmaxf, yminf, ymaxf; 01145 int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); 01146 int xmin= RNA_int_get(op->ptr, "xmin"); 01147 int xmax= RNA_int_get(op->ptr, "xmax"); 01148 int ymin= RNA_int_get(op->ptr, "ymin"); 01149 int ymax= RNA_int_get(op->ptr, "ymax"); 01150 int extend= RNA_boolean_get(op->ptr, "extend"); 01151 01152 UI_view2d_region_to_view(v2d, xmin, ymin, &xminf, &yminf); 01153 UI_view2d_region_to_view(v2d, xmax, ymax, &xmaxf, &ymaxf); 01154 01155 if (markers == NULL) 01156 return 0; 01157 01158 /* XXX marker context */ 01159 for (marker= markers->first; marker; marker= marker->next) { 01160 if ((marker->frame > xminf) && (marker->frame <= xmaxf)) { 01161 switch (gesture_mode) { 01162 case GESTURE_MODAL_SELECT: 01163 marker->flag |= SELECT; 01164 break; 01165 case GESTURE_MODAL_DESELECT: 01166 marker->flag &= ~SELECT; 01167 break; 01168 } 01169 } 01170 else if (!extend) { 01171 marker->flag &= ~SELECT; 01172 } 01173 } 01174 01175 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01176 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01177 01178 return 1; 01179 } 01180 01181 static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 01182 { 01183 return ed_markers_opwrap_invoke_custom(C, op, evt, WM_border_select_invoke); 01184 } 01185 01186 static void MARKER_OT_select_border(wmOperatorType *ot) 01187 { 01188 /* identifiers */ 01189 ot->name= "Marker Border select"; 01190 ot->description= "Select all time markers using border selection"; 01191 ot->idname= "MARKER_OT_select_border"; 01192 01193 /* api callbacks */ 01194 ot->exec= ed_marker_border_select_exec; 01195 ot->invoke= ed_marker_select_border_invoke_wrapper; 01196 ot->modal= WM_border_select_modal; 01197 ot->cancel= WM_border_select_cancel; 01198 01199 ot->poll= ed_markers_poll_markers_exist; 01200 01201 /* flags */ 01202 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01203 01204 /* rna */ 01205 WM_operator_properties_gesture_border(ot, TRUE); 01206 } 01207 01208 /* *********************** (de)select all ***************** */ 01209 01210 static int ed_marker_select_all_exec(bContext *C, wmOperator *op) 01211 { 01212 ListBase *markers= ED_context_get_markers(C); 01213 TimeMarker *marker; 01214 int action = RNA_enum_get(op->ptr, "action"); 01215 01216 if (markers == NULL) 01217 return OPERATOR_CANCELLED; 01218 01219 if (action == SEL_TOGGLE) { 01220 action = (ED_markers_get_first_selected(markers) != NULL) ? SEL_DESELECT : SEL_SELECT; 01221 } 01222 01223 for(marker= markers->first; marker; marker= marker->next) { 01224 switch (action) { 01225 case SEL_SELECT: 01226 marker->flag |= SELECT; 01227 break; 01228 case SEL_DESELECT: 01229 marker->flag &= ~SELECT; 01230 break; 01231 case SEL_INVERT: 01232 marker->flag ^= SELECT; 01233 break; 01234 } 01235 } 01236 01237 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01238 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01239 01240 return OPERATOR_FINISHED; 01241 } 01242 01243 static void MARKER_OT_select_all(wmOperatorType *ot) 01244 { 01245 /* identifiers */ 01246 ot->name= "(De)select all markers"; 01247 ot->description= "Change selection of all time markers"; 01248 ot->idname= "MARKER_OT_select_all"; 01249 01250 /* api callbacks */ 01251 ot->exec= ed_marker_select_all_exec; 01252 ot->invoke = ed_markers_opwrap_invoke; 01253 ot->poll= ed_markers_poll_markers_exist; 01254 01255 /* flags */ 01256 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01257 01258 /* rna */ 01259 WM_operator_properties_select_all(ot); 01260 } 01261 01262 /* ***************** remove marker *********************** */ 01263 01264 /* remove selected TimeMarkers */ 01265 static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op)) 01266 { 01267 ListBase *markers= ED_context_get_markers(C); 01268 TimeMarker *marker, *nmarker; 01269 short changed= 0; 01270 01271 if (markers == NULL) 01272 return OPERATOR_CANCELLED; 01273 01274 for (marker= markers->first; marker; marker= nmarker) { 01275 nmarker= marker->next; 01276 if (marker->flag & SELECT) { 01277 BLI_freelinkN(markers, marker); 01278 changed= 1; 01279 } 01280 } 01281 01282 if (changed) { 01283 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01284 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01285 } 01286 01287 return OPERATOR_FINISHED; 01288 } 01289 01290 static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 01291 { 01292 // XXX: must we keep these confirmations? 01293 return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_confirm); 01294 } 01295 01296 static void MARKER_OT_delete(wmOperatorType *ot) 01297 { 01298 /* identifiers */ 01299 ot->name= "Delete Markers"; 01300 ot->description= "Delete selected time marker(s)"; 01301 ot->idname= "MARKER_OT_delete"; 01302 01303 /* api callbacks */ 01304 ot->invoke= ed_marker_delete_invoke_wrapper; 01305 ot->exec= ed_marker_delete_exec; 01306 ot->poll= ed_markers_poll_selected_markers; 01307 01308 /* flags */ 01309 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01310 } 01311 01312 01313 /* **************** rename marker ***************** */ 01314 01315 /* rename first selected TimeMarker */ 01316 static int ed_marker_rename_exec(bContext *C, wmOperator *op) 01317 { 01318 TimeMarker *marker= ED_markers_get_first_selected(ED_context_get_markers(C)); 01319 01320 if (marker) { 01321 RNA_string_get(op->ptr, "name", marker->name); 01322 01323 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01324 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01325 01326 return OPERATOR_FINISHED; 01327 } 01328 else { 01329 return OPERATOR_CANCELLED; 01330 } 01331 } 01332 01333 static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt) 01334 { 01335 /* must initialise the marker name first if there is a marker selected */ 01336 TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C)); 01337 if (marker) 01338 RNA_string_set(op->ptr, "name", marker->name); 01339 01340 /* now see if the operator is usable */ 01341 return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_props_popup); 01342 } 01343 01344 static void MARKER_OT_rename(wmOperatorType *ot) 01345 { 01346 /* identifiers */ 01347 ot->name= "Rename Marker"; 01348 ot->description= "Rename first selected time marker"; 01349 ot->idname= "MARKER_OT_rename"; 01350 01351 /* api callbacks */ 01352 ot->invoke= ed_marker_rename_invoke_wrapper; 01353 ot->exec= ed_marker_rename_exec; 01354 ot->poll= ed_markers_poll_selected_markers; 01355 01356 /* flags */ 01357 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01358 01359 /* properties */ 01360 ot->prop = RNA_def_string(ot->srna, "name", "RenamedMarker", sizeof(((TimeMarker *)NULL)->name), "Name", "New name for marker"); 01361 //RNA_def_boolean(ot->srna, "ensure_unique", 0, "Ensure Unique", "Ensure that new name is unique within collection of markers"); 01362 } 01363 01364 /* **************** make links to scene ***************** */ 01365 01366 static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op) 01367 { 01368 ListBase *markers= ED_context_get_markers(C); 01369 Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); 01370 TimeMarker *marker, *marker_new; 01371 01372 if (scene_to==NULL) { 01373 BKE_report(op->reports, RPT_ERROR, "Scene not found"); 01374 return OPERATOR_CANCELLED; 01375 } 01376 01377 if (scene_to == CTX_data_scene(C)) { 01378 BKE_report(op->reports, RPT_ERROR, "Can't re-link markers into the same scene"); 01379 return OPERATOR_CANCELLED; 01380 } 01381 01382 /* copy markers */ 01383 for (marker= markers->first; marker; marker= marker->next) { 01384 if (marker->flag & SELECT) { 01385 marker_new= MEM_dupallocN(marker); 01386 marker_new->prev= marker_new->next = NULL; 01387 01388 BLI_addtail(&scene_to->markers, marker_new); 01389 } 01390 } 01391 01392 return OPERATOR_FINISHED; 01393 } 01394 01395 static void MARKER_OT_make_links_scene(wmOperatorType *ot) 01396 { 01397 PropertyRNA *prop; 01398 01399 /* identifiers */ 01400 ot->name= "Make Links to Scene"; 01401 ot->description= "Copy selected markers to another scene"; 01402 ot->idname= "MARKER_OT_make_links_scene"; 01403 01404 /* api callbacks */ 01405 ot->exec= ed_marker_make_links_scene_exec; 01406 ot->invoke = ed_markers_opwrap_invoke; 01407 ot->poll= ed_markers_poll_selected_markers; 01408 01409 /* flags */ 01410 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01411 01412 /* properties */ 01413 prop= RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", ""); 01414 RNA_def_enum_funcs(prop, RNA_scene_itemf); 01415 ot->prop= prop; 01416 01417 } 01418 01419 #ifdef DURIAN_CAMERA_SWITCH 01420 /* ******************************* camera bind marker ***************** */ 01421 01422 static int ed_marker_camera_bind_exec(bContext *C, wmOperator *UNUSED(op)) 01423 { 01424 bScreen *sc= CTX_wm_screen(C); 01425 Scene *scene= CTX_data_scene(C); 01426 Object *ob = CTX_data_active_object(C); 01427 ListBase *markers= ED_context_get_markers(C); 01428 TimeMarker *marker; 01429 01430 marker= ED_markers_get_first_selected(markers); 01431 if(marker == NULL) 01432 return OPERATOR_CANCELLED; 01433 01434 marker->camera= ob; 01435 01436 /* camera may have changes */ 01437 scene_camera_switch_update(scene); 01438 BKE_screen_view3d_scene_sync(sc); 01439 01440 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); 01441 WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); 01442 WM_event_add_notifier(C, NC_SCENE|NA_EDITED, scene); /* so we get view3d redraws */ 01443 01444 return OPERATOR_FINISHED; 01445 } 01446 01447 static void MARKER_OT_camera_bind(wmOperatorType *ot) 01448 { 01449 /* identifiers */ 01450 ot->name= "Bind Camera to Markers"; 01451 ot->description= "Bind the active camera to selected markers(s)"; 01452 ot->idname= "MARKER_OT_camera_bind"; 01453 01454 /* api callbacks */ 01455 ot->exec= ed_marker_camera_bind_exec; 01456 ot->invoke = ed_markers_opwrap_invoke; 01457 ot->poll= ed_markers_poll_selected_markers; 01458 01459 /* flags */ 01460 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01461 } 01462 #endif 01463 01464 /* ************************** registration **********************************/ 01465 01466 /* called in screen_ops.c:ED_operatortypes_screen() */ 01467 void ED_operatortypes_marker(void) 01468 { 01469 WM_operatortype_append(MARKER_OT_add); 01470 WM_operatortype_append(MARKER_OT_move); 01471 WM_operatortype_append(MARKER_OT_duplicate); 01472 WM_operatortype_append(MARKER_OT_select); 01473 WM_operatortype_append(MARKER_OT_select_border); 01474 WM_operatortype_append(MARKER_OT_select_all); 01475 WM_operatortype_append(MARKER_OT_delete); 01476 WM_operatortype_append(MARKER_OT_rename); 01477 WM_operatortype_append(MARKER_OT_make_links_scene); 01478 #ifdef DURIAN_CAMERA_SWITCH 01479 WM_operatortype_append(MARKER_OT_camera_bind); 01480 #endif 01481 } 01482 01483 /* called in screen_ops.c:ED_keymap_screen() */ 01484 void ED_marker_keymap(wmKeyConfig *keyconf) 01485 { 01486 wmKeyMap *keymap= WM_keymap_find(keyconf, "Markers", 0, 0); 01487 wmKeyMapItem *kmi; 01488 01489 WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0); 01490 WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0); 01491 WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); 01492 WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); 01493 kmi = WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); 01494 RNA_boolean_set(kmi->ptr, "extend", TRUE); 01495 01496 #ifdef DURIAN_CAMERA_SWITCH 01497 kmi= WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); 01498 RNA_boolean_set(kmi->ptr, "extend", FALSE); 01499 RNA_boolean_set(kmi->ptr, "camera", TRUE); 01500 01501 kmi= WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); 01502 RNA_boolean_set(kmi->ptr, "extend", TRUE); 01503 RNA_boolean_set(kmi->ptr, "camera", TRUE); 01504 #else 01505 (void)kmi; 01506 #endif 01507 01508 WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0); 01509 WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0); 01510 WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0); 01511 WM_keymap_verify_item(keymap, "MARKER_OT_delete", DELKEY, KM_PRESS, 0, 0); 01512 WM_keymap_verify_item(keymap, "MARKER_OT_rename", MKEY, KM_PRESS, KM_CTRL, 0); 01513 01514 WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0); 01515 #ifdef DURIAN_CAMERA_SWITCH 01516 WM_keymap_add_item(keymap, "MARKER_OT_camera_bind", BKEY, KM_PRESS, KM_CTRL, 0); 01517 #endif 01518 } 01519 01520 /* to be called from animation editor keymaps, see note below */ 01521 void ED_marker_keymap_animedit_conflictfree(wmKeyMap *keymap) 01522 { 01523 /* duplicate of some marker-hotkeys but without the bounds checking 01524 * since these are handy to be able to do unrestricted and won't conflict 01525 * with primary function hotkeys (Usability tweak [#27469]) 01526 */ 01527 WM_keymap_add_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0); 01528 WM_keymap_add_item(keymap, "MARKER_OT_rename", MKEY, KM_PRESS, KM_CTRL, 0); 01529 }