Merging r38941 through r38950 from trunk into sox-2011-tomato
[blender.git] / source / blender / editors / space_clip / clip_buttons.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2011 Blender Foundation.
21  * All rights reserved.
22  *
23  *
24  * Contributor(s): Blender Foundation,
25  *                 Sergey Sharybin
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/editors/space_clip/clip_buttons.c
31  *  \ingroup spclip
32  */
33
34 #include <string.h>
35 #include <stdio.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_scene_types.h"
40 #include "DNA_screen_types.h"
41 #include "DNA_space_types.h"
42
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45 #include "BLI_listbase.h"
46
47 #include "BKE_context.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_screen.h"
50 #include "BKE_movieclip.h"
51 #include "BKE_tracking.h"
52
53 #include "ED_clip.h"
54
55 #include "UI_interface.h"
56 #include "UI_resources.h"
57
58 #include "RNA_access.h"
59
60 #include "WM_api.h"
61 #include "WM_types.h"
62
63 #include "clip_intern.h"        // own include
64
65 #define B_MARKER_POS                    3
66 #define B_MARKER_OFFSET                 4
67 #define B_MARKER_PAT_DIM                5
68 #define B_MARKER_SEARCH_POS             6
69 #define B_MARKER_SEARCH_DIM             7
70 #define B_MARKER_FLAG                   8
71
72 static void to_pixel_space(float r[2], float a[2], int width, int height)
73 {
74         copy_v2_v2(r, a);
75         r[0]*= width;
76         r[1]*= height;
77 }
78
79 static void trackingMarker_buttons(const bContext *C, uiLayout *layout)
80 {
81         SpaceClip *sc= CTX_wm_space_clip(C);
82         MovieClip *clip= ED_space_clip(sc);
83         int width, height, step, digits, type;
84         MovieTrackingTrack *track;
85         MovieTrackingMarker *marker;
86         float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2];
87         uiBlock *block;
88         uiLayout *col;
89
90         ED_space_clip_size(sc, &width, &height);
91         BKE_movieclip_last_selection(clip, &type, (void**)&track);
92
93         step= 100;
94         digits= 2;
95
96         marker= BKE_tracking_get_marker(track, sc->user.framenr);
97
98         sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min);
99         sub_v2_v2v2(search_dim, track->search_max, track->search_min);
100
101         add_v2_v2v2(search_pos, track->search_max, track->search_min);
102         mul_v2_fl(search_pos, 0.5);
103
104         add_v2_v2v2(pat_pos, track->pat_max, track->pat_min);
105         mul_v2_fl(pat_pos, 0.5);
106
107         to_pixel_space(sc->marker_pos, marker->pos, width, height);
108         to_pixel_space(sc->track_pat, pat_dim, width, height);
109         to_pixel_space(sc->track_search, search_dim, width, height);
110         to_pixel_space(sc->track_search_pos, search_pos, width, height);
111         to_pixel_space(sc->track_offset, track->offset, width, height);
112
113         sc->marker_flag= marker->flag;
114
115         block= uiLayoutAbsoluteBlock(layout);
116
117         uiDefButBitI(block, OPTION, MARKER_DISABLED, B_MARKER_FLAG,  "Disabled", 10, 190, 145, 19, &sc->marker_flag,
118                 0, 0, 0, 0, "Marker is disabled for current frame.");
119
120         col= uiLayoutColumn(layout, 1);
121         uiLayoutSetActive(col, (sc->marker_flag&MARKER_DISABLED)==0);
122
123         block= uiLayoutAbsoluteBlock(col);
124         uiBlockBeginAlign(block);
125
126         uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, "");
127         uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &sc->marker_pos[0],
128                 -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates.");
129         uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &sc->marker_pos[1],
130                 -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates.");
131
132         uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, "");
133         uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &sc->track_offset[0],
134                 -10*width, 10.0*width, step, digits, "X-offset to parenting point.");
135         uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &sc->track_offset[1],
136                 -10*height, 10.0*height, step, digits, "Y-offset to parenting point.");
137
138         uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, "");
139         uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &sc->track_pat[0], 3.0f,
140                 10.0*width, step, digits, "Width of marker's pattern in screen soordinates.");
141         uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &sc->track_pat[1], 3.0f,
142                 10.0*height, step, digits, "Height of marker's pattern in screen soordinates.");
143
144         uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, "");
145         uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &sc->track_search_pos[0],
146                 -width, width, step, digits, "X-position of search at frame relative to marker's position");
147         uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &sc->track_search_pos[1],
148                 -height, height, step, digits, "X-position of search at frame relative to marker's position");
149         uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &sc->track_search[0], 3.0f,
150                 10.0*width, step, digits, "Width of marker's search in screen soordinates.");
151         uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &sc->track_search[1], 3.0f,
152                 10.0*height, step, digits, "Height of marker's search in screen soordinates.");
153
154         uiBlockEndAlign(block);
155 }
156
157 static void do_tracking_marker(bContext *C, void *UNUSED(arg), int event)
158 {
159         SpaceClip *sc= CTX_wm_space_clip(C);
160         MovieClip *clip= ED_space_clip(sc);
161         MovieTrackingTrack *track;
162         MovieTrackingMarker *marker;
163         int width, height, type, ok= 0;
164
165         ED_space_clip_size(sc, &width, &height);
166
167         BKE_movieclip_last_selection(clip, &type, (void**)&track);
168
169         marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
170
171         if(event==B_MARKER_POS) {
172                 marker->pos[0]= sc->marker_pos[0]/width;
173                 marker->pos[1]= sc->marker_pos[1]/height;
174
175                 /* to update position of "parented" objects */
176                 DAG_id_tag_update(&clip->id, 0);
177                 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
178
179                 ok= 1;
180         }
181         else if(event==B_MARKER_PAT_DIM) {
182                 float dim[2], pat_dim[2];
183
184                 sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min);
185
186                 dim[0]= sc->track_pat[0]/width;
187                 dim[1]= sc->track_pat[1]/height;
188
189                 sub_v2_v2(dim, pat_dim);
190                 mul_v2_fl(dim, 0.5f);
191
192                 track->pat_min[0]-= dim[0];
193                 track->pat_min[1]-= dim[1];
194
195                 track->pat_max[0]+= dim[0];
196                 track->pat_max[1]+= dim[1];
197
198                 BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
199
200                 ok= 1;
201         }
202         else if(event==B_MARKER_SEARCH_POS) {
203                 float delta[2], side[2];
204
205                 sub_v2_v2v2(side, track->search_max, track->search_min);
206                 mul_v2_fl(side, 0.5f);
207
208                 delta[0]= sc->track_search_pos[0]/width;
209                 delta[1]= sc->track_search_pos[1]/height;
210
211                 sub_v2_v2v2(track->search_min, delta, side);
212                 add_v2_v2v2(track->search_max, delta, side);
213
214                 BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
215
216                 ok= 1;
217         }
218         else if(event==B_MARKER_SEARCH_DIM) {
219                 float dim[2], search_dim[2];
220
221                 sub_v2_v2v2(search_dim, track->search_max, track->search_min);
222
223                 dim[0]= sc->track_search[0]/width;
224                 dim[1]= sc->track_search[1]/height;
225
226                 sub_v2_v2(dim, search_dim);
227                 mul_v2_fl(dim, 0.5f);
228
229                 track->search_min[0]-= dim[0];
230                 track->search_min[1]-= dim[1];
231
232                 track->search_max[0]+= dim[0];
233                 track->search_max[1]+= dim[1];
234
235                 BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
236
237                 ok= 1;
238         } else if(event==B_MARKER_FLAG) {
239                 marker->flag= sc->marker_flag;
240
241                 ok= 1;
242         } else if(event==B_MARKER_OFFSET) {
243                 track->offset[0]= sc->track_offset[0]/width;
244                 track->offset[1]= sc->track_offset[1]/height;
245
246                 /* to update position of "parented" objects */
247                 DAG_id_tag_update(&clip->id, 0);
248                 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
249
250                 ok= 1;
251         }
252
253         if(ok)
254                 WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
255 }
256
257 /* Panels */
258
259 static int clip_panel_marker_poll(const bContext *C, PanelType *UNUSED(pt))
260 {
261         SpaceClip *sc= CTX_wm_space_clip(C);
262         MovieClip *clip;
263         int type;
264         MovieTrackingTrack *track;
265
266         if(!sc)
267                 return 0;
268
269         clip= ED_space_clip(sc);
270
271         if(!clip || !BKE_movieclip_has_frame(clip, &sc->user))
272                 return 0;
273
274         BKE_movieclip_last_selection(clip, &type, (void**)&track);
275
276         if(type!=MCLIP_SEL_TRACK)
277                 return 0;
278
279         if(track->flag&TRACK_LOCKED)
280                 return 0;
281
282         return 1;
283 }
284
285 static void clip_panel_marker(const bContext *C, Panel *pa)
286 {
287         uiBlock *block;
288
289         block= uiLayoutAbsoluteBlock(pa->layout);
290         uiBlockSetHandleFunc(block, do_tracking_marker, NULL);
291
292         trackingMarker_buttons(C, pa->layout);
293 }
294
295 void ED_clip_buttons_register(ARegionType *art)
296 {
297         PanelType *pt;
298
299         pt= MEM_callocN(sizeof(PanelType), "spacetype clip panel marker");
300         strcpy(pt->idname, "CLIP_PT_marker");
301         strcpy(pt->label, "Marker");
302         pt->draw= clip_panel_marker;
303         pt->poll= clip_panel_marker_poll;
304
305         BLI_addtail(&art->paneltypes, pt);
306 }
307
308 /********************* MovieClip Template ************************/
309
310 void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(userptr), int compact)
311 {
312         PropertyRNA *prop;
313         PointerRNA clipptr;
314         MovieClip *clip;
315         /* MovieClipUser *user; */ /* currently unused */
316         uiLayout *row, *split;
317         uiBlock *block;
318
319         if(!ptr->data)
320                 return;
321
322         prop= RNA_struct_find_property(ptr, propname);
323         if(!prop) {
324                 printf("uiTemplateMovieClip: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
325                 return;
326         }
327
328         if(RNA_property_type(prop) != PROP_POINTER) {
329                 printf("uiTemplateMovieClip: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname);
330                 return;
331         }
332
333         clipptr= RNA_property_pointer_get(ptr, prop);
334         clip= clipptr.data;
335         /* user= userptr->data; */
336
337         uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr);
338
339         if(!compact)
340                 uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL);
341
342         if(clip) {
343                 row= uiLayoutRow(layout, 0);
344                 block= uiLayoutGetBlock(row);
345                 uiDefBut(block, LABEL, 0, "File Path:", 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
346
347                 row= uiLayoutRow(layout, 0);
348                 split = uiLayoutSplit(row, 0.0, 0);
349                 row= uiLayoutRow(split, 1);
350
351                 uiItemR(row, &clipptr, "filepath", 0, "", ICON_NONE);
352                 uiItemO(row, "", ICON_FILE_REFRESH, "clip.reload");
353         }
354 }
355
356 /********************* Marker Template ************************/
357
358 void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
359 {
360         PropertyRNA *prop;
361         PointerRNA scopesptr;
362         uiBlock *block;
363         rctf rect;
364         MovieClipScopes *scopes;
365
366         if(!ptr->data)
367                 return;
368
369         prop= RNA_struct_find_property(ptr, propname);
370         if(!prop) {
371                 printf("uiTemplateTrack: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
372                 return;
373         }
374
375         if(RNA_property_type(prop) != PROP_POINTER) {
376                 printf("uiTemplateTrack: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname);
377                 return;
378         }
379
380         scopesptr= RNA_property_pointer_get(ptr, prop);
381         scopes= (MovieClipScopes *)scopesptr.data;
382
383         rect.xmin= 0; rect.xmax= 200;
384         rect.ymin= 0; rect.ymax= 120;
385
386         block= uiLayoutAbsoluteBlock(layout);
387
388         scopes->track_preview_height= (scopes->track_preview_height<=UI_UNIT_Y)?UI_UNIT_Y:scopes->track_preview_height;
389
390         uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
391 }