code cleanup: use const events for modal and invoke operators.
[blender.git] / source / blender / editors / space_view3d / space_view3d.c
index 72b67c2a71601633ad672fb260cbb8e0c9d32c37..0958e53df16935812a22af77fce54ccd56ba540d 100644 (file)
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "DNA_material_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
 #include "BLI_rand.h"
 #include "BLI_utildefines.h"
 
-#include "BKE_object.h"
 #include "BKE_context.h"
+#include "BKE_icons.h"
+#include "BKE_object.h"
 #include "BKE_screen.h"
 
 #include "ED_space_api.h"
 #include "ED_screen.h"
 #include "ED_object.h"
 
-#include "BIF_gl.h"
+#include "GPU_material.h"
 
+#include "BIF_gl.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -62,7 +65,7 @@
 
 #include "UI_resources.h"
 
-#include "view3d_intern.h"  // own include
+#include "view3d_intern.h"  /* own include */
 
 /* ******************** manage regions ********************* */
 
@@ -117,7 +120,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
                
                BLI_insertlinkafter(&sa->regionbase, arhead, artool);
                artool->regiontype = RGN_TYPE_TOOLS;
-               artool->alignment = RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT;
+               artool->alignment = RGN_ALIGN_LEFT;
                artool->flag = RGN_FLAG_HIDDEN;
        }
 
@@ -143,7 +146,7 @@ RegionView3D *ED_view3d_context_rv3d(bContext *C)
        if (rv3d == NULL) {
                ScrArea *sa = CTX_wm_area(C);
                if (sa && sa->spacetype == SPACE_VIEW3D) {
-                       ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+                       ARegion *ar = BKE_area_find_region_active_win(sa);
                        if (ar) {
                                rv3d = ar->regiondata;
                        }
@@ -185,7 +188,7 @@ int ED_view3d_context_user_region(bContext *C, View3D **v3d_r, ARegion **ar_r)
                                                                ar_unlock_user = ar;
                                                                break;
                                                        }
-                                               } 
+                                               }
                                        }
                                }
 
@@ -261,14 +264,11 @@ static SpaceLink *view3d_new(const bContext *C)
        v3d->gridlines = 16;
        v3d->gridsubdiv = 10;
        v3d->drawtype = OB_SOLID;
+
+       v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
        
-       v3d->gridflag |= V3D_SHOW_X;
-       v3d->gridflag |= V3D_SHOW_Y;
-       v3d->gridflag |= V3D_SHOW_FLOOR;
-       v3d->gridflag &= ~V3D_SHOW_Z;
-       
-       v3d->flag |= V3D_SELECT_OUTLINE;
-       v3d->flag2 |= V3D_SHOW_RECONSTRUCTION;
+       v3d->flag = V3D_SELECT_OUTLINE;
+       v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
        
        v3d->lens = 35.0f;
        v3d->near = 0.01f;
@@ -338,6 +338,14 @@ static void view3d_free(SpaceLink *sl)
        if (vd->localvd) MEM_freeN(vd->localvd);
        
        if (vd->properties_storage) MEM_freeN(vd->properties_storage);
+       
+       /* matcap material, its preview rect gets freed via icons */
+       if (vd->defmaterial) {
+               if (vd->defmaterial->gpumaterial.first)
+                       GPU_material_free(vd->defmaterial);
+               BKE_previewimg_free(&vd->defmaterial->preview);
+               MEM_freeN(vd->defmaterial);
+       }
 }
 
 
@@ -368,6 +376,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
        
        /* copy or clear inside new stuff */
 
+       v3dn->defmaterial = NULL;
+       
        BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
 
        v3dn->properties_storage = NULL;
@@ -459,7 +469,7 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
        
 }
 
