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