4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
32 #include "MEM_guardedalloc.h"
34 #include "DNA_action_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_space_types.h"
38 #include "DNA_view2d_types.h"
39 #include "DNA_userdef_types.h"
40 #include "DNA_windowmanager_types.h"
42 #include "RNA_access.h"
43 #include "RNA_define.h"
45 #include "BLI_blenlib.h"
47 #include "BKE_context.h"
48 #include "BKE_global.h"
49 #include "BKE_fcurve.h"
50 #include "BKE_utildefines.h"
56 #include "BIF_glutil.h"
58 #include "UI_interface.h"
59 #include "UI_interface_icons.h"
60 #include "UI_view2d.h"
61 #include "UI_resources.h"
63 #include "ED_markers.h"
64 #include "ED_screen.h"
68 /* ************* Marker API **************** */
70 static ListBase *context_get_markers(const bContext *C)
74 /* XXX get them from pose */
75 if ((slink->spacetype == SPACE_ACTION) && (saction->flag & SACTION_POSEMARKERS_MOVE)) {
77 markers= &saction->action->markers;
84 return &CTX_data_scene(C)->markers;
87 /* Get the marker that is closest to this point */
88 /* XXX for select, the min_dist should be small */
89 TimeMarker *ED_markers_find_nearest_marker (ListBase *markers, float x)
91 TimeMarker *marker, *nearest=NULL;
92 float dist, min_dist= 1000000;
95 for (marker= markers->first; marker; marker= marker->next) {
96 dist = ABS((float)marker->frame - x);
98 if (dist < min_dist) {
108 /* Return the time of the marker that occurs on a frame closest to the given time */
109 int ED_markers_find_nearest_marker_time (ListBase *markers, float x)
111 TimeMarker *nearest= ED_markers_find_nearest_marker(markers, x);
112 return (nearest) ? (nearest->frame) : (int)floor(x + 0.5f);
116 void ED_markers_get_minmax (ListBase *markers, short sel, float *first, float *last)
123 printf("markers = %p - %p, %p \n", markers, markers->first, markers->last);
124 if (markers == NULL) {
130 if (markers->first && markers->last) {
131 TimeMarker *fm= markers->first;
132 TimeMarker *lm= markers->last;
134 min= (float)fm->frame;
135 max= (float)lm->frame;
143 /* count how many markers are usable - see later */
145 for (marker= markers->first; marker; marker= marker->next) {
146 if (marker->flag & SELECT)
151 selcount= BLI_countlist(markers);
153 /* if only selected are to be considered, only consider the selected ones
154 * (optimisation for not searching list)
157 for (marker= markers->first; marker; marker= marker->next) {
159 if (marker->flag & SELECT) {
160 if (marker->frame < min)
161 min= (float)marker->frame;
162 if (marker->frame > max)
163 max= (float)marker->frame;
167 if (marker->frame < min)
168 min= (float)marker->frame;
169 if (marker->frame > max)
170 max= (float)marker->frame;
175 /* set the min/max values */
180 /* Adds a marker to list of cfra elems */
181 void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
185 /* should this one only be considered if it is selected? */
186 if ((only_sel) && ((marker->flag & SELECT)==0))
189 /* insertion sort - try to find a previous cfra elem */
190 for (ce= lb->first; ce; ce= ce->next) {
191 if (ce->cfra == marker->frame) {
192 /* do because of double keys */
193 if (marker->flag & SELECT)
194 ce->sel= marker->flag;
197 else if (ce->cfra > marker->frame) break;
200 cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
201 if (ce) BLI_insertlinkbefore(lb, ce, cen);
202 else BLI_addtail(lb, cen);
204 cen->cfra= marker->frame;
205 cen->sel= marker->flag;
208 /* This function makes a list of all the markers. The only_sel
209 * argument is used to specify whether only the selected markers
212 void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
219 for (marker= markers->first; marker; marker= marker->next)
220 add_marker_to_cfra_elem(lb, marker, only_sel);
223 /* ************* Marker Drawing ************ */
225 /* function to draw markers */
226 static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
228 float xpos, ypixels, xscale, yscale;
231 xpos = marker->frame;
233 /* no time correction for framelen! space is drawn with old values */
234 ypixels= v2d->mask.ymax-v2d->mask.ymin;
235 UI_view2d_getscale(v2d, &xscale, &yscale);
237 glScalef(1.0f/xscale, 1.0f, 1.0f);
240 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
242 /* vertical line - dotted */
243 // NOTE: currently only used for sequencer
244 #ifdef DURIAN_CAMERA_SWITCH
245 if (marker->camera || flag & DRAW_MARKERS_LINES) {
247 if (flag & DRAW_MARKERS_LINES) {
251 if (marker->flag & SELECT)
252 glColor4ub(255, 255, 255, 96);
254 glColor4ub(0, 0, 0, 96);
257 glVertex2f((xpos*xscale)+0.5f, 12.0f);
258 glVertex2f((xpos*xscale)+0.5f, 34.0f*yscale); /* a bit lazy but we know it cant be greater then 34 strips high */
264 /* 5 px to offset icon to align properly, space / pixels corrects for zoom */
265 if (flag & DRAW_MARKERS_LOCAL) {
266 icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
267 (marker->flag & SELECT) ? ICON_PMARKER_SEL :
271 icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT :
275 UI_icon_draw(xpos*xscale-5.0f, 16.0f, icon_id);
277 glBlendFunc(GL_ONE, GL_ZERO);
280 /* and the marker name too, shifted slightly to the top-right */
281 if (marker->name && marker->name[0]) {
284 if (marker->flag & SELECT) {
285 UI_ThemeColor(TH_TEXT_HI);
286 x= xpos*xscale + 4.0f;
287 y= (ypixels <= 39.0f)? (ypixels-10.0f) : 29.0f;
290 UI_ThemeColor(TH_TEXT);
291 if((marker->frame <= cfra) && (marker->frame+5 > cfra)) {
292 x= xpos*xscale + 4.0f;
293 y= (ypixels <= 39.0f)? (ypixels - 10.0f) : 29.0f;
296 x= xpos*xscale + 4.0f;
300 UI_DrawString(x, y, marker->name);
303 glScalef(xscale, 1.0f, 1.0f);
306 /* Draw Scene-Markers in time window */
307 void draw_markers_time(const bContext *C, int flag)
309 ListBase *markers= context_get_markers(C);
310 View2D *v2d= UI_view2d_fromcontext(C);
316 /* unselected markers are drawn at the first time */
317 for (marker= markers->first; marker; marker= marker->next) {
318 if ((marker->flag & SELECT) == 0)
319 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag);
322 /* selected markers are drawn later */
323 for (marker= markers->first; marker; marker= marker->next) {
324 if (marker->flag & SELECT)
325 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag);
329 /* ************************** add markers *************************** */
331 /* add TimeMarker at curent frame */
332 static int ed_marker_add(bContext *C, wmOperator *op)
334 ListBase *markers= context_get_markers(C);
336 int frame= CTX_data_scene(C)->r.cfra;
339 return OPERATOR_CANCELLED;
341 /* two markers can't be at the same place */
342 for (marker= markers->first; marker; marker= marker->next) {
343 if (marker->frame == frame)
344 return OPERATOR_CANCELLED;
348 for(marker= markers->first; marker; marker= marker->next)
349 marker->flag &= ~SELECT;
351 marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
352 marker->flag= SELECT;
353 marker->frame= frame;
354 sprintf(marker->name, "Frame %d", frame); // XXX - temp code only
355 BLI_addtail(markers, marker);
357 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
359 return OPERATOR_FINISHED;
362 static void MARKER_OT_add(wmOperatorType *ot)
365 ot->name= "Add Time Marker";
366 ot->description= "Add a new time marker.";
367 ot->idname= "MARKER_OT_add";
370 ot->exec= ed_marker_add;
371 ot->poll= ED_operator_areaactive;
374 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
377 /* ************************** transform markers *************************** */
380 /* operator state vars used:
385 init() check selection, add customdata with old values and some lookups
387 apply() do the actual movement
389 exit() cleanup, send notifier
391 cancel() to escpae from modal
395 exec() calls init, apply, exit
397 invoke() calls init, adds modal handler
399 modal() accept modal events while doing it, ends with apply and exit, or cancel
403 typedef struct MarkerMove {
406 int event_type; /* store invoke-event, to verify */
407 int *oldframe, evtx, firstx;
410 /* copy selection to temp buffer */
411 /* return 0 if not OK */
412 static int ed_marker_move_init(bContext *C, wmOperator *op)
414 ListBase *markers= context_get_markers(C);
420 if(markers == NULL) return 0;
422 for (marker= markers->first; marker; marker= marker->next)
423 if (marker->flag & SELECT) totmark++;
425 if (totmark==0) return 0;
427 op->customdata= mm= MEM_callocN(sizeof(MarkerMove), "Markermove");
428 mm->slink= CTX_wm_space_data(C);
429 mm->markers= markers;
430 mm->oldframe= MEM_callocN(totmark*sizeof(int), "MarkerMove oldframe");
432 for (a=0, marker= markers->first; marker; marker= marker->next) {
433 if (marker->flag & SELECT) {
434 mm->oldframe[a]= marker->frame;
443 static void ed_marker_move_exit(bContext *C, wmOperator *op)
445 MarkerMove *mm= op->customdata;
448 MEM_freeN(mm->oldframe);
449 MEM_freeN(op->customdata);
450 op->customdata= NULL;
452 /* clear custom header prints */
453 ED_area_headerprint(CTX_wm_area(C), NULL);
456 static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
458 if(ed_marker_move_init(C, op)) {
459 MarkerMove *mm= op->customdata;
463 mm->event_type= evt->type;
465 /* add temp handler */
466 WM_event_add_modal_handler(C, op);
468 /* reset frs delta */
469 RNA_int_set(op->ptr, "frames", 0);
471 return OPERATOR_RUNNING_MODAL;
474 return OPERATOR_CANCELLED;
477 /* note, init has to be called succesfully */
478 static void ed_marker_move_apply(bContext *C, wmOperator *op)
480 MarkerMove *mm= op->customdata;
484 offs= RNA_int_get(op->ptr, "frames");
485 for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
486 if (marker->flag & SELECT) {
487 marker->frame= mm->oldframe[a] + offs;
494 static void ed_marker_move_cancel(bContext *C, wmOperator *op)
496 RNA_int_set(op->ptr, "frames", 0);
497 ed_marker_move_apply(C, op);
498 ed_marker_move_exit(C, op);
500 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
505 static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
507 Scene *scene= CTX_data_scene(C);
508 MarkerMove *mm= op->customdata;
509 View2D *v2d= UI_view2d_fromcontext(C);
510 TimeMarker *marker, *selmarker=NULL;
516 ed_marker_move_cancel(C, op);
517 return OPERATOR_CANCELLED;
522 if(WM_modal_tweak_exit(evt, mm->event_type)) {
523 ed_marker_move_exit(C, op);
524 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
525 return OPERATOR_FINISHED;
530 dx= v2d->mask.xmax-v2d->mask.xmin;
531 dx= (v2d->cur.xmax-v2d->cur.xmin)/dx;
533 if (evt->x != mm->evtx) { /* XXX maybe init for firsttime */
534 int a, offs, totmark=0;
538 fac= ((float)(evt->x - mm->firstx)*dx);
540 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND))
541 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0);
543 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID);
546 RNA_int_set(op->ptr, "frames", offs);
547 ed_marker_move_apply(C, op);
549 /* cruft below is for header print */
550 for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
551 if (marker->flag & SELECT) {
558 /* we print current marker value */
559 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
560 SpaceTime *stime= (SpaceTime *)mm->slink;
561 if (stime->flag & TIME_DRAWFRAMES)
562 sprintf(str, "Marker %d offset %d", selmarker->frame, offs);
564 sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
566 else if (mm->slink->spacetype == SPACE_ACTION) {
567 SpaceAction *saction= (SpaceAction *)mm->slink;
568 if (saction->flag & SACTION_DRAWTIME)
569 sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
571 sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
574 sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
578 /* we only print the offset */
579 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
580 SpaceTime *stime= (SpaceTime *)mm->slink;
581 if (stime->flag & TIME_DRAWFRAMES)
582 sprintf(str, "Marker offset %d ", offs);
584 sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
586 else if (mm->slink->spacetype == SPACE_ACTION) {
587 SpaceAction *saction= (SpaceAction *)mm->slink;
588 if (saction->flag & SACTION_DRAWTIME)
589 sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
591 sprintf(str, "Marker offset %.2f ", (double)(offs));
594 sprintf(str, "Marker offset %.2f ", (double)(offs));
598 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
599 ED_area_headerprint(CTX_wm_area(C), str);
603 return OPERATOR_RUNNING_MODAL;
606 static int ed_marker_move_exec(bContext *C, wmOperator *op)
608 if(ed_marker_move_init(C, op)) {
609 ed_marker_move_apply(C, op);
610 ed_marker_move_exit(C, op);
611 return OPERATOR_FINISHED;
613 return OPERATOR_PASS_THROUGH;
616 static void MARKER_OT_move(wmOperatorType *ot)
619 ot->name= "Move Time Marker";
620 ot->description= "Move selected time marker(s).";
621 ot->idname= "MARKER_OT_move";
624 ot->exec= ed_marker_move_exec;
625 ot->invoke= ed_marker_move_invoke;
626 ot->modal= ed_marker_move_modal;
627 ot->poll= ED_operator_areaactive;
630 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
633 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
636 /* ************************** duplicate markers *************************** */
638 /* operator state vars used:
643 apply() do the actual duplicate
647 exec() calls apply, move_exec
649 invoke() calls apply, move_invoke
651 modal() uses move_modal
656 /* duplicate selected TimeMarkers */
657 static void ed_marker_duplicate_apply(bContext *C, wmOperator *op)
659 ListBase *markers= context_get_markers(C);
660 TimeMarker *marker, *newmarker;
665 /* go through the list of markers, duplicate selected markers and add duplicated copies
666 * to the begining of the list (unselect original markers)
668 for (marker= markers->first; marker; marker= marker->next) {
669 if (marker->flag & SELECT) {
670 /* unselect selected marker */
671 marker->flag &= ~SELECT;
673 /* create and set up new marker */
674 newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
675 newmarker->flag= SELECT;
676 newmarker->frame= marker->frame;
677 BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
679 #ifdef DURIAN_CAMERA_SWITCH
680 newmarker->camera= marker->camera;
683 /* new marker is added to the begining of list */
684 BLI_addhead(markers, newmarker);
689 static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
691 ed_marker_duplicate_apply(C, op);
692 ed_marker_move_exec(C, op); /* assumes frs delta set */
694 return OPERATOR_FINISHED;
698 static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt)
700 ed_marker_duplicate_apply(C, op);
701 return ed_marker_move_invoke(C, op, evt);
704 static void MARKER_OT_duplicate(wmOperatorType *ot)
707 ot->name= "Duplicate Time Marker";
708 ot->description= "Duplicate selected time marker(s).";
709 ot->idname= "MARKER_OT_duplicate";
712 ot->exec= ed_marker_duplicate_exec;
713 ot->invoke= ed_marker_duplicate_invoke;
714 ot->modal= ed_marker_move_modal;
715 ot->poll= ED_operator_areaactive;
718 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
721 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
724 /* ************************** selection ************************************/
726 /* select/deselect TimeMarker at current frame */
727 static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned char shift)
732 for (marker= markers->first; marker; marker= marker->next) {
733 /* if Shift is not set, then deselect Markers */
734 if (!shift) marker->flag &= ~SELECT;
736 /* this way a not-shift select will allways give 1 selected marker */
737 if ((marker->frame == frame) && (!select)) {
738 if (marker->flag & SELECT)
739 marker->flag &= ~SELECT;
741 marker->flag |= SELECT;
747 static int ed_marker_select(bContext *C, wmEvent *evt, int extend)
749 ListBase *markers= context_get_markers(C);
750 View2D *v2d= UI_view2d_fromcontext(C);
755 return OPERATOR_PASS_THROUGH;
757 x= evt->x - CTX_wm_region(C)->winrct.xmin;
758 y= evt->y - CTX_wm_region(C)->winrct.ymin;
760 UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
762 cfra= ED_markers_find_nearest_marker_time(markers, viewx);
765 select_timeline_marker_frame(markers, cfra, 1);
767 select_timeline_marker_frame(markers, cfra, 0);
769 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
771 /* allowing tweaks */
772 return OPERATOR_PASS_THROUGH;
775 static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
777 short extend= RNA_boolean_get(op->ptr, "extend");
778 return ed_marker_select(C, evt, extend);
781 static void MARKER_OT_select(wmOperatorType *ot)
784 ot->name= "Select Time Marker";
785 ot->description= "Select time marker(s).";
786 ot->idname= "MARKER_OT_select";
789 ot->invoke= ed_marker_select_invoke;
790 ot->poll= ED_operator_areaactive;
793 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
795 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "extend the selection");
798 /* *************************** border select markers **************** */
800 /* operator state vars used: (added by default WM callbacks)
804 customdata: the wmGesture pointer, with subwindow
808 exec() has to be filled in by user
810 invoke() default WM function
813 modal() default WM function
814 accept modal events while doing it, calls exec(), handles ESC and border drawing
816 poll() has to be filled in by user for context
819 static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
821 View2D *v2d= UI_view2d_fromcontext(C);
822 ListBase *markers= context_get_markers(C);
824 float xminf, xmaxf, yminf, ymaxf;
825 int gesture_mode= RNA_int_get(op->ptr, "gesture_mode");
826 int xmin= RNA_int_get(op->ptr, "xmin");
827 int xmax= RNA_int_get(op->ptr, "xmax");
828 int ymin= RNA_int_get(op->ptr, "ymin");
829 int ymax= RNA_int_get(op->ptr, "ymax");
831 UI_view2d_region_to_view(v2d, xmin, ymin, &xminf, &yminf);
832 UI_view2d_region_to_view(v2d, xmax, ymax, &xmaxf, &ymaxf);
835 if(yminf > 30.0f || ymaxf < 0.0f)
841 /* XXX marker context */
842 for(marker= markers->first; marker; marker= marker->next) {
843 if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
844 switch (gesture_mode) {
845 case GESTURE_MODAL_SELECT:
846 if ((marker->flag & SELECT) == 0)
847 marker->flag |= SELECT;
849 case GESTURE_MODAL_DESELECT:
850 if (marker->flag & SELECT)
851 marker->flag &= ~SELECT;
857 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
862 static void MARKER_OT_select_border(wmOperatorType *ot)
865 ot->name= "Marker Border select";
866 ot->description= "Select all time markers using border selection.";
867 ot->idname= "MARKER_OT_select_border";
870 ot->exec= ed_marker_border_select_exec;
871 ot->invoke= WM_border_select_invoke;
872 ot->modal= WM_border_select_modal;
874 ot->poll= ED_operator_areaactive;
877 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
880 WM_operator_properties_gesture_border(ot, FALSE);
883 /* *********************** (de)select all ***************** */
885 static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
887 ListBase *markers= context_get_markers(C);
889 int action = RNA_enum_get(op->ptr, "action");
892 return OPERATOR_CANCELLED;
894 if (action == SEL_TOGGLE) {
896 for(marker= markers->first; marker; marker= marker->next) {
897 if(marker->flag & SELECT) {
898 action = SEL_DESELECT;
904 for(marker= markers->first; marker; marker= marker->next) {
907 marker->flag |= SELECT;
910 marker->flag &= ~SELECT;
913 if (marker->flag & SELECT) {
914 marker->flag &= ~SELECT;
916 marker->flag |= SELECT;
922 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
924 return OPERATOR_FINISHED;
927 static void MARKER_OT_select_all(wmOperatorType *ot)
930 ot->name= "(De)select all markers";
931 ot->description= "Change selection of all time markers.";
932 ot->idname= "MARKER_OT_select_all";
935 ot->exec= ed_marker_select_all_exec;
936 ot->poll= ED_operator_areaactive;
939 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
942 WM_operator_properties_select_all(ot);
945 /* ******************************* remove marker ***************** */
947 /* remove selected TimeMarkers */
948 static int ed_marker_delete_exec(bContext *C, wmOperator *op)
950 ListBase *markers= context_get_markers(C);
951 TimeMarker *marker, *nmarker;
955 return OPERATOR_CANCELLED;
957 for(marker= markers->first; marker; marker= nmarker) {
958 nmarker= marker->next;
959 if(marker->flag & SELECT) {
960 BLI_freelinkN(markers, marker);
966 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
968 return OPERATOR_FINISHED;
972 static void MARKER_OT_delete(wmOperatorType *ot)
975 ot->name= "Delete Markers";
976 ot->description= "Delete selected time marker(s).";
977 ot->idname= "MARKER_OT_delete";
980 ot->invoke= WM_operator_confirm;
981 ot->exec= ed_marker_delete_exec;
982 ot->poll= ED_operator_areaactive;
985 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
989 #ifdef DURIAN_CAMERA_SWITCH
990 /* ******************************* camera bind marker ***************** */
992 /* remove selected TimeMarkers */
993 static int ed_marker_camera_bind_exec(bContext *C, wmOperator *op)
995 Scene *scene= CTX_data_scene(C);
996 ListBase *markers= context_get_markers(C);
1001 return OPERATOR_CANCELLED;
1003 for(marker= markers->first; marker; marker= marker->next) {
1004 if(marker->flag & SELECT) {
1005 marker->camera= scene->camera;
1010 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
1012 return OPERATOR_FINISHED;
1015 static void MARKER_OT_camera_bind(wmOperatorType *ot)
1018 ot->name= "Bind Camera to Markers";
1019 ot->description= "Bind the active camera to selected markers(s).";
1020 ot->idname= "MARKER_OT_camera_bind";
1023 ot->exec= ed_marker_camera_bind_exec;
1024 ot->poll= ED_operator_areaactive;
1027 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1031 /* ************************** registration **********************************/
1033 /* called in screen_ops.c:ED_operatortypes_screen() */
1034 void ED_operatortypes_marker(void)
1036 WM_operatortype_append(MARKER_OT_add);
1037 WM_operatortype_append(MARKER_OT_move);
1038 WM_operatortype_append(MARKER_OT_duplicate);
1039 WM_operatortype_append(MARKER_OT_select);
1040 WM_operatortype_append(MARKER_OT_select_border);
1041 WM_operatortype_append(MARKER_OT_select_all);
1042 WM_operatortype_append(MARKER_OT_delete);
1043 #ifdef DURIAN_CAMERA_SWITCH
1044 WM_operatortype_append(MARKER_OT_camera_bind);
1048 /* called in screen_ops.c:ED_keymap_screen() */
1049 void ED_marker_keymap(wmKeyConfig *keyconf)
1051 wmKeyMap *keymap= WM_keymap_find(keyconf, "Markers", 0, 0);
1053 WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
1054 WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
1055 WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
1056 WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
1057 RNA_boolean_set(WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
1058 WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0);
1059 WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
1060 WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
1061 WM_keymap_verify_item(keymap, "MARKER_OT_delete", DELKEY, KM_PRESS, 0, 0);
1063 WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
1064 #ifdef DURIAN_CAMERA_SWITCH
1065 WM_keymap_add_item(keymap, "MARKER_OT_camera_bind", HOMEKEY, KM_PRESS, 0, 0);