-static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
 {
        if (drag->type == WM_DRAG_ID) {
                ID *id = (ID *)drag->poin;
@@ -469,7 +479,17 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE
        return 0;
 }
 
-static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+{
+       if (drag->type == WM_DRAG_ID) {
+               ID *id = (ID *)drag->poin;
+               if (GS(id->name) == ID_GR)
+                       return 1;
+       }
+       return 0;
+}
+
+static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
 {
        if (drag->type == WM_DRAG_ID) {
                ID *id = (ID *)drag->poin;
@@ -479,7 +499,7 @@ static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
        return 0;
 }
 
-static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
 {
        if (drag->type == WM_DRAG_ID) {
                ID *id = (ID *)drag->poin;
@@ -493,34 +513,50 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
        return 0;
 }
 
-
-static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
 {
-       if (ED_view3d_give_base_under_cursor(C, event->mval) ) {
-               return 0;
+       if (event->ctrl)
+               return false;
+
+       if (!ED_view3d_give_base_under_cursor(C, event->mval)) {
+               return view3d_ima_drop_poll(C, drag, event);
        }
-       return view3d_ima_drop_poll(C, drag, event);
+       return 0;
 }
 
-static int view3d_ima_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
 {
-       if (ED_view3d_give_base_under_cursor(C, event->mval) ) {
+       Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+
+       /* either holding and ctrl and no object, or dropping to empty */
+       if ((event->ctrl && !base) || (base && base->object->type == OB_EMPTY))
+               return view3d_ima_drop_poll(C, drag, event);
+
+       return 0;
+}
+
+static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+{
+       Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
+
+       if (base && base->object->type == OB_MESH)
                return view3d_ima_drop_poll(C, drag, event);
-       }
        return 0;
 }
 
 static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
        ID *id = (ID *)drag->poin;
-       PointerRNA ptr;
 
-       /* need to put name in sub-operator in macro */
-       ptr = RNA_pointer_get(drop->ptr, "OBJECT_OT_add_named");
-       if (ptr.data)
-               RNA_string_set(&ptr, "name", id->name + 2);
-       else
-               RNA_string_set(drop->ptr, "name", id->name + 2);
+       RNA_string_set(drop->ptr, "name", id->name + 2);
+}
+
+static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+       ID *id = (ID *)drag->poin;
+       
+       drop->opcontext = WM_OP_EXEC_DEFAULT;
+       RNA_string_set(drop->ptr, "name", id->name + 2);
 }
 
 static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -546,10 +582,12 @@ static void view3d_dropboxes(void)
 {
        ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
        
-       WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_ob_drop_copy);
+       WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
        WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
-       WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_ob_drop_poll, view3d_id_path_drop_copy);
+       WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
+       WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
        WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
+       WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
 }
 
 
@@ -574,6 +612,9 @@ static void view3d_main_area_free(ARegion *ar)
                        if (rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
                        MEM_freeN(rv3d->depths);
                }
+               if (rv3d->sms) {
+                       MEM_freeN(rv3d->sms);
+               }
                MEM_freeN(rv3d);
                ar->regiondata = NULL;
        }
@@ -635,8 +676,7 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
 
 static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
 {
-       bScreen *sc;
-
+       
        /* context changes */
        switch (wmn->category) {
                case NC_ANIMATION:
@@ -659,7 +699,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                case NC_SCENE:
                        switch (wmn->data) {
                                case ND_LAYER_CONTENT:
-                                       view3d_recalc_used_layers(ar, wmn, wmn->reference);
+                                       if (wmn->reference)
+                                               view3d_recalc_used_layers(ar, wmn, wmn->reference);
                                        ED_region_tag_redraw(ar);
                                        break;
                                case ND_FRAME:
@@ -702,6 +743,7 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                case NC_GEOM:
                        switch (wmn->data) {
                                case ND_DATA:
+                               case ND_VERTEX_GROUP:
                                case ND_SELECT:
                                        ED_region_tag_redraw(ar);
                                        break;
@@ -719,10 +761,11 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                case NC_BRUSH:
                        if (wmn->action == NA_EDITED)
                                ED_region_tag_redraw_overlay(ar);
-                       break;                  
+                       break;
                case NC_MATERIAL:
                        switch (wmn->data) {
                                case ND_SHADING_DRAW:
+                               case ND_SHADING_LINKS:
                                        ED_region_tag_redraw(ar);
                                        break;
                        }
@@ -748,12 +791,12 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                                        break;
                        }
                        break;
-               case NC_IMAGE:  
+               case NC_IMAGE:
                        /* this could be more fine grained checks if we had
                         * more context than just the region */
                        ED_region_tag_redraw(ar);
                        break;
-               case NC_TEXTURE:        
+               case NC_TEXTURE:
                        /* same as above */
                        ED_region_tag_redraw(ar);
                        break;
@@ -776,7 +819,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                        break;
                case NC_SCREEN:
                        switch (wmn->data) {
-                               case ND_GPENCIL:
                                case ND_ANIMPLAY:
                                case ND_SKETCH:
                                        ED_region_tag_redraw(ar);
@@ -786,13 +828,19 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                                case ND_SCREENSET:
                                        /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
                                        /* updates used layers only for View3D in active screen */
-                                       sc = wmn->reference;
-                                       view3d_recalc_used_layers(ar, wmn, sc->scene);
+                                       if (wmn->reference) {
+                                               bScreen *sc = wmn->reference;
+                                               view3d_recalc_used_layers(ar, wmn, sc->scene);
+                                       }
                                        ED_region_tag_redraw(ar);
                                        break;
                        }
 
                        break;
+               case NC_GPENCIL:
+                       if (wmn->action == NA_EDITED)
+                               ED_region_tag_redraw(ar);
+                       break;
        }
 }
 
@@ -879,7 +927,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
                                case ND_KEYFRAME:
                                        if (wmn->action == NA_EDITED)
                                                ED_region_tag_redraw(ar);
-                                       break;  
+                                       break;
                        }
                        break;
                case NC_SCENE:
