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