6ddf78290aafb6c551ea39f8b2b10c4a4920eea9
[blender-staging.git] / source / blender / editors / space_image / space_image.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_image/space_image.c
28  *  \ingroup spimage
29  */
30
31 #include "DNA_gpencil_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_mask_types.h"
34 #include "DNA_meshdata_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_image_types.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_threads.h"
44
45 #include "BKE_colortools.h"
46 #include "BKE_context.h"
47 #include "BKE_image.h"
48 #include "BKE_library.h"
49 #include "BKE_scene.h"
50 #include "BKE_screen.h"
51
52 #include "IMB_imbuf_types.h"
53
54 #include "ED_image.h"
55 #include "ED_mask.h"
56 #include "ED_mesh.h"
57 #include "ED_node.h"
58 #include "ED_render.h"
59 #include "ED_space_api.h"
60 #include "ED_screen.h"
61 #include "ED_uvedit.h"
62
63 #include "BIF_gl.h"
64
65 #include "RNA_access.h"
66
67 #include "WM_api.h"
68 #include "WM_types.h"
69
70 #include "UI_resources.h"
71 #include "UI_interface.h"
72 #include "UI_view2d.h"
73
74 #include "image_intern.h"
75
76 /**************************** common state *****************************/
77
78 static void image_scopes_tag_refresh(ScrArea *sa)
79 {
80         SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
81         ARegion *ar;
82
83         /* only while histogram is visible */
84         for (ar = sa->regionbase.first; ar; ar = ar->next) {
85                 if (ar->regiontype == RGN_TYPE_TOOLS && ar->flag & RGN_FLAG_HIDDEN)
86                         return;
87         }
88
89         sima->scopes.ok = 0;
90 }
91
92
93 /* ******************** manage regions ********************* */
94
95 ARegion *image_has_buttons_region(ScrArea *sa)
96 {
97         ARegion *ar, *arnew;
98
99         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
100         if (ar) return ar;
101         
102         /* add subdiv level; after header */
103         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
104
105         /* is error! */
106         if (ar == NULL) return NULL;
107         
108         arnew = MEM_callocN(sizeof(ARegion), "buttons for image");
109         
110         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
111         arnew->regiontype = RGN_TYPE_UI;
112         arnew->alignment = RGN_ALIGN_RIGHT;
113         
114         arnew->flag = RGN_FLAG_HIDDEN;
115         
116         return arnew;
117 }
118
119 ARegion *image_has_tools_region(ScrArea *sa)
120 {
121         ARegion *ar, *arnew;
122
123         ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
124         if (ar) return ar;
125
126         /* add subdiv level; after buttons */
127         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
128
129         /* is error! */
130         if (ar == NULL) return NULL;
131         
132         arnew = MEM_callocN(sizeof(ARegion), "scopes for image");
133         
134         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
135         arnew->regiontype = RGN_TYPE_TOOLS;
136         arnew->alignment = RGN_ALIGN_LEFT;
137         
138         arnew->flag = RGN_FLAG_HIDDEN;
139
140         image_scopes_tag_refresh(sa);
141         
142         return arnew;
143 }
144
145 /* ******************** default callbacks for image space ***************** */
146
147 static SpaceLink *image_new(const bContext *UNUSED(C))
148 {
149         ARegion *ar;
150         SpaceImage *simage;
151         
152         simage = MEM_callocN(sizeof(SpaceImage), "initimage");
153         simage->spacetype = SPACE_IMAGE;
154         simage->zoom = 1.0f;
155         simage->lock = true;
156         simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA;
157
158         simage->iuser.ok = true;
159         simage->iuser.fie_ima = 2;
160         simage->iuser.frames = 100;
161         simage->iuser.flag = IMA_SHOW_STEREO;
162
163         scopes_new(&simage->scopes);
164         simage->sample_line_hist.height = 100;
165
166         /* header */
167         ar = MEM_callocN(sizeof(ARegion), "header for image");
168         
169         BLI_addtail(&simage->regionbase, ar);
170         ar->regiontype = RGN_TYPE_HEADER;
171         ar->alignment = RGN_ALIGN_BOTTOM;
172         
173         /* buttons/list view */
174         ar = MEM_callocN(sizeof(ARegion), "buttons for image");
175         
176         BLI_addtail(&simage->regionbase, ar);
177         ar->regiontype = RGN_TYPE_UI;
178         ar->alignment = RGN_ALIGN_RIGHT;
179         ar->flag = RGN_FLAG_HIDDEN;
180         
181         /* scopes/uv sculpt/paint */
182         ar = MEM_callocN(sizeof(ARegion), "buttons for image");
183         
184         BLI_addtail(&simage->regionbase, ar);
185         ar->regiontype = RGN_TYPE_TOOLS;
186         ar->alignment = RGN_ALIGN_LEFT;
187         ar->flag = RGN_FLAG_HIDDEN;
188
189         /* main area */
190         ar = MEM_callocN(sizeof(ARegion), "main area for image");
191         
192         BLI_addtail(&simage->regionbase, ar);
193         ar->regiontype = RGN_TYPE_WINDOW;
194         
195         return (SpaceLink *)simage;
196 }
197
198 /* not spacelink itself */
199 static void image_free(SpaceLink *sl)
200 {       
201         SpaceImage *simage = (SpaceImage *) sl;
202
203         scopes_free(&simage->scopes);
204 }
205
206
207 /* spacetype; init callback, add handlers */
208 static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
209 {
210         ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
211
212         /* add drop boxes */
213         WM_event_add_dropbox_handler(&sa->handlers, lb);
214         
215 }
216
217 static SpaceLink *image_duplicate(SpaceLink *sl)
218 {
219         SpaceImage *simagen = MEM_dupallocN(sl);
220         
221         /* clear or remove stuff from old */
222
223         scopes_new(&simagen->scopes);
224
225         return (SpaceLink *)simagen;
226 }
227
228 static void image_operatortypes(void)
229 {
230         WM_operatortype_append(IMAGE_OT_view_all);
231         WM_operatortype_append(IMAGE_OT_view_pan);
232         WM_operatortype_append(IMAGE_OT_view_selected);
233         WM_operatortype_append(IMAGE_OT_view_zoom);
234         WM_operatortype_append(IMAGE_OT_view_zoom_in);
235         WM_operatortype_append(IMAGE_OT_view_zoom_out);
236         WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
237         WM_operatortype_append(IMAGE_OT_view_zoom_border);
238 #ifdef WITH_INPUT_NDOF
239         WM_operatortype_append(IMAGE_OT_view_ndof);
240 #endif
241
242         WM_operatortype_append(IMAGE_OT_new);
243         WM_operatortype_append(IMAGE_OT_open);
244         WM_operatortype_append(IMAGE_OT_match_movie_length);
245         WM_operatortype_append(IMAGE_OT_replace);
246         WM_operatortype_append(IMAGE_OT_reload);
247         WM_operatortype_append(IMAGE_OT_save);
248         WM_operatortype_append(IMAGE_OT_save_as);
249         WM_operatortype_append(IMAGE_OT_save_sequence);
250         WM_operatortype_append(IMAGE_OT_pack);
251         WM_operatortype_append(IMAGE_OT_unpack);
252         
253         WM_operatortype_append(IMAGE_OT_invert);
254
255         WM_operatortype_append(IMAGE_OT_cycle_render_slot);
256
257         WM_operatortype_append(IMAGE_OT_sample);
258         WM_operatortype_append(IMAGE_OT_sample_line);
259         WM_operatortype_append(IMAGE_OT_curves_point_set);
260
261         WM_operatortype_append(IMAGE_OT_properties);
262         WM_operatortype_append(IMAGE_OT_toolshelf);
263
264         WM_operatortype_append(IMAGE_OT_change_frame);
265
266         WM_operatortype_append(IMAGE_OT_read_renderlayers);
267         WM_operatortype_append(IMAGE_OT_render_border);
268         WM_operatortype_append(IMAGE_OT_clear_render_border);
269 }
270
271 static void image_keymap(struct wmKeyConfig *keyconf)
272 {
273         wmKeyMap *keymap = WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
274         wmKeyMapItem *kmi;
275         int i;
276         
277         WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
278         WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
279         WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
280         WM_keymap_add_item(keymap, "IMAGE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0);
281         WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
282         WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
283         WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
284         WM_keymap_add_item(keymap, "IMAGE_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
285
286         WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
287         RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", true);
288         
289         keymap = WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
290         
291         WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
292
293         kmi = WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, KM_SHIFT, 0);
294         RNA_boolean_set(kmi->ptr, "fit_view", true);
295
296         WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
297         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
298         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
299         WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0);
300
301 #ifdef WITH_INPUT_NDOF
302         WM_keymap_add_item(keymap, "IMAGE_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); // or view selected?
303         WM_keymap_add_item(keymap, "IMAGE_OT_view_ndof", NDOF_MOTION, 0, 0, 0);
304 #endif
305
306         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
307         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
308         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
309         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
310         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
311         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
312         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0);
313         WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
314
315         /* ctrl now works as well, shift + numpad works as arrow keys on Windows */
316         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f);
317         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f);
318         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f);
319         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
320         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
321         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
322
323         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
324         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
325         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
326         RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
327
328         WM_keymap_add_item(keymap, "IMAGE_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
329
330         WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
331         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
332         RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
333
334         /* toggle editmode is handy to have while UV unwrapping */
335         kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
336         RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
337         RNA_boolean_set(kmi->ptr, "toggle", true);
338
339         /* fast switch to render slots */
340         for (i = 0; i < MIN2(IMA_MAX_RENDER_SLOT, 9); i++) {
341                 kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_int", ONEKEY + i, KM_PRESS, 0, 0);
342                 RNA_string_set(kmi->ptr, "data_path", "space_data.image.render_slots.active_index");
343                 RNA_int_set(kmi->ptr, "value", i);
344         }
345
346         /* pivot */
347         kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
348         RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
349         RNA_string_set(kmi->ptr, "value", "CENTER");
350
351         kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, KM_CTRL, 0);
352         RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
353         RNA_string_set(kmi->ptr, "value", "MEDIAN");
354
355         kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0);
356         RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
357         RNA_string_set(kmi->ptr, "value", "CURSOR");
358
359         /* render border */
360         WM_keymap_add_item(keymap, "IMAGE_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0);
361         WM_keymap_add_item(keymap, "IMAGE_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
362 }
363
364 /* dropboxes */
365 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
366 {
367         if (drag->type == WM_DRAG_PATH)
368                 if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
369                         return 1;
370         return 0;
371 }
372
373 static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
374 {
375         /* copy drag path to properties */
376         RNA_string_set(drop->ptr, "filepath", drag->path);
377 }
378
379 /* area+region dropbox definition */
380 static void image_dropboxes(void)
381 {
382         ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
383         
384         WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy);
385 }
386
387 /**
388  * \note take care not to get into feedback loop here,
389  *       calling composite job causes viewer to refresh.
390  */
391 static void image_refresh(const bContext *C, ScrArea *sa)
392 {
393         Scene *scene = CTX_data_scene(C);
394         SpaceImage *sima = sa->spacedata.first;
395         Object *obedit = CTX_data_edit_object(C);
396         Image *ima;
397
398         ima = ED_space_image(sima);
399
400         BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra, 0);
401         
402         /* check if we have to set the image from the editmesh */
403         if (ima && (ima->source == IMA_SRC_VIEWER && sima->mode == SI_MODE_MASK)) {
404                 if (scene->nodetree) {
405                         Mask *mask = ED_space_image_get_mask(sima);
406                         if (mask) {
407                                 ED_node_composite_job(C, scene->nodetree, scene);
408                         }
409                 }
410         }
411         else if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) {
412                 /* pass */
413         }
414         else if (obedit && obedit->type == OB_MESH) {
415                 Mesh *me = (Mesh *)obedit->data;
416                 struct BMEditMesh *em = me->edit_btmesh;
417                 bool sloppy = true; /* partially selected face is ok */
418                 bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); /* only selected active face? */
419
420                 if (BKE_scene_use_new_shading_nodes(scene)) {
421                         /* new shading system does not alter image */
422                 }
423                 else {
424                         /* old shading system, we set texface */
425                         MTexPoly *tf;
426                         
427                         if (em && EDBM_mtexpoly_check(em)) {
428                                 tf = EDBM_mtexpoly_active_get(em, NULL, sloppy, selected);
429
430                                 if (tf) {
431                                         /* don't need to check for pin here, see above */
432                                         sima->image = tf->tpage;
433                                         
434                                         if ((sima->flag & SI_EDITTILE) == 0) {
435                                                 sima->curtile = tf->tile;
436                                         }
437                                 }
438                         }
439                 }
440         }
441 }
442
443 static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
444 {
445         Scene *scene = sc->scene;
446         SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
447         
448         /* context changes */
449         switch (wmn->category) {
450                 case NC_WINDOW:
451                         /* notifier comes from editing color space */
452                         image_scopes_tag_refresh(sa);
453                         ED_area_tag_redraw(sa);
454                         break;
455                 case NC_SCENE:
456                         switch (wmn->data) {
457                                 case ND_FRAME:
458                                         image_scopes_tag_refresh(sa);
459                                         ED_area_tag_refresh(sa);
460                                         ED_area_tag_redraw(sa);
461                                         break;
462                                 case ND_MODE:
463                                         if (wmn->subtype == NS_EDITMODE_MESH)
464                                                 ED_area_tag_refresh(sa);
465                                         ED_area_tag_redraw(sa);
466                                         break;
467                                 case ND_RENDER_RESULT:
468                                 case ND_RENDER_OPTIONS:
469                                 case ND_COMPO_RESULT:
470                                         if (ED_space_image_show_render(sima))
471                                                 image_scopes_tag_refresh(sa);
472                                         ED_area_tag_redraw(sa);
473                                         break;
474                         }
475                         break;
476                 case NC_IMAGE:
477                         if (wmn->reference == sima->image || !wmn->reference) {
478                                 if (wmn->action != NA_PAINTING) {
479                                         image_scopes_tag_refresh(sa);
480                                         ED_area_tag_refresh(sa);
481                                         ED_area_tag_redraw(sa);
482                                 }
483                         }
484                         break;
485                 case NC_SPACE:
486                         if (wmn->data == ND_SPACE_IMAGE) {
487                                 image_scopes_tag_refresh(sa);
488                                 ED_area_tag_redraw(sa);
489                         }
490                         break;
491                 case NC_MASK:
492                 {
493                         // Scene *scene = wmn->window->screen->scene;
494                         /* ideally would check for: ED_space_image_check_show_maskedit(scene, sima) but we cant get the scene */
495                         if (sima->mode == SI_MODE_MASK) {
496                                 switch (wmn->data) {
497                                         case ND_SELECT:
498                                                 ED_area_tag_redraw(sa);
499                                                 break;
500                                         case ND_DATA:
501                                         case ND_DRAW:
502                                                 /* causes node-recalc */
503                                                 ED_area_tag_redraw(sa);
504                                                 ED_area_tag_refresh(sa);
505                                                 break;
506                                 }
507                                 switch (wmn->action) {
508                                         case NA_SELECTED:
509                                                 ED_area_tag_redraw(sa);
510                                                 break;
511                                         case NA_EDITED:
512                                                 /* causes node-recalc */
513                                                 ED_area_tag_redraw(sa);
514                                                 ED_area_tag_refresh(sa);
515                                                 break;
516                                 }
517                         }
518                         break;
519                 }
520                 case NC_GEOM:
521                 {
522                         switch (wmn->data) {
523                                 case ND_DATA:
524                                 case ND_SELECT:
525                                         image_scopes_tag_refresh(sa);
526                                         ED_area_tag_refresh(sa);
527                                         ED_area_tag_redraw(sa);
528                                         break;
529                         }
530                         break;
531                 }
532                 case NC_OBJECT:
533                 {
534                         switch (wmn->data) {
535                                 case ND_TRANSFORM:
536                                 case ND_MODIFIER:
537                                 {
538                                         Object *ob = OBACT;
539                                         if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
540                                                 if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
541                                                         ED_area_tag_refresh(sa);
542                                                         ED_area_tag_redraw(sa);
543                                                 }
544                                         }
545                                         break;
546                                 }
547                         }
548
549                         break;
550                 }
551                 case NC_ID:
552                 {
553                         if (wmn->action == NA_RENAME) {
554                                 ED_area_tag_redraw(sa);
555                         }
556                         break;
557                 }
558                 case NC_WM:
559                         if (wmn->data == ND_UNDO) {
560                                 ED_area_tag_redraw(sa);
561                                 ED_area_tag_refresh(sa);
562                         }
563                         break;
564         }
565 }
566
567 const char *image_context_dir[] = {"edit_image", "edit_mask", NULL};
568
569 static int image_context(const bContext *C, const char *member, bContextDataResult *result)
570 {
571         SpaceImage *sima = CTX_wm_space_image(C);
572
573         if (CTX_data_dir(member)) {
574                 CTX_data_dir_set(result, image_context_dir);
575         }
576         else if (CTX_data_equals(member, "edit_image")) {
577                 CTX_data_id_pointer_set(result, (ID *)ED_space_image(sima));
578                 return 1;
579         }
580         else if (CTX_data_equals(member, "edit_mask")) {
581                 Mask *mask = ED_space_image_get_mask(sima);
582                 if (mask) {
583                         CTX_data_id_pointer_set(result, &mask->id);
584                 }
585                 return true;
586         }
587         return 0;
588 }
589
590 /************************** main region ***************************/
591
592 /* sets up the fields of the View2D from zoom and offset */
593 static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
594 {
595         Image *ima = ED_space_image(sima);
596         float x1, y1, w, h;
597         int width, height, winx, winy;
598         
599 #if 0
600         if (image_preview_active(curarea, &width, &height)) {}
601         else
602 #endif
603         ED_space_image_get_size(sima, &width, &height);
604
605         w = width;
606         h = height;
607         
608         if (ima)
609                 h *= ima->aspy / ima->aspx;
610
611         winx = BLI_rcti_size_x(&ar->winrct) + 1;
612         winy = BLI_rcti_size_y(&ar->winrct) + 1;
613                 
614         ar->v2d.tot.xmin = 0;
615         ar->v2d.tot.ymin = 0;
616         ar->v2d.tot.xmax = w;
617         ar->v2d.tot.ymax = h;
618         
619         ar->v2d.mask.xmin = ar->v2d.mask.ymin = 0;
620         ar->v2d.mask.xmax = winx;
621         ar->v2d.mask.ymax = winy;
622
623         /* which part of the image space do we see? */
624         x1 = ar->winrct.xmin + (winx - sima->zoom * w) / 2.0f;
625         y1 = ar->winrct.ymin + (winy - sima->zoom * h) / 2.0f;
626
627         x1 -= sima->zoom * sima->xof;
628         y1 -= sima->zoom * sima->yof;
629         
630         /* relative display right */
631         ar->v2d.cur.xmin = ((ar->winrct.xmin - (float)x1) / sima->zoom);
632         ar->v2d.cur.xmax = ar->v2d.cur.xmin + ((float)winx / sima->zoom);
633         
634         /* relative display left */
635         ar->v2d.cur.ymin = ((ar->winrct.ymin - (float)y1) / sima->zoom);
636         ar->v2d.cur.ymax = ar->v2d.cur.ymin + ((float)winy / sima->zoom);
637         
638         /* normalize 0.0..1.0 */
639         ar->v2d.cur.xmin /= w;
640         ar->v2d.cur.xmax /= w;
641         ar->v2d.cur.ymin /= h;
642         ar->v2d.cur.ymax /= h;
643 }
644
645 /* add handlers, stuff you only do once or on area/region changes */
646 static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
647 {
648         wmKeyMap *keymap;
649         
650         // image space manages own v2d
651         // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
652
653         /* mask polls mode */
654         keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0);
655         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
656
657         /* image paint polls for mode */
658         keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
659         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
660
661         keymap = WM_keymap_find(wm->defaultconf, "Paint Curve", 0, 0);
662         WM_event_add_keymap_handler(&ar->handlers, keymap);
663
664         keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
665         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
666
667         keymap = WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
668         WM_event_add_keymap_handler(&ar->handlers, keymap);
669         
670         keymap = WM_keymap_find(wm->defaultconf, "UV Sculpt", 0, 0);
671         WM_event_add_keymap_handler(&ar->handlers, keymap);
672
673         /* own keymaps */
674         keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
675         WM_event_add_keymap_handler(&ar->handlers, keymap);
676         keymap = WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
677         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
678
679 }
680
681 static void image_main_region_draw(const bContext *C, ARegion *ar)
682 {
683         /* draw entirely, view changes should be handled here */
684         SpaceImage *sima = CTX_wm_space_image(C);
685         Object *obact = CTX_data_active_object(C);
686         Object *obedit = CTX_data_edit_object(C);
687         Mask *mask = NULL;
688         bool curve = false;
689         Scene *scene = CTX_data_scene(C);
690         View2D *v2d = &ar->v2d;
691         //View2DScrollers *scrollers;
692         float col[3];
693
694         /* XXX not supported yet, disabling for now */
695         scene->r.scemode &= ~R_COMP_CROP;
696         
697         /* clear and setup matrix */
698         UI_GetThemeColor3fv(TH_BACK, col);
699         glClearColor(col[0], col[1], col[2], 0.0);
700         glClear(GL_COLOR_BUFFER_BIT);
701
702         /* put scene context variable in iuser */
703         if (sima->image && sima->image->type == IMA_TYPE_R_RESULT) {
704                 /* for render result, try to use the currently rendering scene */
705                 Scene *render_scene = ED_render_job_get_current_scene(C);
706                 if (render_scene)
707                         sima->iuser.scene = render_scene;
708                 else
709                         sima->iuser.scene = scene;
710         }
711         else
712                 sima->iuser.scene = scene;
713
714         /* we set view2d from own zoom and offset each time */
715         image_main_region_set_view2d(sima, ar);
716
717         /* we draw image in pixelspace */
718         draw_image_main(C, ar);
719
720         /* and uvs in 0.0-1.0 space */
721         UI_view2d_view_ortho(v2d);
722
723         ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
724
725         ED_uvedit_draw_main(sima, ar, scene, obedit, obact);
726
727         /* check for mask (delay draw) */
728         if (ED_space_image_show_uvedit(sima, obedit)) {
729                 /* pass */
730         }
731         else if (sima->mode == SI_MODE_MASK) {
732                 mask = ED_space_image_get_mask(sima);
733         }
734         else if (ED_space_image_paint_curve(C)) {
735                 curve = true;
736         }
737
738         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
739
740         if (sima->flag & SI_SHOW_GPENCIL) {
741                 /* Grease Pencil too (in addition to UV's) */
742                 draw_image_grease_pencil((bContext *)C, true);
743         }
744
745         /* sample line */
746         draw_image_sample_line(sima);
747
748         UI_view2d_view_restore(C);
749
750         if (sima->flag & SI_SHOW_GPENCIL) {
751                 /* draw Grease Pencil - screen space only */
752                 draw_image_grease_pencil((bContext *)C, false);
753         }
754
755         if (mask) {
756                 Image *image = ED_space_image(sima);
757                 int width, height, show_viewer;
758                 float aspx, aspy;
759
760                 show_viewer = (image && image->source == IMA_SRC_VIEWER);
761
762                 if (show_viewer) {
763                         /* ED_space_image_get* will acquire image buffer which requires
764                          * lock here by the same reason why lock is needed in draw_image_main
765                          */
766                         BLI_lock_thread(LOCK_DRAW_IMAGE);
767                 }
768
769                 ED_space_image_get_size(sima, &width, &height);
770                 ED_space_image_get_aspect(sima, &aspx, &aspy);
771
772                 if (show_viewer)
773                         BLI_unlock_thread(LOCK_DRAW_IMAGE);
774
775                 ED_mask_draw_region(mask, ar,
776                                     sima->mask_info.draw_flag,
777                                     sima->mask_info.draw_type,
778                                     sima->mask_info.overlay_mode,
779                                     width, height,
780                                     aspx, aspy,
781                                     true, false,
782                                     NULL, C);
783
784                 UI_view2d_view_ortho(v2d);
785                 ED_image_draw_cursor(ar, sima->cursor);
786                 UI_view2d_view_restore(C);
787         }
788         else if (curve) {
789                 UI_view2d_view_ortho(v2d);
790                 ED_image_draw_cursor(ar, sima->cursor);
791                 UI_view2d_view_restore(C);
792         }
793
794         draw_image_cache(C, ar);
795
796         /* scrollers? */
797 #if 0
798         scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
799         UI_view2d_scrollers_draw(C, v2d, scrollers);
800         UI_view2d_scrollers_free(scrollers);
801 #endif
802 }
803
804 static void image_main_region_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn)
805 {
806         /* context changes */
807         switch (wmn->category) {
808                 case NC_GPENCIL:
809                         if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
810                                 ED_region_tag_redraw(ar);
811                         else if (wmn->data & ND_GPENCIL_EDITMODE)
812                                 ED_region_tag_redraw(ar);
813                         break;
814                 case NC_IMAGE:
815                         if (wmn->action == NA_PAINTING)
816                                 ED_region_tag_redraw(ar);
817                         break;
818                 case NC_MATERIAL:
819                         if (wmn->data == ND_SHADING_LINKS) {
820                                 SpaceImage *sima = sa->spacedata.first;
821
822                                 if (sima->iuser.scene && (sima->iuser.scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE))
823                                         ED_region_tag_redraw(ar);
824                         }
825                         break;
826         }
827 }
828
829 /* *********************** buttons region ************************ */
830
831 /* add handlers, stuff you only do once or on area/region changes */
832 static void image_buttons_region_init(wmWindowManager *wm, ARegion *ar)
833 {
834         wmKeyMap *keymap;
835
836         ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
837         ED_region_panels_init(wm, ar);
838         
839         keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
840         WM_event_add_keymap_handler(&ar->handlers, keymap);
841 }
842
843 static void image_buttons_region_draw(const bContext *C, ARegion *ar)
844 {
845         ED_region_panels(C, ar, NULL, -1, true);
846 }
847
848 static void image_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
849 {
850         /* context changes */
851         switch (wmn->category) {
852                 case NC_TEXTURE:
853                 case NC_MATERIAL:
854                         /* sending by texture render job and needed to properly update displaying
855                          * brush texture icon */
856                         ED_region_tag_redraw(ar);
857                         break;
858                 case NC_SCENE:
859                         switch (wmn->data) {
860                                 case ND_MODE:
861                                 case ND_RENDER_RESULT:
862                                 case ND_COMPO_RESULT:
863                                         ED_region_tag_redraw(ar);
864                                         break;
865                         }
866                         break;
867                 case NC_IMAGE:
868                         if (wmn->action != NA_PAINTING)
869                                 ED_region_tag_redraw(ar);
870                         break;
871                 case NC_NODE:
872                         ED_region_tag_redraw(ar);
873                         break;
874                 case NC_GPENCIL:
875                         if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
876                                 ED_region_tag_redraw(ar);
877                         break;
878         }
879 }
880
881 /* *********************** scopes region ************************ */
882
883 /* add handlers, stuff you only do once or on area/region changes */
884 static void image_tools_region_init(wmWindowManager *wm, ARegion *ar)
885 {
886         wmKeyMap *keymap;
887         
888         ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
889         ED_region_panels_init(wm, ar);
890         
891         keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
892         WM_event_add_keymap_handler(&ar->handlers, keymap);
893 }
894
895 static void image_tools_region_draw(const bContext *C, ARegion *ar)
896 {
897         SpaceImage *sima = CTX_wm_space_image(C);
898         Scene *scene = CTX_data_scene(C);
899         void *lock;
900         ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
901         /* XXX performance regression if name of scopes category changes! */
902         PanelCategoryStack *category = UI_panel_category_active_find(ar, "Scopes");
903
904         /* only update scopes if scope category is active */
905         if (category) {
906                 if (ibuf) {
907                         if (!sima->scopes.ok) {
908                                 BKE_histogram_update_sample_line(&sima->sample_line_hist, ibuf, &scene->view_settings, &scene->display_settings);
909                         }
910                         if (sima->image->flag & IMA_VIEW_AS_RENDER)
911                                 ED_space_image_scopes_update(C, sima, ibuf, true);
912                         else
913                                 ED_space_image_scopes_update(C, sima, ibuf, false);
914                 }
915         }
916         ED_space_image_release_buffer(sima, ibuf, lock);
917         
918         ED_region_panels(C, ar, NULL, -1, true);
919 }
920
921 static void image_tools_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
922 {
923         /* context changes */
924         switch (wmn->category) {
925                 case NC_GPENCIL:
926                         if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED))
927                                 ED_region_tag_redraw(ar);
928                         break;
929                 case NC_BRUSH:
930                         /* NA_SELECTED is used on brush changes */
931                         if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
932                                 ED_region_tag_redraw(ar);
933                         break;
934                 case NC_SCENE:
935                         switch (wmn->data) {
936                                 case ND_MODE:
937                                 case ND_RENDER_RESULT:
938                                 case ND_COMPO_RESULT:
939                                         ED_region_tag_redraw(ar);
940                                         break;
941                         }
942                         break;
943                 case NC_IMAGE:
944                         if (wmn->action != NA_PAINTING)
945                                 ED_region_tag_redraw(ar);
946                         break;
947                 case NC_NODE:
948                         ED_region_tag_redraw(ar);
949                         break;
950                         
951         }
952 }
953
954 /************************* header region **************************/
955
956 /* add handlers, stuff you only do once or on area/region changes */
957 static void image_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
958 {
959         ED_region_header_init(ar);
960 }
961
962 static void image_header_region_draw(const bContext *C, ARegion *ar)
963 {
964         ED_region_header(C, ar);
965 }
966
967 static void image_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
968 {
969         /* context changes */
970         switch (wmn->category) {
971                 case NC_SCENE:
972                         switch (wmn->data) {
973                                 case ND_MODE:
974                                 case ND_TOOLSETTINGS:
975                                         ED_region_tag_redraw(ar);
976                                         break;
977                         }
978                         break;
979                 case NC_GEOM:
980                         switch (wmn->data) {
981                                 case ND_DATA:
982                                 case ND_SELECT:
983                                         ED_region_tag_redraw(ar);
984                                         break;
985                         }
986                         break;
987         }
988 }
989
990 static void image_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
991 {
992         SpaceImage *simg = (SpaceImage *)slink;
993
994         if (!ELEM(GS(old_id->name), ID_IM, ID_GD, ID_MSK)) {
995                 return;
996         }
997
998         if ((ID *)simg->image == old_id) {
999                 simg->image = (Image *)new_id;
1000                 id_us_ensure_real(new_id);
1001         }
1002
1003         if ((ID *)simg->gpd == old_id) {
1004                 simg->gpd = (bGPdata *)new_id;
1005                 id_us_min(old_id);
1006                 id_us_plus(new_id);
1007         }
1008
1009         if ((ID *)simg->mask_info.mask == old_id) {
1010                 simg->mask_info.mask = (Mask *)new_id;
1011                 id_us_ensure_real(new_id);
1012         }
1013 }
1014
1015 /**************************** spacetype *****************************/
1016
1017 /* only called once, from space/spacetypes.c */
1018 void ED_spacetype_image(void)
1019 {
1020         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype image");
1021         ARegionType *art;
1022         
1023         st->spaceid = SPACE_IMAGE;
1024         strncpy(st->name, "Image", BKE_ST_MAXNAME);
1025         
1026         st->new = image_new;
1027         st->free = image_free;
1028         st->init = image_init;
1029         st->duplicate = image_duplicate;
1030         st->operatortypes = image_operatortypes;
1031         st->keymap = image_keymap;
1032         st->dropboxes = image_dropboxes;
1033         st->refresh = image_refresh;
1034         st->listener = image_listener;
1035         st->context = image_context;
1036         st->id_remap = image_id_remap;
1037
1038         /* regions: main window */
1039         art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
1040         art->regionid = RGN_TYPE_WINDOW;
1041         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_GPENCIL;
1042         art->init = image_main_region_init;
1043         art->draw = image_main_region_draw;
1044         art->listener = image_main_region_listener;
1045
1046         BLI_addhead(&st->regiontypes, art);
1047         
1048         /* regions: listview/buttons */
1049         art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
1050         art->regionid = RGN_TYPE_UI;
1051         art->prefsizex = 220; // XXX
1052         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1053         art->listener = image_buttons_region_listener;
1054         art->init = image_buttons_region_init;
1055         art->draw = image_buttons_region_draw;
1056         BLI_addhead(&st->regiontypes, art);
1057
1058         ED_uvedit_buttons_register(art);
1059         image_buttons_register(art);
1060
1061         /* regions: statistics/scope buttons */
1062         art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
1063         art->regionid = RGN_TYPE_TOOLS;
1064         art->prefsizex = 220; // XXX
1065         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
1066         art->listener = image_tools_region_listener;
1067         art->init = image_tools_region_init;
1068         art->draw = image_tools_region_draw;
1069         BLI_addhead(&st->regiontypes, art);
1070
1071         /* regions: header */
1072         art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
1073         art->regionid = RGN_TYPE_HEADER;
1074         art->prefsizey = HEADERY;
1075         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
1076         art->listener = image_header_region_listener;
1077         art->init = image_header_region_init;
1078         art->draw = image_header_region_draw;
1079         
1080         BLI_addhead(&st->regiontypes, art);
1081         
1082         BKE_spacetype_register(st);
1083 }
1084