@@ -917,6 +965,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
                case NC_GEOM:
                        switch (wmn->data) {
                                case ND_DATA:
+                               case ND_VERTEX_GROUP:
                                case ND_SELECT:
                                        ED_region_tag_redraw(ar);
                                        break;
@@ -941,8 +990,8 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
                        if (wmn->action == NA_RENAME)
                                ED_region_tag_redraw(ar);
                        break;
-               case NC_SCREEN: 
-                       if (wmn->data == ND_GPENCIL)
+               case NC_GPENCIL:
+                       if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
                                ED_region_tag_redraw(ar);
                        break;
        }
@@ -984,7 +1033,7 @@ static void view3d_props_area_listener(ARegion *ar, wmNotifier *wmn)
 }
 
 /*area (not region) level listener*/
-static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn)
+static void space_view3d_listener(ScrArea *sa, struct wmNotifier *wmn)
 {
        View3D *v3d = sa->spacedata.first;
 
@@ -1016,7 +1065,7 @@ static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn)
                        break;
        }
 
-       // removed since BKE_image_user_calc_frame is now called in draw_bgpic because screen_ops doesnt call the notifier.
+       /* removed since BKE_image_user_frame_calc is now called in view3d_draw_bgpic because screen_ops doesnt call the notifier. */
 #if 0
        if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) {
                View3D *v3d = area->spacedata.first;
@@ -1025,7 +1074,7 @@ static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn)
                for (; bgpic; bgpic = bgpic->next) {
                        if (bgpic->ima) {
                                Scene *scene = wmn->reference;
-                               BKE_image_user_calc_frame(&bgpic->iuser, scene->r.cfra, 0);
+                               BKE_image_user_frame_calc(&bgpic->iuser, scene->r.cfra, 0);
                        }
                }
        }
@@ -1071,7 +1120,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
                for (base = scene->base.first; base; base = base->next) {
                        if ((base->flag & SELECT) && (base->lay & lay)) {
                                if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
-                                       if (0 == object_is_libdata(base->object)) {
+                                       if (0 == BKE_object_is_libdata(base->object)) {
                                                if (selected_editable_objects)
                                                        CTX_data_id_list_add(result, &base->object->id);
                                                else
@@ -1116,16 +1165,21 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
                return 1;
        }
        else if (CTX_data_equals(member, "active_base")) {
-               if (scene->basact && (scene->basact->lay & lay))
-                       if ((scene->basact->object->restrictflag & OB_RESTRICT_VIEW) == 0)
+               if (scene->basact && (scene->basact->lay & lay)) {
+                       Object *ob = scene->basact->object;
+                       /* if hidden but in edit mode, we still display, can happen with animation */
+                       if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
                                CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, scene->basact);
+               }
                
                return 1;
        }
        else if (CTX_data_equals(member, "active_object")) {
-               if (scene->basact && (scene->basact->lay & lay))
-                       if ((scene->basact->object->restrictflag & OB_RESTRICT_VIEW) == 0)
+               if (scene->basact && (scene->basact->lay & lay)) {
+                       Object *ob = scene->basact->object;
+                       if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
                                CTX_data_id_pointer_set(result, &scene->basact->object->id);
+               }
                
                return 1;
        }
@@ -1172,7 +1226,7 @@ void ED_spacetype_view3d(void)
        /* regions: listview/buttons */
        art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
        art->regionid = RGN_TYPE_UI;
-       art->prefsizex = 180; // XXX
+       art->prefsizex = 180; /* XXX */
        art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
        art->listener = view3d_buttons_area_listener;
        art->init = view3d_buttons_area_init;
@@ -1184,8 +1238,8 @@ void ED_spacetype_view3d(void)
        /* regions: tool(bar) */
        art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region");
        art->regionid = RGN_TYPE_TOOLS;
-       art->prefsizex = 160; // XXX
-       art->prefsizey = 50; // XXX
+       art->prefsizex = 160; /* XXX */
+       art->prefsizey = 50; /* XXX */
        art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
        art->listener = view3d_buttons_area_listener;
        art->init = view3d_tools_area_init;