Blender V2.61 - r43446

space_image.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2008 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 #include <stdio.h>
00034 
00035 #include "DNA_meshdata_types.h"
00036 #include "DNA_object_types.h"
00037 #include "DNA_scene_types.h"
00038 
00039 #include "MEM_guardedalloc.h"
00040 
00041 #include "BLI_blenlib.h"
00042 #include "BLI_math.h"
00043 #include "BLI_editVert.h"
00044 #include "BLI_rand.h"
00045 #include "BLI_utildefines.h"
00046 
00047 #include "BKE_colortools.h"
00048 #include "BKE_context.h"
00049 #include "BKE_image.h"
00050 #include "BKE_global.h"
00051 #include "BKE_main.h"
00052 #include "BKE_mesh.h"
00053 #include "BKE_scene.h"
00054 #include "BKE_screen.h"
00055 
00056 #include "IMB_imbuf_types.h"
00057 
00058 #include "ED_image.h"
00059 #include "ED_mesh.h"
00060 #include "ED_space_api.h"
00061 #include "ED_screen.h"
00062 #include "ED_uvedit.h"
00063 
00064 #include "BIF_gl.h"
00065 
00066 #include "RNA_access.h"
00067 
00068 #include "WM_api.h"
00069 #include "WM_types.h"
00070 
00071 #include "UI_resources.h"
00072 #include "UI_view2d.h"
00073 
00074 #include "image_intern.h"
00075 
00076 /**************************** common state *****************************/
00077 
00078 /* note; image_panel_properties() uses pointer to sima->image directly */
00079 Image *ED_space_image(SpaceImage *sima)
00080 {
00081     return sima->image;
00082 }
00083 
00084 /* called to assign images to UV faces */
00085 void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
00086 {
00087     /* context may be NULL, so use global */
00088     ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image);
00089     
00090     /* change the space ima after because uvedit_face_visible uses the space ima
00091      * to check if the face is displayed in UV-localview */
00092     sima->image= ima;
00093     
00094     if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
00095         sima->flag &= ~SI_DRAWTOOL;
00096     
00097     if(sima->image)
00098         BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
00099     
00100     if(sima->image && sima->image->id.us==0)
00101         sima->image->id.us= 1;
00102     
00103     if(obedit)
00104         WM_main_add_notifier(NC_GEOM|ND_DATA, obedit->data);
00105 
00106     WM_main_add_notifier(NC_SPACE|ND_SPACE_IMAGE, NULL);
00107 }
00108 
00109 ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
00110 {
00111     ImBuf *ibuf;
00112     
00113     if(sima && sima->image) {
00114 #if 0
00115         if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
00116             return BIF_render_spare_imbuf();
00117         else
00118 #endif
00119             ibuf= BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
00120         
00121         if(ibuf && (ibuf->rect || ibuf->rect_float))
00122             return ibuf;
00123     }
00124     
00125     return NULL;
00126 }
00127 
00128 void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
00129 {
00130     if(sima && sima->image)
00131         BKE_image_release_ibuf(sima->image, lock);
00132 }
00133 
00134 int ED_space_image_has_buffer(SpaceImage *sima)
00135 {
00136     ImBuf *ibuf;
00137     void *lock;
00138     int has_buffer;
00139     
00140     ibuf= ED_space_image_acquire_buffer(sima, &lock);
00141     has_buffer= (ibuf != NULL);
00142     ED_space_image_release_buffer(sima, lock);
00143     
00144     return has_buffer;
00145 }
00146 
00147 void ED_image_size(Image *ima, int *width, int *height)
00148 {
00149     ImBuf *ibuf= NULL;
00150     void *lock;
00151     
00152     if(ima)
00153         ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock);
00154     
00155     if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
00156         *width= ibuf->x;
00157         *height= ibuf->y;
00158     }
00159     else {
00160         *width= 256;
00161         *height= 256;
00162     }
00163     
00164     if(ima)
00165         BKE_image_release_ibuf(ima, lock);
00166 }
00167 
00168 void ED_space_image_size(SpaceImage *sima, int *width, int *height)
00169 {
00170     Scene *scene= sima->iuser.scene;
00171     ImBuf *ibuf;
00172     void *lock;
00173     
00174     ibuf= ED_space_image_acquire_buffer(sima, &lock);
00175     
00176     if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
00177         *width= ibuf->x;
00178         *height= ibuf->y;
00179     }
00180     else if(sima->image && sima->image->type==IMA_TYPE_R_RESULT && scene) {
00181         /* not very important, just nice */
00182         *width= (scene->r.xsch*scene->r.size)/100;
00183         *height= (scene->r.ysch*scene->r.size)/100;
00184 
00185         if((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) {
00186             *width *= (scene->r.border.xmax - scene->r.border.xmin);
00187             *height *= (scene->r.border.ymax - scene->r.border.ymin);
00188         }
00189 
00190     }
00191     /* I know a bit weak... but preview uses not actual image size */
00192     // XXX else if(image_preview_active(sima, width, height));
00193     else {
00194         *width= 256;
00195         *height= 256;
00196     }
00197     
00198     ED_space_image_release_buffer(sima, lock);
00199 }
00200 
00201 void ED_image_aspect(Image *ima, float *aspx, float *aspy)
00202 {
00203     *aspx= *aspy= 1.0;
00204     
00205     if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) ||
00206        (ima->aspx==0.0f || ima->aspy==0.0f))
00207         return;
00208     
00209     /* x is always 1 */
00210     *aspy = ima->aspy/ima->aspx;
00211 }
00212 
00213 void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy)
00214 {
00215     ED_image_aspect(ED_space_image(sima), aspx, aspy);
00216 }
00217 
00218 void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
00219 {
00220     int width, height;
00221     
00222     ED_space_image_size(sima, &width, &height);
00223     
00224     *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
00225     *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
00226 }
00227 
00228 void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
00229 {
00230     int w, h;
00231     
00232     ED_space_image_aspect(sima, aspx, aspy);
00233     ED_space_image_size(sima, &w, &h);
00234 
00235     *aspx *= (float)w;
00236     *aspy *= (float)h;
00237     
00238     if(*aspx < *aspy) {
00239         *aspy= *aspy / *aspx;
00240         *aspx= 1.0f;
00241     }
00242     else {
00243         *aspx= *aspx / *aspy;
00244         *aspy= 1.0f;        
00245     }
00246 }
00247 
00248 void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy)
00249 {
00250     int w, h;
00251     
00252     ED_image_aspect(ima, aspx, aspy);
00253     ED_image_size(ima, &w, &h);
00254     
00255     *aspx *= (float)w;
00256     *aspy *= (float)h;
00257 }
00258 
00259 int ED_space_image_show_render(SpaceImage *sima)
00260 {
00261     return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
00262 }
00263 
00264 int ED_space_image_show_paint(SpaceImage *sima)
00265 {
00266     if(ED_space_image_show_render(sima))
00267         return 0;
00268     
00269     return (sima->flag & SI_DRAWTOOL);
00270 }
00271 
00272 int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
00273 {
00274     if(sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima)))
00275         return 0;
00276 
00277     if(obedit && obedit->type == OB_MESH) {
00278         EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
00279         int ret;
00280         
00281         ret = EM_texFaceCheck(em);
00282         
00283         BKE_mesh_end_editmesh(obedit->data, em);
00284         return ret;
00285     }
00286     
00287     return 0;
00288 }
00289 
00290 int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
00291 {
00292     if(ED_space_image_show_render(sima))
00293         return 0;
00294     
00295     if(ED_space_image_show_paint(sima))
00296         if(obedit && obedit->type == OB_MESH) {
00297             EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
00298             int ret;
00299             
00300             ret = EM_texFaceCheck(em);
00301             
00302             BKE_mesh_end_editmesh(obedit->data, em);
00303             return ret;
00304         }
00305     
00306     return 0;
00307 }
00308 
00309 
00310 static void image_scopes_tag_refresh(ScrArea *sa)
00311 {
00312     SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
00313     ARegion *ar;
00314 
00315     /* only while histogram is visible */
00316     for (ar=sa->regionbase.first; ar; ar=ar->next) {
00317         if (ar->regiontype == RGN_TYPE_PREVIEW && ar->flag & RGN_FLAG_HIDDEN)
00318             return;
00319     }
00320 
00321     sima->scopes.ok=0;
00322 }
00323 
00324 
00325 /* ******************** manage regions ********************* */
00326 
00327 ARegion *image_has_buttons_region(ScrArea *sa)
00328 {
00329     ARegion *ar, *arnew;
00330 
00331     ar= BKE_area_find_region_type(sa, RGN_TYPE_UI);
00332     if(ar) return ar;
00333     
00334     /* add subdiv level; after header */
00335     ar= BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
00336 
00337     /* is error! */
00338     if(ar==NULL) return NULL;
00339     
00340     arnew= MEM_callocN(sizeof(ARegion), "buttons for image");
00341     
00342     BLI_insertlinkafter(&sa->regionbase, ar, arnew);
00343     arnew->regiontype= RGN_TYPE_UI;
00344     arnew->alignment= RGN_ALIGN_LEFT;
00345     
00346     arnew->flag = RGN_FLAG_HIDDEN;
00347     
00348     return arnew;
00349 }
00350 
00351 ARegion *image_has_scope_region(ScrArea *sa)
00352 {
00353     ARegion *ar, *arnew;
00354 
00355     ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
00356     if(ar) return ar;
00357 
00358     /* add subdiv level; after buttons */
00359     ar= BKE_area_find_region_type(sa, RGN_TYPE_UI);
00360 
00361     /* is error! */
00362     if(ar==NULL) return NULL;
00363     
00364     arnew= MEM_callocN(sizeof(ARegion), "scopes for image");
00365     
00366     BLI_insertlinkafter(&sa->regionbase, ar, arnew);
00367     arnew->regiontype= RGN_TYPE_PREVIEW;
00368     arnew->alignment= RGN_ALIGN_RIGHT;
00369     
00370     arnew->flag = RGN_FLAG_HIDDEN;
00371 
00372     image_scopes_tag_refresh(sa);
00373     
00374     return arnew;
00375 }
00376 
00377 /* ******************** default callbacks for image space ***************** */
00378 
00379 static SpaceLink *image_new(const bContext *UNUSED(C))
00380 {
00381     ARegion *ar;
00382     SpaceImage *simage;
00383     
00384     simage= MEM_callocN(sizeof(SpaceImage), "initimage");
00385     simage->spacetype= SPACE_IMAGE;
00386     simage->zoom= 1;
00387     simage->lock= 1;
00388     
00389     simage->iuser.ok= 1;
00390     simage->iuser.fie_ima= 2;
00391     simage->iuser.frames= 100;
00392     
00393     scopes_new(&simage->scopes);
00394     simage->sample_line_hist.height= 100;
00395 
00396     /* header */
00397     ar= MEM_callocN(sizeof(ARegion), "header for image");
00398     
00399     BLI_addtail(&simage->regionbase, ar);
00400     ar->regiontype= RGN_TYPE_HEADER;
00401     ar->alignment= RGN_ALIGN_BOTTOM;
00402     
00403     /* buttons/list view */
00404     ar= MEM_callocN(sizeof(ARegion), "buttons for image");
00405     
00406     BLI_addtail(&simage->regionbase, ar);
00407     ar->regiontype= RGN_TYPE_UI;
00408     ar->alignment= RGN_ALIGN_LEFT;
00409     ar->flag = RGN_FLAG_HIDDEN;
00410     
00411     /* scopes */
00412     ar= MEM_callocN(sizeof(ARegion), "buttons for image");
00413     
00414     BLI_addtail(&simage->regionbase, ar);
00415     ar->regiontype= RGN_TYPE_PREVIEW;
00416     ar->alignment= RGN_ALIGN_RIGHT;
00417     ar->flag = RGN_FLAG_HIDDEN;
00418 
00419     /* main area */
00420     ar= MEM_callocN(sizeof(ARegion), "main area for image");
00421     
00422     BLI_addtail(&simage->regionbase, ar);
00423     ar->regiontype= RGN_TYPE_WINDOW;
00424     
00425     return (SpaceLink *)simage;
00426 }
00427 
00428 /* not spacelink itself */
00429 static void image_free(SpaceLink *sl)
00430 {   
00431     SpaceImage *simage= (SpaceImage*) sl;
00432     
00433     if(simage->cumap)
00434         curvemapping_free(simage->cumap);
00435     scopes_free(&simage->scopes);
00436 }
00437 
00438 
00439 /* spacetype; init callback, add handlers */
00440 static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
00441 {
00442     ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
00443 
00444     /* add drop boxes */
00445     WM_event_add_dropbox_handler(&sa->handlers, lb);
00446     
00447 }
00448 
00449 static SpaceLink *image_duplicate(SpaceLink *sl)
00450 {
00451     SpaceImage *simagen= MEM_dupallocN(sl);
00452     
00453     /* clear or remove stuff from old */
00454     if(simagen->cumap)
00455         simagen->cumap= curvemapping_copy(simagen->cumap);
00456 
00457     scopes_new(&simagen->scopes);
00458 
00459     return (SpaceLink *)simagen;
00460 }
00461 
00462 static void image_operatortypes(void)
00463 {
00464     WM_operatortype_append(IMAGE_OT_view_all);
00465     WM_operatortype_append(IMAGE_OT_view_pan);
00466     WM_operatortype_append(IMAGE_OT_view_selected);
00467     WM_operatortype_append(IMAGE_OT_view_zoom);
00468     WM_operatortype_append(IMAGE_OT_view_zoom_in);
00469     WM_operatortype_append(IMAGE_OT_view_zoom_out);
00470     WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
00471     WM_operatortype_append(IMAGE_OT_view_ndof);
00472 
00473     WM_operatortype_append(IMAGE_OT_new);
00474     WM_operatortype_append(IMAGE_OT_open);
00475     WM_operatortype_append(IMAGE_OT_replace);
00476     WM_operatortype_append(IMAGE_OT_reload);
00477     WM_operatortype_append(IMAGE_OT_save);
00478     WM_operatortype_append(IMAGE_OT_save_as);
00479     WM_operatortype_append(IMAGE_OT_save_sequence);
00480     WM_operatortype_append(IMAGE_OT_pack);
00481     WM_operatortype_append(IMAGE_OT_unpack);
00482     
00483     WM_operatortype_append(IMAGE_OT_invert);
00484 
00485     WM_operatortype_append(IMAGE_OT_cycle_render_slot);
00486 
00487     WM_operatortype_append(IMAGE_OT_sample);
00488     WM_operatortype_append(IMAGE_OT_sample_line);
00489     WM_operatortype_append(IMAGE_OT_curves_point_set);
00490 
00491     WM_operatortype_append(IMAGE_OT_record_composite);
00492 
00493     WM_operatortype_append(IMAGE_OT_properties);
00494     WM_operatortype_append(IMAGE_OT_scopes);
00495 }
00496 
00497 static void image_keymap(struct wmKeyConfig *keyconf)
00498 {
00499     wmKeyMap *keymap= WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
00500     wmKeyMapItem *kmi;
00501     
00502     WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
00503     WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
00504     WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
00505     WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
00506     WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
00507     WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
00508     WM_keymap_add_item(keymap, "IMAGE_OT_scopes", TKEY, KM_PRESS, 0, 0);
00509 
00510     WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
00511     RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", TRUE);
00512     
00513     keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
00514     
00515     WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
00516     WM_keymap_add_item(keymap, "IMAGE_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
00517     WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
00518     WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
00519     WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0);
00520 
00521     WM_keymap_add_item(keymap, "IMAGE_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); // or view selected?
00522     WM_keymap_add_item(keymap, "IMAGE_OT_view_ndof", NDOF_MOTION, 0, 0, 0);
00523 
00524     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
00525     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
00526     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
00527     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
00528     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
00529     WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
00530 
00531     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
00532     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
00533     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
00534     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
00535     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
00536     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
00537     RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
00538 
00539     WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
00540     RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
00541     RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
00542 
00543     /* toggle editmode is handy to have while UV unwrapping */
00544     kmi= WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
00545     RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
00546     RNA_boolean_set(kmi->ptr, "toggle", TRUE);
00547 }
00548 
00549 /* dropboxes */
00550 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
00551 {
00552     if(drag->type==WM_DRAG_PATH)
00553         if(ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK))  /* rule might not work? */
00554             return 1;
00555     return 0;
00556 }
00557 
00558 static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
00559 {
00560     /* copy drag path to properties */
00561     RNA_string_set(drop->ptr, "filepath", drag->path);
00562 }
00563 
00564 /* area+region dropbox definition */
00565 static void image_dropboxes(void)
00566 {
00567     ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
00568     
00569     WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy);
00570 }
00571 
00572 
00573 
00574 static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
00575 {
00576     Scene *scene = CTX_data_scene(C);
00577     SpaceImage *sima= CTX_wm_space_image(C);
00578     Object *obedit= CTX_data_edit_object(C);
00579     Image *ima;
00580 
00581     ima= ED_space_image(sima);
00582 
00583     if(sima->iuser.flag & IMA_ANIM_ALWAYS)
00584         BKE_image_user_calc_frame(&sima->iuser, CTX_data_scene(C)->r.cfra, 0);
00585     
00586     /* check if we have to set the image from the editmesh */
00587     if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
00588     else if(obedit && obedit->type == OB_MESH) {
00589         Mesh *me= (Mesh*)obedit->data;
00590         EditMesh *em= BKE_mesh_get_editmesh(me);
00591         int sloppy= 1; /* partially selected face is ok */
00592 
00593         if(scene_use_new_shading_nodes(scene)) {
00594             /* new shading system, get image from material */
00595             EditFace *efa= EM_get_actFace(em, sloppy);
00596 
00597             if(efa) {
00598                 Image *node_ima;
00599                 ED_object_get_active_image(obedit, efa->mat_nr, &node_ima, NULL, NULL);
00600 
00601                 if(node_ima)
00602                     sima->image= node_ima;
00603             }
00604         }
00605         else {
00606             /* old shading system, we set texface */
00607             MTFace *tf;
00608             
00609             if(em && EM_texFaceCheck(em)) {
00610                 sima->image= NULL;
00611                 
00612                 tf = EM_get_active_mtface(em, NULL, NULL, sloppy);
00613                 
00614                 if(tf) {
00615                     /* don't need to check for pin here, see above */
00616                     sima->image= tf->tpage;
00617                     
00618                     if(sima->flag & SI_EDITTILE);
00619                     else sima->curtile= tf->tile;
00620                 }
00621             }
00622         }
00623 
00624         BKE_mesh_end_editmesh(obedit->data, em);
00625     }
00626 }
00627 
00628 static void image_listener(ScrArea *sa, wmNotifier *wmn)
00629 {
00630     SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
00631     
00632     /* context changes */
00633     switch(wmn->category) {
00634         case NC_SCENE:
00635             switch(wmn->data) {
00636                 case ND_FRAME:
00637                     image_scopes_tag_refresh(sa);
00638                     ED_area_tag_refresh(sa);
00639                     ED_area_tag_redraw(sa);                 
00640                     break;
00641                 case ND_MODE:
00642                 case ND_RENDER_RESULT:
00643                 case ND_COMPO_RESULT:
00644                     if (ED_space_image_show_render(sima))
00645                         image_scopes_tag_refresh(sa);
00646                     ED_area_tag_refresh(sa);
00647                     ED_area_tag_redraw(sa);                 
00648                     break;
00649             }
00650             break;
00651         case NC_IMAGE:
00652             if (wmn->reference == sima->image || !wmn->reference) {
00653                 image_scopes_tag_refresh(sa);
00654                 ED_area_tag_refresh(sa);
00655                 ED_area_tag_redraw(sa);
00656             }
00657             break;
00658         case NC_SPACE:  
00659             if(wmn->data == ND_SPACE_IMAGE) {
00660                 image_scopes_tag_refresh(sa);
00661                 ED_area_tag_redraw(sa);
00662             }
00663             break;
00664         case NC_GEOM:
00665             switch(wmn->data) {
00666                 case ND_DATA:
00667                 case ND_SELECT:
00668                     image_scopes_tag_refresh(sa);
00669                     ED_area_tag_refresh(sa);
00670                     ED_area_tag_redraw(sa);
00671                     break;
00672             }
00673         case NC_OBJECT:
00674         {
00675             Object *ob= (Object *)wmn->reference;
00676             switch(wmn->data) {
00677                 case ND_TRANSFORM:
00678                 case ND_MODIFIER:
00679                     if(ob && (ob->mode & OB_MODE_EDIT) && sima->lock && (sima->flag & SI_DRAWSHADOW)) {
00680                         ED_area_tag_refresh(sa);
00681                         ED_area_tag_redraw(sa);
00682                     }
00683                     break;
00684             }
00685         }
00686     }
00687 }
00688 
00689 const char *image_context_dir[] = {"edit_image", NULL};
00690 
00691 static int image_context(const bContext *C, const char *member, bContextDataResult *result)
00692 {
00693     SpaceImage *sima= CTX_wm_space_image(C);
00694 
00695     if(CTX_data_dir(member)) {
00696         CTX_data_dir_set(result, image_context_dir);
00697     }
00698     else if(CTX_data_equals(member, "edit_image")) {
00699         CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
00700         return 1;
00701     }
00702 
00703     return 0;
00704 }
00705 
00706 /************************** main region ***************************/
00707 
00708 /* sets up the fields of the View2D from zoom and offset */
00709 static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar)
00710 {
00711     Image *ima= ED_space_image(sima);
00712     float x1, y1, w, h;
00713     int width, height, winx, winy;
00714     
00715 #if 0
00716     if(image_preview_active(curarea, &width, &height));
00717     else
00718 #endif
00719     ED_space_image_size(sima, &width, &height);
00720 
00721     w= width;
00722     h= height;
00723     
00724     if(ima)
00725         h *= ima->aspy/ima->aspx;
00726 
00727     winx= ar->winrct.xmax - ar->winrct.xmin + 1;
00728     winy= ar->winrct.ymax - ar->winrct.ymin + 1;
00729         
00730     ar->v2d.tot.xmin= 0;
00731     ar->v2d.tot.ymin= 0;
00732     ar->v2d.tot.xmax= w;
00733     ar->v2d.tot.ymax= h;
00734     
00735     ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
00736     ar->v2d.mask.xmax= winx;
00737     ar->v2d.mask.ymax= winy;
00738 
00739     /* which part of the image space do we see? */
00740     x1= ar->winrct.xmin+(winx-sima->zoom*w)/2.0f;
00741     y1= ar->winrct.ymin+(winy-sima->zoom*h)/2.0f;
00742 
00743     x1-= sima->zoom*sima->xof;
00744     y1-= sima->zoom*sima->yof;
00745     
00746     /* relative display right */
00747     ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sima->zoom);
00748     ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sima->zoom);
00749     
00750     /* relative display left */
00751     ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sima->zoom);
00752     ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sima->zoom);
00753     
00754     /* normalize 0.0..1.0 */
00755     ar->v2d.cur.xmin /= w;
00756     ar->v2d.cur.xmax /= w;
00757     ar->v2d.cur.ymin /= h;
00758     ar->v2d.cur.ymax /= h;
00759 }
00760 
00761 /* add handlers, stuff you only do once or on area/region changes */
00762 static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
00763 {
00764     wmKeyMap *keymap;
00765     
00766     // image space manages own v2d
00767     // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
00768 
00769     /* image paint polls for mode */
00770     keymap= WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
00771     WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
00772 
00773     keymap= WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
00774     WM_event_add_keymap_handler(&ar->handlers, keymap);
00775     
00776     /* own keymaps */
00777     keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
00778     WM_event_add_keymap_handler(&ar->handlers, keymap);
00779     keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
00780     WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
00781 
00782 }
00783 
00784 static void image_main_area_draw(const bContext *C, ARegion *ar)
00785 {
00786     /* draw entirely, view changes should be handled here */
00787     SpaceImage *sima= CTX_wm_space_image(C);
00788     Object *obedit= CTX_data_edit_object(C);
00789     Scene *scene= CTX_data_scene(C);
00790     View2D *v2d= &ar->v2d;
00791     //View2DScrollers *scrollers;
00792     float col[3];
00793     
00794     /* XXX not supported yet, disabling for now */
00795     scene->r.scemode &= ~R_COMP_CROP;
00796     
00797     /* clear and setup matrix */
00798     UI_GetThemeColor3fv(TH_BACK, col);
00799     glClearColor(col[0], col[1], col[2], 0.0);
00800     glClear(GL_COLOR_BUFFER_BIT);
00801 
00802     /* put scene context variable in iuser */
00803     sima->iuser.scene= scene;
00804 
00805     /* we set view2d from own zoom and offset each time */
00806     image_main_area_set_view2d(sima, ar);
00807     
00808     /* we draw image in pixelspace */
00809     draw_image_main(sima, ar, scene);
00810 
00811     /* and uvs in 0.0-1.0 space */
00812     UI_view2d_view_ortho(v2d);
00813     draw_uvedit_main(sima, ar, scene, obedit);
00814 
00815     ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
00816         
00817     /* Grease Pencil too (in addition to UV's) */
00818     draw_image_grease_pencil((bContext *)C, 1); 
00819 
00820     UI_view2d_view_restore(C);
00821 
00822     /* draw Grease Pencil - screen space only */
00823     draw_image_grease_pencil((bContext *)C, 0);
00824     
00825     /* scrollers? */
00826     /*scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
00827     UI_view2d_scrollers_draw(C, v2d, scrollers);
00828     UI_view2d_scrollers_free(scrollers);*/
00829 }
00830 
00831 static void image_main_area_listener(ARegion *ar, wmNotifier *wmn)
00832 {
00833     /* context changes */
00834     switch(wmn->category) {
00835         case NC_SCREEN:
00836             if (wmn->data==ND_GPENCIL)
00837                 ED_region_tag_redraw(ar);
00838         break;
00839     }
00840 }
00841 
00842 /* *********************** buttons region ************************ */
00843 
00844 /* add handlers, stuff you only do once or on area/region changes */
00845 static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
00846 {
00847     wmKeyMap *keymap;
00848 
00849     ED_region_panels_init(wm, ar);
00850     
00851     keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
00852     WM_event_add_keymap_handler(&ar->handlers, keymap);
00853 }
00854 
00855 static void image_buttons_area_draw(const bContext *C, ARegion *ar)
00856 {
00857     ED_region_panels(C, ar, 1, NULL, -1);
00858 }
00859 
00860 static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
00861 {
00862     /* context changes */
00863     switch(wmn->category) {
00864         case NC_SCREEN:
00865             if (wmn->data==ND_GPENCIL)
00866                 ED_region_tag_redraw(ar);
00867             break;
00868         case NC_BRUSH:
00869             if(wmn->action==NA_EDITED)
00870                 ED_region_tag_redraw(ar);
00871             break;
00872     }
00873 }
00874 
00875 /* *********************** scopes region ************************ */
00876 
00877 /* add handlers, stuff you only do once or on area/region changes */
00878 static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
00879 {
00880     wmKeyMap *keymap;
00881     
00882     ED_region_panels_init(wm, ar);
00883     
00884     keymap= WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
00885     WM_event_add_keymap_handler(&ar->handlers, keymap);
00886 }
00887 
00888 static void image_scope_area_draw(const bContext *C, ARegion *ar)
00889 {
00890     SpaceImage *sima= CTX_wm_space_image(C);
00891     Scene *scene= CTX_data_scene(C);
00892     void *lock;
00893     ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
00894     if(ibuf) {
00895         scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT );
00896     }
00897     ED_space_image_release_buffer(sima, lock);
00898     
00899     ED_region_panels(C, ar, 1, NULL, -1);
00900 }
00901 
00902 static void image_scope_area_listener(ARegion *ar, wmNotifier *wmn)
00903 {
00904     /* context changes */
00905     switch(wmn->category) {
00906         case NC_SCENE:
00907             switch(wmn->data) {
00908                 case ND_MODE:
00909                 case ND_RENDER_RESULT:
00910                 case ND_COMPO_RESULT:
00911                     ED_region_tag_redraw(ar);
00912                     break;
00913             }
00914             break;
00915         case NC_IMAGE:
00916             ED_region_tag_redraw(ar);
00917             break;
00918         case NC_NODE:
00919             ED_region_tag_redraw(ar);
00920             break;
00921             
00922     }
00923 }
00924 
00925 /************************* header region **************************/
00926 
00927 /* add handlers, stuff you only do once or on area/region changes */
00928 static void image_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
00929 {
00930     ED_region_header_init(ar);
00931 }
00932 
00933 static void image_header_area_draw(const bContext *C, ARegion *ar)
00934 {
00935     ED_region_header(C, ar);
00936 }
00937 
00938 static void image_header_area_listener(ARegion *ar, wmNotifier *wmn)
00939 {
00940     /* context changes */
00941     switch(wmn->category) {
00942         case NC_SCENE:
00943             switch(wmn->data) {
00944                 case ND_MODE:
00945                 case ND_TOOLSETTINGS:
00946                     ED_region_tag_redraw(ar);
00947                     break;
00948             }
00949             break;
00950         case NC_GEOM:
00951             switch(wmn->data) {
00952                 case ND_DATA:
00953                 case ND_SELECT:
00954                     ED_region_tag_redraw(ar);
00955                     break;
00956             }
00957             
00958     }
00959 }
00960 
00961 /**************************** spacetype *****************************/
00962 
00963 /* only called once, from space/spacetypes.c */
00964 void ED_spacetype_image(void)
00965 {
00966     SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype image");
00967     ARegionType *art;
00968     
00969     st->spaceid= SPACE_IMAGE;
00970     strncpy(st->name, "Image", BKE_ST_MAXNAME);
00971     
00972     st->new= image_new;
00973     st->free= image_free;
00974     st->init= image_init;
00975     st->duplicate= image_duplicate;
00976     st->operatortypes= image_operatortypes;
00977     st->keymap= image_keymap;
00978     st->dropboxes= image_dropboxes;
00979     st->refresh= image_refresh;
00980     st->listener= image_listener;
00981     st->context= image_context;
00982     
00983     /* regions: main window */
00984     art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
00985     art->regionid = RGN_TYPE_WINDOW;
00986     art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_GPENCIL;
00987     art->init= image_main_area_init;
00988     art->draw= image_main_area_draw;
00989     art->listener= image_main_area_listener;
00990 
00991     BLI_addhead(&st->regiontypes, art);
00992     
00993     /* regions: listview/buttons */
00994     art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
00995     art->regionid = RGN_TYPE_UI;
00996     art->prefsizex= 220; // XXX
00997     art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
00998     art->listener= image_buttons_area_listener;
00999     art->init= image_buttons_area_init;
01000     art->draw= image_buttons_area_draw;
01001     BLI_addhead(&st->regiontypes, art);
01002 
01003     image_buttons_register(art);
01004     ED_uvedit_buttons_register(art);
01005     
01006     /* regions: statistics/scope buttons */
01007     art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
01008     art->regionid = RGN_TYPE_PREVIEW;
01009     art->prefsizex= 220; // XXX
01010     art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
01011     art->listener= image_scope_area_listener;
01012     art->init= image_scope_area_init;
01013     art->draw= image_scope_area_draw;
01014     BLI_addhead(&st->regiontypes, art);
01015 
01016     /* regions: header */
01017     art= MEM_callocN(sizeof(ARegionType), "spacetype image region");
01018     art->regionid = RGN_TYPE_HEADER;
01019     art->prefsizey= HEADERY;
01020     art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
01021     art->listener= image_header_area_listener;
01022     art->init= image_header_area_init;
01023     art->draw= image_header_area_draw;
01024     
01025     BLI_addhead(&st->regiontypes, art);
01026     
01027     BKE_spacetype_register(st);
01028 }
01029