cc81d7ac97531c66377e6aa7ca93979fd51ee405
[blender.git] / source / blender / editors / space_image / space_image.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) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_meshdata_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_math.h"
40 #include "BLI_editVert.h"
41 #include "BLI_rand.h"
42 #include "BLI_utildefines.h"
43
44 #include "BKE_colortools.h"
45 #include "BKE_context.h"
46 #include "BKE_image.h"
47 #include "BKE_mesh.h"
48 #include "BKE_screen.h"
49
50 #include "IMB_imbuf_types.h"
51
52 #include "ED_image.h"
53 #include "ED_mesh.h"
54 #include "ED_space_api.h"
55 #include "ED_screen.h"
56 #include "ED_uvedit.h"
57
58 #include "BIF_gl.h"
59
60 #include "RNA_access.h"
61
62 #include "WM_api.h"
63 #include "WM_types.h"
64
65 #include "UI_resources.h"
66 #include "UI_view2d.h"
67
68 #include "image_intern.h"
69
70 /**************************** common state *****************************/
71
72 /* note; image_panel_properties() uses pointer to sima->image directly */
73 Image *ED_space_image(SpaceImage *sima)
74 {
75         return sima->image;
76 }
77
78 /* called to assign images to UV faces */
79 void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
80 {
81         ED_uvedit_assign_image(scene, obedit, ima, sima->image);
82         
83         /* change the space ima after because uvedit_face_visible uses the space ima
84          * to check if the face is displayed in UV-localview */
85         sima->image= ima;
86         
87         if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
88                 sima->flag &= ~SI_DRAWTOOL;
89         
90         if(sima->image)
91                 BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
92         
93         if(sima->image && sima->image->id.us==0)
94                 sima->image->id.us= 1;
95         
96         if(C) {
97                 if(obedit)
98                         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
99                 
100                 ED_area_tag_redraw(CTX_wm_area(C));
101                 
102         }
103 }
104
105 ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
106 {
107         ImBuf *ibuf;
108         
109         if(sima && sima->image) {
110 #if 0
111                 if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
112                         return BIF_render_spare_imbuf();
113                 else
114 #endif
115                         ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
116                 
117                 if(ibuf && (ibuf->rect || ibuf->rect_float))
118                         return ibuf;
119         }
120         
121         return NULL;
122 }
123
124 void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
125 {
126         if(sima && sima->image)
127                 BKE_image_release_ibuf(sima->image, lock);
128 }
129
130 int ED_space_image_has_buffer(SpaceImage *sima)
131 {
132         ImBuf *ibuf;
133         void *lock;
134         int has_buffer;
135         
136         ibuf= ED_space_image_acquire_buffer(sima, &lock);
137         has_buffer= (ibuf != NULL);
138         ED_space_image_release_buffer(sima, lock);
139         
140         return has_buffer;
141 }
142
143 void ED_image_size(Image *ima, int *width, int *height)
144 {
145         ImBuf *ibuf= NULL;
146         void *lock;
147         
148         if(ima)
149                 ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
150         
151         if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
152                 *width= ibuf->x;
153                 *height= ibuf->y;
154         }
155         else {
156                 *width= 256;
157                 *height= 256;
158         }
159         
160         if(ima)
161                 BKE_image_release_ibuf(ima, lock);
162 }
163
164 void ED_space_image_size(SpaceImage *sima, int *width, int *height)
165 {
166         Scene *scene= sima->iuser.scene;
167         ImBuf *ibuf;
168         void *lock;
169         
170         ibuf= ED_space_image_acquire_buffer(sima, &lock);
171         
172         if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
173                 *width= ibuf->x;
174                 *height= ibuf->y;
175         }
176         else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
177                 /* not very important, just nice */
178                 *width= (scene->r.xsch*scene->r.size)/100;
179                 *height= (scene->r.ysch*scene->r.size)/100;
180
181                 if((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) {
182                         *width *= (scene->r.border.xmax - scene->r.border.xmin);
183                         *height *= (scene->r.border.ymax - scene->r.border.ymin);
184                 }
185
186         }
187         /* I know a bit weak... but preview uses not actual image size */
188         // XXX else if(image_preview_active(sima, width, height));
189         else {
190                 *width= 256;
191                 *height= 256;
192         }
193         
194         ED_space_image_release_buffer(sima, lock);
195 }
196
197 void ED_image_aspect(Image *ima, float *aspx, float *aspy)
198 {
199         *aspx= *aspy= 1.0;
200         
201         if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
202            (ima->aspx==0.0 || ima->aspy==0.0))
203                 return;
204         
205         /* x is always 1 */
206         *aspy = ima->aspy/ima->aspx;
207 }
208
209 void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
210 {
211         ED_image_aspect(ED_space_image(sima), aspx, aspy);
212 }
213
214 void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
215 {
216         int width, height;
217         
218         ED_space_image_size(sima, &width, &height);
219         
220         *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
221         *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
222 }
223
224 void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
225 {
226         int w, h;
227         
228         ED_space_image_aspect(sima, aspx, aspy);
229         ED_space_image_size(sima, &w, &h);
230
231         *aspx *= (float)w;
232         *aspy *= (float)h;
233         
234         if(*aspx < *aspy) {
235                 *aspy= *aspy / *aspx;
236                 *aspx= 1.0f;
237         }
238         else {
239                 *aspx= *aspx / *aspy;
240                 *aspy= 1.0f;            
241         }
242 }
243
244 void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy)
245 {
246         int w, h;
247         
248         ED_image_aspect(ima, aspx, aspy);
249         ED_image_size(ima, &w, &h);
250         
251         *aspx *= (float)w;
252         *aspy *= (float)h;
253 }
254
255 int ED_space_image_show_render(SpaceImage *sima)
256 {
257         return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
258 }
259
260 int ED_space_image_show_paint(SpaceImage *sima)
261 {
262         if(ED_space_image_show_render(sima))
263                 return 0;
264         
265         return (sima->flag & SI_DRAWTOOL);
266 }
267
268 int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
269 {
270         if(sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima)))
271                 return 0;
272
273         if(obedit && obedit->type == OB_MESH) {
274                 EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
275                 int ret;
276                 
277                 ret = EM_texFaceCheck(em);
278                 
279                 BKE_mesh_end_editmesh(obedit->data, em);
280                 return ret;
281         }
282         
283         return 0;
284 }
285
286 int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
287 {
288         if(ED_space_image_show_render(sima))
289                 return 0;
290         
291         if(ED_space_image_show_paint(sima))
292                 if(obedit && obedit->type == OB_MESH) {
293                         EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
294                         int ret;
295                         
296                         ret = EM_texFaceCheck(em);
297                         
298                         BKE_mesh_end_editmesh(obedit->data, em);
299                         return ret;
300                 }
301         
302         return 0;
303 }
304
305
306 static void image_scopes_tag_refresh(ScrArea *sa)
307 {
308         SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
309         ARegion *ar;
310
311         /* only while histogram is visible */
312         for (ar=sa->regionbase.first; ar; ar=ar->next) {
313                 if (ar->regiontype == RGN_TYPE_PREVIEW && ar->flag & RGN_FLAG_HIDDEN)
314                         return;
315         }
316
317         sima->scopes.ok=0;
318 }
319
320
321 /* ******************** manage regions ********************* */
322
323 ARegion *image_has_buttons_region(ScrArea *sa)
324 {
325         ARegion *ar, *arnew;
326         
327         for(ar= sa->regionbase.first; ar; ar= ar->next)
328                 if(ar->regiontype==RGN_TYPE_UI)
329                         return ar;
330         
331         /* add subdiv level; after header */
332         for(ar= sa->regionbase.first; ar; ar= ar->next)
333                 if(ar->regiontype==RGN_TYPE_HEADER)
334                         break;
335         
336         /* is error! */
337         if(ar==NULL) return NULL;
338         
339         arnew= MEM_callocN(sizeof(ARegion), "buttons for image");
340         
341         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
342         arnew->regiontype= RGN_TYPE_UI;
343         arnew->alignment= RGN_ALIGN_LEFT;
344         
345         arnew->flag = RGN_FLAG_HIDDEN;
346         
347         return arnew;
348 }
349
350 ARegion *image_has_scope_region(ScrArea *sa)
351 {
352         ARegion *ar, *arnew;
353         
354         for(ar= sa->regionbase.first; ar; ar= ar->next)
355                 if(ar->regiontype==RGN_TYPE_PREVIEW)
356                         return ar;
357         
358         /* add subdiv level; after buttons */
359         for(ar= sa->regionbase.first; ar; ar= ar->next)
360                 if(ar->regiontype==RGN_TYPE_UI)
361                         break;
362         
363         /* is error! */
364         if(ar==NULL) return NULL;
365         
366         arnew= MEM_callocN(sizeof(ARegion), "scopes for image");
367         
368         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
369         arnew->regiontype= RGN_TYPE_PREVIEW;
370         arnew->alignment= RGN_ALIGN_RIGHT;
371         
372         arnew->flag = RGN_FLAG_HIDDEN;
373
374         image_scopes_tag_refresh(sa);
375         
376         return arnew;
377 }
378
379 /* ******************** default callbacks for image space ***************** */
380
381 static SpaceLink *image_new(const bContext *UNUSED(C))
382 {
383         ARegion *ar;
384         SpaceImage *simage;
385         
386         simage= MEM_callocN(sizeof(SpaceImage), "initimage");
387         simage->spacetype= SPACE_IMAGE;
388         simage->zoom= 1;
389         simage->lock= 1;
390         
391         simage->iuser.ok= 1;
392         simage->iuser.fie_ima= 2;
393         simage->iuser.frames= 100;
394         
395         scopes_new(&simage->scopes);
396         simage->sample_line_hist.height= 100;
397
398         /* header */
399         ar= MEM_callocN(sizeof(ARegion), "header for image");
400         
401         BLI_addtail(&simage->regionbase, ar);
402         ar->regiontype= RGN_TYPE_HEADER;
403         ar->alignment= RGN_ALIGN_BOTTOM;
404         
405         /* buttons/list view */
406         ar= MEM_callocN(sizeof(ARegion), "buttons for image");
407         
408         BLI_addtail(&simage->regionbase, ar);
409         ar->regiontype= RGN_TYPE_UI;
410         ar->alignment= RGN_ALIGN_LEFT;
411         ar->flag = RGN_FLAG_HIDDEN;
412         
413         /* scopes */
414         ar= MEM_callocN(sizeof(ARegion), "buttons for image");
415         
416         BLI_addtail(&simage->regionbase, ar);
417         ar->regiontype= RGN_TYPE_PREVIEW;
418         ar->alignment= RGN_ALIGN_RIGHT;
419         ar->flag = RGN_FLAG_HIDDEN;
420
421         /* main area */
422         ar= MEM_callocN(sizeof(ARegion), "main area for image");
423         
424         BLI_addtail(&simage->regionbase, ar);
425         ar->regiontype= RGN_TYPE_WINDOW;
426         
427         return (SpaceLink *)simage;
428 }
429
430 /* not spacelink itself */
431 static void image_free(SpaceLink *sl)
432 {       
433         SpaceImage *simage= (SpaceImage*) sl;
434         
435         if(simage->cumap)
436                 curvemapping_free(simage->cumap);
437         scopes_free(&simage->scopes);
438 }
439
440
441 /* spacetype; init callback, add handlers */
442 static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
443 {
444         ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
445
446         /* add drop boxes */
447         WM_event_add_dropbox_handler(&sa->handlers, lb);
448         
449 }
450
451 static SpaceLink *image_duplicate(SpaceLink *sl)
452 {
453         SpaceImage *simagen= MEM_dupallocN(sl);
454         
455         /* clear or remove stuff from old */
456         if(simagen->cumap)
457                 simagen->cumap= curvemapping_copy(simagen->cumap);
458         
459         return (SpaceLink *)simagen;
460 }
461
462 static void image_operatortypes(void)
463 {
464         WM_operatortype_append(IMAGE_OT_view_all);
465         WM_operatortype_append(IMAGE_OT_view_pan);
466         WM_operatortype_append(IMAGE_OT_view_selected);
467         WM_operatortype_append(IMAGE_OT_view_zoom);
468         WM_operatortype_append(IMAGE_OT_view_zoom_in);
469         WM_operatortype_append(IMAGE_OT_view_zoom_out);
470         WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
471
472         WM_operatortype_append(IMAGE_OT_new);
473         WM_operatortype_append(IMAGE_OT_open);
474         WM_operatortype_append(IMAGE_OT_replace);
475         WM_operatortype_append(IMAGE_OT_reload);
476         WM_operatortype_append(IMAGE_OT_save);
477         WM_operatortype_append(IMAGE_OT_save_as);
478         WM_operatortype_append(IMAGE_OT_save_sequence);
479         WM_operatortype_append(IMAGE_OT_pack);
480         WM_operatortype_append(IMAGE_OT_unpack);
481         
482         WM_operatortype_append(IMAGE_OT_invert);
483
484         WM_operatortype_append(IMAGE_OT_cycle_render_slot);
485
486         WM_operatortype_append(IMAGE_OT_sample);
487         WM_operatortype_append(IMAGE_OT_sample_line);
488         WM_operatortype_append(IMAGE_OT_curves_point_set);
489
490         WM_operatortype_append(IMAGE_OT_record_composite);
491
492         WM_operatortype_append(IMAGE_OT_toolbox);
493         WM_operatortype_append(IMAGE_OT_properties);
494         WM_operatortype_append(IMAGE_OT_scopes);
495 }
496
497 static void image_keymap(struct wmKeyConfig *keyconf)
498 {
499         wmKeyMap *keymap= WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
500         wmKeyMapItem *kmi;
501         
502         WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
503         WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
504         WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
505         WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
506         WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
507         WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
508         WM_keymap_add_item(keymap, "IMAGE_OT_scopes", PKEY, KM_PRESS, 0, 0);
509
510         WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
511         RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", TRUE);
512         
513         keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
514         
515         WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
516         WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
517         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
518         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
519         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0);
520
521         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
522         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
523         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
524         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
525         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
526         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
527
528         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
529         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
530         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
531         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
532         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
533         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
534         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
535
536         WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
537         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
538         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
539
540         WM_keymap_add_item(keymap, "IMAGE_OT_toolbox", SPACEKEY, KM_PRESS, 0, 0);
541
542         /* toggle editmode is handy to have while UV unwrapping */
543         kmi= WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
544         RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
545         RNA_boolean_set(kmi->ptr, "toggle", 1);
546 }
547
548 /* dropboxes */
549 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
550 {
551         if(drag->type==WM_DRAG_PATH)
552                 if(ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK))      /* rule might not work? */
553                         return 1;
554         return 0;
555 }
556
557 static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
558 {
559         /* copy drag path to properties */
560         RNA_string_set(drop->ptr, "filepath", drag->path);
561 }
562
563 /* area+region dropbox definition */
564 static void image_dropboxes(void)
565 {
566         ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
567         
568         WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy);
569 }
570
571
572
573 static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
574 {
575         SpaceImage *sima= CTX_wm_space_image(C);
576         Object *obedit= CTX_data_edit_object(C);
577         Image *ima;
578
579         ima= ED_space_image(sima);
580
581         if(sima->iuser.flag & IMA_ANIM_ALWAYS)
582                 BKE_image_user_calc_frame(&sima->iuser, CTX_data_scene(C)->r.cfra, 0);
583         
584         /* check if we have to set the image from the editmesh */
585         if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
586         else if(obedit && obedit->type == OB_MESH) {
587                 Mesh *me= (Mesh*)obedit->data;
588                 EditMesh *em= BKE_mesh_get_editmesh(me);
589                 MTFace *tf;
590                 
591                 if(em && EM_texFaceCheck(em)) {
592                         sima->image= NULL;
593                         
594                         tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
595                         
596                         if(tf && (tf->mode & TF_TEX)) {
597                                 /* don't need to check for pin here, see above */
598                                 sima->image= tf->tpage;
599                                 
600                                 if(sima->flag & SI_EDITTILE);
601                                 else sima->curtile= tf->tile;
602                         }
603                 }
604
605                 BKE_mesh_end_editmesh(obedit->data, em);
606         }
607 }
608
609 static void image_listener(ScrArea *sa, wmNotifier *wmn)
610 {
611         SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
612         
613         /* context changes */
614         switch(wmn->category) {
615                 case NC_SCENE:
616                         switch(wmn->data) {
617                                 case ND_FRAME:
618                                         image_scopes_tag_refresh(sa);
619                                         ED_area_tag_refresh(sa);
620                                         ED_area_tag_redraw(sa);                                 
621                                         break;
622                                 case ND_MODE:
623                                 case ND_RENDER_RESULT:
624                                 case ND_COMPO_RESULT:
625                                         if (ED_space_image_show_render(sima))
626                                                 image_scopes_tag_refresh(sa);
627                                         ED_area_tag_refresh(sa);
628                                         ED_area_tag_redraw(sa);                                 
629                                         break;
630                         }
631                         break;
632                 case NC_IMAGE:
633                         if (wmn->reference == sima->image || !wmn->reference) {
634                                 image_scopes_tag_refresh(sa);
635                                 ED_area_tag_refresh(sa);
636                                 ED_area_tag_redraw(sa);
637                         }
638                         break;
639                 case NC_SPACE:  
640                         if(wmn->data == ND_SPACE_IMAGE) {
641                                 image_scopes_tag_refresh(sa);
642                                 ED_area_tag_redraw(sa);
643                         }
644                         break;
645                 case NC_GEOM:
646                         switch(wmn->data) {
647                                 case ND_DATA:
648                                 case ND_SELECT:
649                                         image_scopes_tag_refresh(sa);
650                                         ED_area_tag_refresh(sa);
651                                         ED_area_tag_redraw(sa);
652                                         break;
653                         }
654                 case NC_OBJECT:
655                 {
656                         Object *ob= (Object *)wmn->reference;
657                         switch(wmn->data) {
658                                 case ND_TRANSFORM:
659                                 case ND_MODIFIER:
660                                         if(ob && (ob->mode & OB_MODE_EDIT) && sima->lock && (sima->flag & SI_DRAWSHADOW)) {
661                                                 ED_area_tag_refresh(sa);
662                                                 ED_area_tag_redraw(sa);
663                                         }
664                                         break;
665                         }
666                 }
667         }
668 }
669
670 const char *image_context_dir[] = {"edit_image", NULL};
671
672 static int image_context(const bContext *C, const char *member, bContextDataResult *result)
673 {
674         SpaceImage *sima= CTX_wm_space_image(C);
675
676         if(CTX_data_dir(member)) {
677                 CTX_data_dir_set(result, image_context_dir);
678         }
679         else if(CTX_data_equals(member, "edit_image")) {
680                 CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
681                 return 1;
682         }
683
684         return 0;
685 }
686
687 /************************** main region ***************************/
688
689 /* sets up the fields of the View2D from zoom and offset */
690 static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
691 {
692         Image *ima= ED_space_image(sima);
693         float x1, y1, w, h;
694         int width, height, winx, winy;
695         
696 #if 0
697         if(image_preview_active(curarea, &width, &height));
698         else
699 #endif
700         ED_space_image_size(sima, &width, &height);
701
702         w= width;
703         h= height;
704         
705         if(ima)
706                 h *= ima->aspy/ima->aspx;
707
708         winx= ar->winrct.xmax - ar->winrct.xmin + 1;
709         winy= ar->winrct.ymax - ar->winrct.ymin + 1;
710                 
711         ar->v2d.tot.xmin= 0;
712         ar->v2d.tot.ymin= 0;
713         ar->v2d.tot.xmax= w;
714         ar->v2d.tot.ymax= h;
715         
716         ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
717         ar->v2d.mask.xmax= winx;
718         ar->v2d.mask.ymax= winy;
719
720         /* which part of the image space do we see? */
721         x1= ar->winrct.xmin+(winx-sima->zoom*w)/2.0f;
722         y1= ar->winrct.ymin+(winy-sima->zoom*h)/2.0f;
723
724         x1-= sima->zoom*sima->xof;
725         y1-= sima->zoom*sima->yof;
726         
727         /* relative display right */
728         ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sima->zoom);
729         ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sima->zoom);
730         
731         /* relative display left */
732         ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sima->zoom);
733         ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sima->zoom);
734         
735         /* normalize 0.0..1.0 */
736         ar->v2d.cur.xmin /= w;
737         ar->v2d.cur.xmax /= w;
738         ar->v2d.cur.ymin /= h;
739         ar->v2d.cur.ymax /= h;
740 }
741
742 /* add handlers, stuff you only do once or on area/region changes */
743 static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
744 {
745         wmKeyMap *keymap;
746         
747         // image space manages own v2d
748         // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
749
750         /* image paint polls for mode */
751         keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
752         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
753
754         keymap= WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
755         WM_event_add_keymap_handler(&ar->handlers, keymap);
756         
757         /* own keymaps */
758         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
759         WM_event_add_keymap_handler(&ar->handlers, keymap);
760         keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
761         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
762
763 }
764
765 static void image_main_area_draw(const bContext *C, ARegion *ar)
766 {
767         /* draw entirely, view changes should be handled here */
768         SpaceImage *sima= CTX_wm_space_image(C);
769         Object *obedit= CTX_data_edit_object(C);
770         Scene *scene= CTX_data_scene(C);
771         View2D *v2d= &ar->v2d;
772         //View2DScrollers *scrollers;
773         float col[3];
774         
775         /* XXX not supported yet, disabling for now */
776         scene->r.scemode &= ~R_COMP_CROP;
777         
778         /* clear and setup matrix */
779         UI_GetThemeColor3fv(TH_BACK, col);
780         glClearColor(col[0], col[1], col[2], 0.0);
781         glClear(GL_COLOR_BUFFER_BIT);
782
783         /* put scene context variable in iuser */
784         sima->iuser.scene= scene;
785
786         /* we set view2d from own zoom and offset each time */
787         image_main_area_set_view2d(sima, ar);
788         
789         /* we draw image in pixelspace */
790         draw_image_main(sima, ar, scene);
791
792         /* and uvs in 0.0-1.0 space */
793         UI_view2d_view_ortho(v2d);
794         draw_uvedit_main(sima, ar, scene, obedit);
795
796         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
797                 
798         /* Grease Pencil too (in addition to UV's) */
799         draw_image_grease_pencil((bContext *)C, 1); 
800
801         UI_view2d_view_restore(C);
802
803         /* draw Grease Pencil - screen space only */
804         draw_image_grease_pencil((bContext *)C, 0);
805         
806         /* scrollers? */
807         /*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
808         UI_view2d_scrollers_draw(C, v2d, scrollers);
809         UI_view2d_scrollers_free(scrollers);*/
810 }
811
812 static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
813 {
814         /* context changes */
815         switch(wmn->category) {
816                 case NC_SCREEN:
817                         if (wmn->data==ND_GPENCIL)
818                                 ED_region_tag_redraw(ar);
819                 break;
820         }
821 }
822
823 /* *********************** buttons region ************************ */
824
825 /* add handlers, stuff you only do once or on area/region changes */
826 static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
827 {
828         wmKeyMap *keymap;
829
830         ED_region_panels_init(wm, ar);
831         
832         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
833         WM_event_add_keymap_handler(&ar->handlers, keymap);
834 }
835
836 static void image_buttons_area_draw(const bContext *C, ARegion *ar)
837 {
838         ED_region_panels(C, ar, 1, NULL, -1);
839 }
840
841 static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
842 {
843         /* context changes */
844         switch(wmn->category) {
845                 case NC_SCREEN:
846                         if (wmn->data==ND_GPENCIL)
847                                 ED_region_tag_redraw(ar);
848                         break;
849                 case NC_BRUSH:
850                         if(wmn->action==NA_EDITED)
851                                 ED_region_tag_redraw(ar);
852                         break;
853         }
854 }
855
856 /* *********************** scopes region ************************ */
857
858 /* add handlers, stuff you only do once or on area/region changes */
859 static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
860 {
861         wmKeyMap *keymap;
862         
863         ED_region_panels_init(wm, ar);
864         
865         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
866         WM_event_add_keymap_handler(&ar->handlers, keymap);
867 }
868
869 static void image_scope_area_draw(const bContext *C, ARegion *ar)
870 {
871         SpaceImage *sima= CTX_wm_space_image(C);
872         Scene *scene= CTX_data_scene(C);
873         void *lock;
874         ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
875         if(ibuf) {
876                 scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT );
877         }
878         ED_space_image_release_buffer(sima, lock);
879         
880         ED_region_panels(C, ar, 1, NULL, -1);
881 }
882
883 static void image_scope_area_listener(ARegion *ar, wmNotifier *wmn)
884 {
885         /* context changes */
886         switch(wmn->category) {
887                 case NC_SCENE:
888                         switch(wmn->data) {
889                                 case ND_MODE:
890                                 case ND_RENDER_RESULT:
891                                 case ND_COMPO_RESULT:
892                                         ED_region_tag_redraw(ar);
893                                         break;
894                         }
895                         break;
896                 case NC_IMAGE:
897                         ED_region_tag_redraw(ar);
898                         break;
899                 case NC_NODE:
900                         ED_region_tag_redraw(ar);
901                         break;
902                         
903         }
904 }
905
906 /************************* header region **************************/
907
908 /* add handlers, stuff you only do once or on area/region changes */
909 static void image_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
910 {
911         ED_region_header_init(ar);
912 }
913
914 static void image_header_area_draw(const bContext *C, ARegion *ar)
915 {
916         ED_region_header(C, ar);
917 }
918
919 static void image_header_area_listener(ARegion *ar, wmNotifier *wmn)
920 {
921         /* context changes */
922         switch(wmn->category) {
923                 case NC_SCENE:
924                         switch(wmn->data) {
925                                 case ND_MODE:
926                                 case ND_TOOLSETTINGS:
927                                         ED_region_tag_redraw(ar);
928                                         break;
929                         }
930                         break;
931                 case NC_GEOM:
932                         switch(wmn->data) {
933                                 case ND_DATA:
934                                 case ND_SELECT:
935                                         ED_region_tag_redraw(ar);
936                                         break;
937                         }
938                         
939         }
940 }
941
942 /**************************** spacetype *****************************/
943
944 /* only called once, from space/spacetypes.c */
945 void ED_spacetype_image(void)
946 {
947         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype image");
948         ARegionType *art;
949         
950         st->spaceid= SPACE_IMAGE;
951         strncpy(st->name, "Image", BKE_ST_MAXNAME);
952         
953         st->new= image_new;
954         st->free= image_free;
955         st->init= image_init;
956         st->duplicate= image_duplicate;
957         st->operatortypes= image_operatortypes;
958         st->keymap= image_keymap;
959         st->dropboxes= image_dropboxes;
960         st->refresh= image_refresh;
961         st->listener= image_listener;
962         st->context= image_context;
963         
964         /* regions: main window */
965         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
966         art->regionid = RGN_TYPE_WINDOW;
967         art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL;
968         art->init= image_main_area_init;
969         art->draw= image_main_area_draw;
970         art->listener= image_main_area_listener;
971
972         BLI_addhead(&st->regiontypes, art);
973         
974         /* regions: listview/buttons */
975         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
976         art->regionid = RGN_TYPE_UI;
977         art->prefsizex= 220; // XXX
978         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
979         art->listener= image_buttons_area_listener;
980         art->init= image_buttons_area_init;
981         art->draw= image_buttons_area_draw;
982         BLI_addhead(&st->regiontypes, art);
983
984         image_buttons_register(art);
985         
986         /* regions: statistics/scope buttons */
987         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
988         art->regionid = RGN_TYPE_PREVIEW;
989         art->prefsizex= 220; // XXX
990         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
991         art->listener= image_scope_area_listener;
992         art->init= image_scope_area_init;
993         art->draw= image_scope_area_draw;
994         BLI_addhead(&st->regiontypes, art);
995
996         /* regions: header */
997         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
998         art->regionid = RGN_TYPE_HEADER;
999         art->prefsizey= HEADERY;
1000         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
1001         art->listener= image_header_area_listener;
1002         art->init= image_header_area_init;
1003         art->draw= image_header_area_draw;
1004         
1005         BLI_addhead(&st->regiontypes, art);
1006         
1007         BKE_spacetype_register(st);
1008 }
1009