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 if (flag & DRAW_MARKERS_LINES) {
247 if (marker->flag & SELECT)
248 glColor4ub(255, 255, 255, 96);
250 glColor4ub(0, 0, 0, 96);
253 glVertex2f((xpos*xscale)+0.5f, 12.0f);
254 glVertex2f((xpos*xscale)+0.5f, 34.0f*yscale); /* a bit lazy but we know it cant be greater then 34 strips high */
260 /* 5 px to offset icon to align properly, space / pixels corrects for zoom */
261 if (flag & DRAW_MARKERS_LOCAL) {
262 icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
263 (marker->flag & SELECT) ? ICON_PMARKER_SEL :
267 icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT :
271 UI_icon_draw(xpos*xscale-5.0f, 16.0f, icon_id);
273 glBlendFunc(GL_ONE, GL_ZERO);
276 /* and the marker name too, shifted slightly to the top-right */
277 if (marker->name && marker->name[0]) {
280 if (marker->flag & SELECT) {
281 UI_ThemeColor(TH_TEXT_HI);
282 x= xpos*xscale + 4.0f;
283 y= (ypixels <= 39.0f)? (ypixels-10.0f) : 29.0f;
286 UI_ThemeColor(TH_TEXT);
287 if((marker->frame <= cfra) && (marker->frame+5 > cfra)) {
288 x= xpos*xscale + 4.0f;
289 y= (ypixels <= 39.0f)? (ypixels - 10.0f) : 29.0f;
292 x= xpos*xscale + 4.0f;
296 UI_DrawString(x, y, marker->name);
299 glScalef(xscale, 1.0f, 1.0f);
302 /* Draw Scene-Markers in time window */
303 void draw_markers_time(const bContext *C, int flag)
305 ListBase *markers= context_get_markers(C);
306 View2D *v2d= UI_view2d_fromcontext(C);
312 /* unselected markers are drawn at the first time */
313 for (marker= markers->first; marker; marker= marker->next) {
314 if ((marker->flag & SELECT) == 0)
315 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag);
318 /* selected markers are drawn later */
319 for (marker= markers->first; marker; marker= marker->next) {
320 if (marker->flag & SELECT)
321 draw_marker(v2d, marker, CTX_data_scene(C)->r.cfra, flag);
325 /* ************************** add markers *************************** */
327 /* add TimeMarker at curent frame */
328 static int ed_marker_add(bContext *C, wmOperator *op)
330 ListBase *markers= context_get_markers(C);
332 int frame= CTX_data_scene(C)->r.cfra;
335 return OPERATOR_CANCELLED;
337 /* two markers can't be at the same place */
338 for (marker= markers->first; marker; marker= marker->next) {
339 if (marker->frame == frame)
340 return OPERATOR_CANCELLED;
344 for(marker= markers->first; marker; marker= marker->next)
345 marker->flag &= ~SELECT;
347 marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
348 marker->flag= SELECT;
349 marker->frame= frame;
350 sprintf(marker->name, "Frame %d", frame); // XXX - temp code only
351 BLI_addtail(markers, marker);
353 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
355 return OPERATOR_FINISHED;
358 static void MARKER_OT_add(wmOperatorType *ot)
361 ot->name= "Add Time Marker";
362 ot->idname= "MARKER_OT_add";
365 ot->exec= ed_marker_add;
366 ot->poll= ED_operator_areaactive;
369 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
372 /* ************************** transform markers *************************** */
375 /* operator state vars used:
380 init() check selection, add customdata with old values and some lookups
382 apply() do the actual movement
384 exit() cleanup, send notifier
386 cancel() to escpae from modal
390 exec() calls init, apply, exit
392 invoke() calls init, adds modal handler
394 modal() accept modal events while doing it, ends with apply and exit, or cancel
398 typedef struct MarkerMove {
401 int event_type; /* store invoke-event, to verify */
402 int *oldframe, evtx, firstx;
405 /* copy selection to temp buffer */
406 /* return 0 if not OK */
407 static int ed_marker_move_init(bContext *C, wmOperator *op)
409 ListBase *markers= context_get_markers(C);
415 if(markers == NULL) return 0;
417 for (marker= markers->first; marker; marker= marker->next)
418 if (marker->flag & SELECT) totmark++;
420 if (totmark==0) return 0;
422 op->customdata= mm= MEM_callocN(sizeof(MarkerMove), "Markermove");
423 mm->slink= CTX_wm_space_data(C);
424 mm->markers= markers;
425 mm->oldframe= MEM_callocN(totmark*sizeof(int), "MarkerMove oldframe");
427 for (a=0, marker= markers->first; marker; marker= marker->next) {
428 if (marker->flag & SELECT) {
429 mm->oldframe[a]= marker->frame;
438 static void ed_marker_move_exit(bContext *C, wmOperator *op)
440 MarkerMove *mm= op->customdata;
443 MEM_freeN(mm->oldframe);
444 MEM_freeN(op->customdata);
445 op->customdata= NULL;
447 /* clear custom header prints */
448 ED_area_headerprint(CTX_wm_area(C), NULL);
451 static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
453 if(ed_marker_move_init(C, op)) {
454 MarkerMove *mm= op->customdata;
458 mm->event_type= evt->type;
460 /* add temp handler */
461 WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
463 /* reset frs delta */
464 RNA_int_set(op->ptr, "frames", 0);
466 return OPERATOR_RUNNING_MODAL;
469 return OPERATOR_CANCELLED;
472 /* note, init has to be called succesfully */
473 static void ed_marker_move_apply(bContext *C, wmOperator *op)
475 MarkerMove *mm= op->customdata;
479 offs= RNA_int_get(op->ptr, "frames");
480 for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
481 if (marker->flag & SELECT) {
482 marker->frame= mm->oldframe[a] + offs;
489 static void ed_marker_move_cancel(bContext *C, wmOperator *op)
491 RNA_int_set(op->ptr, "frames", 0);
492 ed_marker_move_apply(C, op);
493 ed_marker_move_exit(C, op);
495 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
500 static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
502 Scene *scene= CTX_data_scene(C);
503 MarkerMove *mm= op->customdata;
504 View2D *v2d= UI_view2d_fromcontext(C);
505 TimeMarker *marker, *selmarker=NULL;
511 ed_marker_move_cancel(C, op);
512 return OPERATOR_CANCELLED;
517 if(WM_modal_tweak_exit(evt, mm->event_type)) {
518 ed_marker_move_exit(C, op);
519 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
520 return OPERATOR_FINISHED;
525 dx= v2d->mask.xmax-v2d->mask.xmin;
526 dx= (v2d->cur.xmax-v2d->cur.xmin)/dx;
528 if (evt->x != mm->evtx) { /* XXX maybe init for firsttime */
529 int a, offs, totmark=0;
533 fac= ((float)(evt->x - mm->firstx)*dx);
535 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND))
536 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0);
538 apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID);
541 RNA_int_set(op->ptr, "frames", offs);
542 ed_marker_move_apply(C, op);
544 /* cruft below is for header print */
545 for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
546 if (marker->flag & SELECT) {
553 /* we print current marker value */
554 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
555 SpaceTime *stime= (SpaceTime *)mm->slink;
556 if (stime->flag & TIME_DRAWFRAMES)
557 sprintf(str, "Marker %d offset %d", selmarker->frame, offs);
559 sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
561 else if (mm->slink->spacetype == SPACE_ACTION) {
562 SpaceAction *saction= (SpaceAction *)mm->slink;
563 if (saction->flag & SACTION_DRAWTIME)
564 sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
566 sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
569 sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
573 /* we only print the offset */
574 if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
575 SpaceTime *stime= (SpaceTime *)mm->slink;
576 if (stime->flag & TIME_DRAWFRAMES)
577 sprintf(str, "Marker offset %d ", offs);
579 sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
581 else if (mm->slink->spacetype == SPACE_ACTION) {
582 SpaceAction *saction= (SpaceAction *)mm->slink;
583 if (saction->flag & SACTION_DRAWTIME)
584 sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
586 sprintf(str, "Marker offset %.2f ", (double)(offs));
589 sprintf(str, "Marker offset %.2f ", (double)(offs));
593 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
594 ED_area_headerprint(CTX_wm_area(C), str);
598 return OPERATOR_RUNNING_MODAL;
601 static int ed_marker_move_exec(bContext *C, wmOperator *op)
603 if(ed_marker_move_init(C, op)) {
604 ed_marker_move_apply(C, op);
605 ed_marker_move_exit(C, op);
606 return OPERATOR_FINISHED;
608 return OPERATOR_PASS_THROUGH;
611 static void MARKER_OT_move(wmOperatorType *ot)
614 ot->name= "Move Time Marker";
615 ot->idname= "MARKER_OT_move";
618 ot->exec= ed_marker_move_exec;
619 ot->invoke= ed_marker_move_invoke;
620 ot->modal= ed_marker_move_modal;
621 ot->poll= ED_operator_areaactive;
624 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
627 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
630 /* ************************** duplicate markers *************************** */
632 /* operator state vars used:
637 apply() do the actual duplicate
641 exec() calls apply, move_exec
643 invoke() calls apply, move_invoke
645 modal() uses move_modal
650 /* duplicate selected TimeMarkers */
651 static void ed_marker_duplicate_apply(bContext *C, wmOperator *op)
653 ListBase *markers= context_get_markers(C);
654 TimeMarker *marker, *newmarker;
659 /* go through the list of markers, duplicate selected markers and add duplicated copies
660 * to the begining of the list (unselect original markers)
662 for (marker= markers->first; marker; marker= marker->next) {
663 if (marker->flag & SELECT) {
664 /* unselect selected marker */
665 marker->flag &= ~SELECT;
667 /* create and set up new marker */
668 newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
669 newmarker->flag= SELECT;
670 newmarker->frame= marker->frame;
671 BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
673 /* new marker is added to the begining of list */
674 BLI_addhead(markers, newmarker);
679 static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
681 ed_marker_duplicate_apply(C, op);
682 ed_marker_move_exec(C, op); /* assumes frs delta set */
684 return OPERATOR_FINISHED;
688 static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt)
690 ed_marker_duplicate_apply(C, op);
691 return ed_marker_move_invoke(C, op, evt);
694 static void MARKER_OT_duplicate(wmOperatorType *ot)
697 ot->name= "Duplicate Time Marker";
698 ot->idname= "MARKER_OT_duplicate";
701 ot->exec= ed_marker_duplicate_exec;
702 ot->invoke= ed_marker_duplicate_invoke;
703 ot->modal= ed_marker_move_modal;
704 ot->poll= ED_operator_areaactive;
707 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
710 RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
713 /* ************************** selection ************************************/
715 /* select/deselect TimeMarker at current frame */
716 static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned char shift)
721 for (marker= markers->first; marker; marker= marker->next) {
722 /* if Shift is not set, then deselect Markers */
723 if (!shift) marker->flag &= ~SELECT;
725 /* this way a not-shift select will allways give 1 selected marker */
726 if ((marker->frame == frame) && (!select)) {
727 if (marker->flag & SELECT)
728 marker->flag &= ~SELECT;
730 marker->flag |= SELECT;
736 static int ed_marker_select(bContext *C, wmEvent *evt, int extend)
738 ListBase *markers= context_get_markers(C);
739 View2D *v2d= UI_view2d_fromcontext(C);
744 return OPERATOR_PASS_THROUGH;
746 x= evt->x - CTX_wm_region(C)->winrct.xmin;
747 y= evt->y - CTX_wm_region(C)->winrct.ymin;
749 UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
751 cfra= ED_markers_find_nearest_marker_time(markers, viewx);
754 select_timeline_marker_frame(markers, cfra, 1);
756 select_timeline_marker_frame(markers, cfra, 0);
758 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
760 /* allowing tweaks */
761 return OPERATOR_PASS_THROUGH;
764 static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
766 short extend= RNA_boolean_get(op->ptr, "extend");
767 return ed_marker_select(C, evt, extend);
770 static void MARKER_OT_select(wmOperatorType *ot)
773 ot->name= "Select Time Marker";
774 ot->idname= "MARKER_OT_select";
777 ot->invoke= ed_marker_select_invoke;
778 ot->poll= ED_operator_areaactive;
781 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
783 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "extend the selection");
786 /* *************************** border select markers **************** */
788 /* operator state vars used: (added by default WM callbacks)
792 customdata: the wmGesture pointer, with subwindow
796 exec() has to be filled in by user
798 invoke() default WM function
801 modal() default WM function
802 accept modal events while doing it, calls exec(), handles ESC and border drawing
804 poll() has to be filled in by user for context
807 static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
809 View2D *v2d= UI_view2d_fromcontext(C);
810 ListBase *markers= context_get_markers(C);
812 float xminf, xmaxf, yminf, ymaxf;
813 int event_type= RNA_int_get(op->ptr, "event_type");
814 int xmin= RNA_int_get(op->ptr, "xmin");
815 int xmax= RNA_int_get(op->ptr, "xmax");
816 int ymin= RNA_int_get(op->ptr, "ymin");
817 int ymax= RNA_int_get(op->ptr, "ymax");
819 UI_view2d_region_to_view(v2d, xmin, ymin, &xminf, &yminf);
820 UI_view2d_region_to_view(v2d, xmax, ymax, &xmaxf, &ymaxf);
823 if(yminf > 30.0f || ymaxf < 0.0f)
829 /* XXX marker context */
830 for(marker= markers->first; marker; marker= marker->next) {
831 if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
833 switch (event_type) {
835 if ((marker->flag & SELECT) == 0)
836 marker->flag |= SELECT;
839 if (marker->flag & SELECT)
840 marker->flag &= ~SELECT;
846 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
851 static void MARKER_OT_select_border(wmOperatorType *ot)
854 ot->name= "Marker Border select";
855 ot->idname= "MARKER_OT_select_border";
858 ot->exec= ed_marker_border_select_exec;
859 ot->invoke= WM_border_select_invoke;
860 ot->modal= WM_border_select_modal;
862 ot->poll= ED_operator_areaactive;
865 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
868 RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
869 RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
870 RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
871 RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
872 RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
875 /* *********************** (de)select all ***************** */
877 static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
879 ListBase *markers= context_get_markers(C);
881 int select= RNA_int_get(op->ptr, "select_type");
884 return OPERATOR_CANCELLED;
886 if(RNA_boolean_get(op->ptr, "select_swap")) {
887 for(marker= markers->first; marker; marker= marker->next) {
888 if(marker->flag & SELECT)
897 for(marker= markers->first; marker; marker= marker->next) {
899 marker->flag |= SELECT;
901 marker->flag &= ~SELECT;
904 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
906 return OPERATOR_FINISHED;
909 static int ed_marker_select_all_invoke(bContext *C, wmOperator *op, wmEvent *evt)
911 RNA_boolean_set(op->ptr, "select_swap", 1);
913 return ed_marker_select_all_exec(C, op);
916 static void MARKER_OT_select_all_toggle(wmOperatorType *ot)
919 ot->name= "(De)select all markers";
920 ot->idname= "MARKER_OT_select_all_toggle";
923 ot->exec= ed_marker_select_all_exec;
924 ot->invoke= ed_marker_select_all_invoke;
925 ot->poll= ED_operator_areaactive;
928 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
931 RNA_def_boolean(ot->srna, "select_swap", 0, "Select Swap", "");
932 RNA_def_int(ot->srna, "select_type", 0, INT_MIN, INT_MAX, "Select Type", "", INT_MIN, INT_MAX);
935 /* ******************************* remove marker ***************** */
937 /* remove selected TimeMarkers */
938 static int ed_marker_delete_exec(bContext *C, wmOperator *op)
940 ListBase *markers= context_get_markers(C);
941 TimeMarker *marker, *nmarker;
945 return OPERATOR_CANCELLED;
947 for(marker= markers->first; marker; marker= nmarker) {
948 nmarker= marker->next;
949 if(marker->flag & SELECT) {
950 BLI_freelinkN(markers, marker);
956 WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
958 return OPERATOR_FINISHED;
962 static void MARKER_OT_delete(wmOperatorType *ot)
965 ot->name= "Delete Markers";
966 ot->idname= "MARKER_OT_delete";
969 ot->invoke= WM_operator_confirm;
970 ot->exec= ed_marker_delete_exec;
971 ot->poll= ED_operator_areaactive;
974 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
978 /* ************************** registration **********************************/
980 /* called in screen_ops.c:ED_operatortypes_screen() */
981 void ED_operatortypes_marker(void)
983 WM_operatortype_append(MARKER_OT_add);
984 WM_operatortype_append(MARKER_OT_move);
985 WM_operatortype_append(MARKER_OT_duplicate);
986 WM_operatortype_append(MARKER_OT_select);
987 WM_operatortype_append(MARKER_OT_select_border);
988 WM_operatortype_append(MARKER_OT_select_all_toggle);
989 WM_operatortype_append(MARKER_OT_delete);
992 /* called in screen_ops.c:ED_keymap_screen() */
993 void ED_marker_keymap(wmWindowManager *wm)
995 ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
997 WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
998 WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
999 WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
1000 WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
1001 RNA_boolean_set(WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
1002 WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0);
1003 WM_keymap_verify_item(keymap, "MARKER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
1004 WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
1006 WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);