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