doxygen: prevent GPL license block from being parsed as doxygen comment.
[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_cycle_render_slot);
483
484         WM_operatortype_append(IMAGE_OT_sample);
485         WM_operatortype_append(IMAGE_OT_sample_line);
486         WM_operatortype_append(IMAGE_OT_curves_point_set);
487
488         WM_operatortype_append(IMAGE_OT_record_composite);
489
490         WM_operatortype_append(IMAGE_OT_toolbox);
491         WM_operatortype_append(IMAGE_OT_properties);
492         WM_operatortype_append(IMAGE_OT_scopes);
493 }
494
495 static void image_keymap(struct wmKeyConfig *keyconf)
496 {
497         wmKeyMap *keymap= WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
498         wmKeyMapItem *kmi;
499         
500         WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
501         WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
502         WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
503         WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
504         WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
505         WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
506         WM_keymap_add_item(keymap, "IMAGE_OT_scopes", PKEY, KM_PRESS, 0, 0);
507
508         WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
509         RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", TRUE);
510         
511         keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
512         
513         WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
514         WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
515         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
516         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
517         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0);
518
519         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
520         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
521         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
522         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
523         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
524         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
525
526         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
527         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
528         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
529         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
530         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
531         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
532         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
533
534         WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
535         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
536         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
537
538         WM_keymap_add_item(keymap, "IMAGE_OT_toolbox", SPACEKEY, KM_PRESS, 0, 0);
539
540         /* toggle editmode is handy to have while UV unwrapping */
541         kmi= WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
542         RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
543         RNA_boolean_set(kmi->ptr, "toggle", 1);
544 }
545
546 /* dropboxes */
547 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
548 {
549         if(drag->type==WM_DRAG_PATH)
550                 if(ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK))      /* rule might not work? */
551                         return 1;
552         return 0;
553 }
554
555 static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
556 {
557         /* copy drag path to properties */
558         RNA_string_set(drop->ptr, "filepath", drag->path);
559 }
560
561 /* area+region dropbox definition */
562 static void image_dropboxes(void)
563 {
564         ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
565         
566         WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy);
567 }
568
569
570
571 static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
572 {
573         SpaceImage *sima= CTX_wm_space_image(C);
574         Object *obedit= CTX_data_edit_object(C);
575         Image *ima;
576
577         ima= ED_space_image(sima);
578
579         if(sima->iuser.flag & IMA_ANIM_ALWAYS)
580                 BKE_image_user_calc_frame(&sima->iuser, CTX_data_scene(C)->r.cfra, 0);
581         
582         /* check if we have to set the image from the editmesh */
583         if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
584         else if(obedit && obedit->type == OB_MESH) {
585                 Mesh *me= (Mesh*)obedit->data;
586                 EditMesh *em= BKE_mesh_get_editmesh(me);
587                 MTFace *tf;
588                 
589                 if(em && EM_texFaceCheck(em)) {
590                         sima->image= NULL;
591                         
592                         tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
593                         
594                         if(tf && (tf->mode & TF_TEX)) {
595                                 /* don't need to check for pin here, see above */
596                                 sima->image= tf->tpage;
597                                 
598                                 if(sima->flag & SI_EDITTILE);
599                                 else sima->curtile= tf->tile;
600                         }
601                 }
602
603                 BKE_mesh_end_editmesh(obedit->data, em);
604         }
605 }
606
607 static void image_listener(ScrArea *sa, wmNotifier *wmn)
608 {
609         SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
610         
611         /* context changes */
612         switch(wmn->category) {
613                 case NC_SCENE:
614                         switch(wmn->data) {
615                                 case ND_FRAME:
616                                         image_scopes_tag_refresh(sa);
617                                         ED_area_tag_refresh(sa);
618                                         ED_area_tag_redraw(sa);                                 
619                                         break;
620                                 case ND_MODE:
621                                 case ND_RENDER_RESULT:
622                                 case ND_COMPO_RESULT:
623                                         if (ED_space_image_show_render(sima))
624                                                 image_scopes_tag_refresh(sa);
625                                         ED_area_tag_refresh(sa);
626                                         ED_area_tag_redraw(sa);                                 
627                                         break;
628                         }
629                         break;
630                 case NC_IMAGE:
631                         if (wmn->reference == sima->image || !wmn->reference) {
632                                 image_scopes_tag_refresh(sa);
633                                 ED_area_tag_refresh(sa);
634                                 ED_area_tag_redraw(sa);
635                         }
636                         break;
637                 case NC_SPACE:  
638                         if(wmn->data == ND_SPACE_IMAGE) {
639                                 image_scopes_tag_refresh(sa);
640                                 ED_area_tag_redraw(sa);
641                         }
642                         break;
643                 case NC_GEOM:
644                         switch(wmn->data) {
645                                 case ND_DATA:
646                                 case ND_SELECT:
647                                         image_scopes_tag_refresh(sa);
648                                         ED_area_tag_refresh(sa);
649                                         ED_area_tag_redraw(sa);
650                                         break;
651                         }
652                 case NC_OBJECT:
653                 {
654                         Object *ob= (Object *)wmn->reference;
655                         switch(wmn->data) {
656                                 case ND_TRANSFORM:
657                                 case ND_MODIFIER:
658                                         if(ob && (ob->mode & OB_MODE_EDIT) && sima->lock && (sima->flag & SI_DRAWSHADOW)) {
659                                                 ED_area_tag_refresh(sa);
660                                                 ED_area_tag_redraw(sa);
661                                         }
662                                         break;
663                         }
664                 }
665         }
666 }
667
668 const char *image_context_dir[] = {"edit_image", NULL};
669
670 static int image_context(const bContext *C, const char *member, bContextDataResult *result)
671 {
672         SpaceImage *sima= CTX_wm_space_image(C);
673
674         if(CTX_data_dir(member)) {
675                 CTX_data_dir_set(result, image_context_dir);
676         }
677         else if(CTX_data_equals(member, "edit_image")) {
678                 CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
679                 return 1;
680         }
681
682         return 0;
683 }
684
685 /************************** main region ***************************/
686
687 /* sets up the fields of the View2D from zoom and offset */
688 static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
689 {
690         Image *ima= ED_space_image(sima);
691         float x1, y1, w, h;
692         int width, height, winx, winy;
693         
694 #if 0
695         if(image_preview_active(curarea, &width, &height));
696         else
697 #endif
698         ED_space_image_size(sima, &width, &height);
699
700         w= width;
701         h= height;
702         
703         if(ima)
704                 h *= ima->aspy/ima->aspx;
705
706         winx= ar->winrct.xmax - ar->winrct.xmin + 1;
707         winy= ar->winrct.ymax - ar->winrct.ymin + 1;
708                 
709         ar->v2d.tot.xmin= 0;
710         ar->v2d.tot.ymin= 0;
711         ar->v2d.tot.xmax= w;
712         ar->v2d.tot.ymax= h;
713         
714         ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
715         ar->v2d.mask.xmax= winx;
716         ar->v2d.mask.ymax= winy;
717
718         /* which part of the image space do we see? */
719         x1= ar->winrct.xmin+(winx-sima->zoom*w)/2.0f;
720         y1= ar->winrct.ymin+(winy-sima->zoom*h)/2.0f;
721
722         x1-= sima->zoom*sima->xof;
723         y1-= sima->zoom*sima->yof;
724         
725         /* relative display right */
726         ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sima->zoom);
727         ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sima->zoom);
728         
729         /* relative display left */
730         ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sima->zoom);
731         ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sima->zoom);
732         
733         /* normalize 0.0..1.0 */
734         ar->v2d.cur.xmin /= w;
735         ar->v2d.cur.xmax /= w;
736         ar->v2d.cur.ymin /= h;
737         ar->v2d.cur.ymax /= h;
738 }
739
740 /* add handlers, stuff you only do once or on area/region changes */
741 static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
742 {
743         wmKeyMap *keymap;
744         
745         // image space manages own v2d
746         // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
747
748         /* image paint polls for mode */
749         keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
750         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
751
752         keymap= WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
753         WM_event_add_keymap_handler(&ar->handlers, keymap);
754         
755         /* own keymaps */
756         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
757         WM_event_add_keymap_handler(&ar->handlers, keymap);
758         keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
759         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
760
761 }
762
763 static void image_main_area_draw(const bContext *C, ARegion *ar)
764 {
765         /* draw entirely, view changes should be handled here */
766         SpaceImage *sima= CTX_wm_space_image(C);
767         Object *obedit= CTX_data_edit_object(C);
768         Scene *scene= CTX_data_scene(C);
769         View2D *v2d= &ar->v2d;
770         //View2DScrollers *scrollers;
771         float col[3];
772         
773         /* XXX not supported yet, disabling for now */
774         scene->r.scemode &= ~R_COMP_CROP;
775         
776         /* clear and setup matrix */
777         UI_GetThemeColor3fv(TH_BACK, col);
778         glClearColor(col[0], col[1], col[2], 0.0);
779         glClear(GL_COLOR_BUFFER_BIT);
780
781         /* put scene context variable in iuser */
782         sima->iuser.scene= scene;
783
784         /* we set view2d from own zoom and offset each time */
785         image_main_area_set_view2d(sima, ar);
786         
787         /* we draw image in pixelspace */
788         draw_image_main(sima, ar, scene);
789
790         /* and uvs in 0.0-1.0 space */
791         UI_view2d_view_ortho(v2d);
792         draw_uvedit_main(sima, ar, scene, obedit);
793
794         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
795                 
796         /* Grease Pencil too (in addition to UV's) */
797         draw_image_grease_pencil((bContext *)C, 1); 
798
799         UI_view2d_view_restore(C);
800
801         /* draw Grease Pencil - screen space only */
802         draw_image_grease_pencil((bContext *)C, 0);
803         
804         /* scrollers? */
805         /*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
806         UI_view2d_scrollers_draw(C, v2d, scrollers);
807         UI_view2d_scrollers_free(scrollers);*/
808 }
809
810 static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
811 {
812         /* context changes */
813         switch(wmn->category) {
814                 case NC_SCREEN:
815                         if (wmn->data==ND_GPENCIL)
816                                 ED_region_tag_redraw(ar);
817                 break;
818         }
819 }
820
821 /* *********************** buttons region ************************ */
822
823 /* add handlers, stuff you only do once or on area/region changes */
824 static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
825 {
826         wmKeyMap *keymap;
827
828         ED_region_panels_init(wm, ar);
829         
830         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
831         WM_event_add_keymap_handler(&ar->handlers, keymap);
832 }
833
834 static void image_buttons_area_draw(const bContext *C, ARegion *ar)
835 {
836         ED_region_panels(C, ar, 1, NULL, -1);
837 }
838
839 static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
840 {
841         /* context changes */
842         switch(wmn->category) {
843                 case NC_SCREEN:
844                         if (wmn->data==ND_GPENCIL)
845                                 ED_region_tag_redraw(ar);
846                         break;
847                 case NC_BRUSH:
848                         if(wmn->action==NA_EDITED)
849                                 ED_region_tag_redraw(ar);
850                         break;
851         }
852 }
853
854 /* *********************** scopes region ************************ */
855
856 /* add handlers, stuff you only do once or on area/region changes */
857 static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
858 {
859         wmKeyMap *keymap;
860         
861         ED_region_panels_init(wm, ar);
862         
863         keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
864         WM_event_add_keymap_handler(&ar->handlers, keymap);
865 }
866
867 static void image_scope_area_draw(const bContext *C, ARegion *ar)
868 {
869         SpaceImage *sima= CTX_wm_space_image(C);
870         Scene *scene= CTX_data_scene(C);
871         void *lock;
872         ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
873         if(ibuf) {
874                 scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT );
875         }
876         ED_space_image_release_buffer(sima, lock);
877         
878         ED_region_panels(C, ar, 1, NULL, -1);
879 }
880
881 static void image_scope_area_listener(ARegion *ar, wmNotifier *wmn)
882 {
883         /* context changes */
884         switch(wmn->category) {
885                 case NC_SCENE:
886                         switch(wmn->data) {
887                                 case ND_MODE:
888                                 case ND_RENDER_RESULT:
889                                 case ND_COMPO_RESULT:
890                                         ED_region_tag_redraw(ar);
891                                         break;
892                         }
893                         break;
894                 case NC_IMAGE:
895                         ED_region_tag_redraw(ar);
896                         break;
897                 case NC_NODE:
898                         ED_region_tag_redraw(ar);
899                         break;
900                         
901         }
902 }
903
904 /************************* header region **************************/
905
906 /* add handlers, stuff you only do once or on area/region changes */
907 static void image_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
908 {
909         ED_region_header_init(ar);
910 }
911
912 static void image_header_area_draw(const bContext *C, ARegion *ar)
913 {
914         ED_region_header(C, ar);
915 }
916
917 static void image_header_area_listener(ARegion *ar, wmNotifier *wmn)
918 {
919         /* context changes */
920         switch(wmn->category) {
921                 case NC_SCENE:
922                         switch(wmn->data) {
923                                 case ND_MODE:
924                                 case ND_TOOLSETTINGS:
925                                         ED_region_tag_redraw(ar);
926                                         break;
927                         }
928                         break;
929                 case NC_GEOM:
930                         switch(wmn->data) {
931                                 case ND_DATA:
932                                 case ND_SELECT:
933                                         ED_region_tag_redraw(ar);
934                                         break;
935                         }
936                         
937         }
938 }
939
940 /**************************** spacetype *****************************/
941
942 /* only called once, from space/spacetypes.c */
943 void ED_spacetype_image(void)
944 {
945         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype image");
946         ARegionType *art;
947         
948         st->spaceid= SPACE_IMAGE;
949         strncpy(st->name, "Image", BKE_ST_MAXNAME);
950         
951         st->new= image_new;
952         st->free= image_free;
953         st->init= image_init;
954         st->duplicate= image_duplicate;
955         st->operatortypes= image_operatortypes;
956         st->keymap= image_keymap;
957         st->dropboxes= image_dropboxes;
958         st->refresh= image_refresh;
959         st->listener= image_listener;
960         st->context= image_context;
961         
962         /* regions: main window */
963         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
964         art->regionid = RGN_TYPE_WINDOW;
965         art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL;
966         art->init= image_main_area_init;
967         art->draw= image_main_area_draw;
968         art->listener= image_main_area_listener;
969
970         BLI_addhead(&st->regiontypes, art);
971         
972         /* regions: listview/buttons */
973         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
974         art->regionid = RGN_TYPE_UI;
975         art->prefsizex= 220; // XXX
976         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
977         art->listener= image_buttons_area_listener;
978         art->init= image_buttons_area_init;
979         art->draw= image_buttons_area_draw;
980         BLI_addhead(&st->regiontypes, art);
981
982         image_buttons_register(art);
983         
984         /* regions: statistics/scope buttons */
985         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
986         art->regionid = RGN_TYPE_PREVIEW;
987         art->prefsizex= 220; // XXX
988         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
989         art->listener= image_scope_area_listener;
990         art->init= image_scope_area_init;
991         art->draw= image_scope_area_draw;
992         BLI_addhead(&st->regiontypes, art);
993
994         /* regions: header */
995         art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
996         art->regionid = RGN_TYPE_HEADER;
997         art->prefsizey= HEADERY;
998         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
999         art->listener= image_header_area_listener;
1000         art->init= image_header_area_init;
1001         art->draw= image_header_area_draw;
1002         
1003         BLI_addhead(&st->regiontypes, art);
1004         
1005         BKE_spacetype_register(st);
1006 }
1007