Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / screen.c
index a719cc8c94a4f62887a92e6788ad8cbd489282f2..b6b49a49de3d16095fbd4e66a90d6f070721fb60 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
-#include "GPU_compositing.h"
-
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BLI_listbase.h"
 #include "BLI_utildefines.h"
 #include "BLI_rect.h"
 
+#include "BKE_icons.h"
 #include "BKE_idprop.h"
 #include "BKE_screen.h"
+#include "BKE_workspace.h"
 
 /* ************ Spacetype/regiontype handling ************** */
 
@@ -68,13 +69,19 @@ static void spacetype_free(SpaceType *st)
        for (art = st->regiontypes.first; art; art = art->next) {
                BLI_freelistN(&art->drawcalls);
 
-               for (pt = art->paneltypes.first; pt; pt = pt->next)
-                       if (pt->ext.free)
+               for (pt = art->paneltypes.first; pt; pt = pt->next) {
+                       if (pt->ext.free) {
                                pt->ext.free(pt->ext.data);
+                       }
 
-               for (ht = art->headertypes.first; ht; ht = ht->next)
-                       if (ht->ext.free)
+                       BLI_freelistN(&pt->children);
+               }
+
+               for (ht = art->headertypes.first; ht; ht = ht->next) {
+                       if (ht->ext.free) {
                                ht->ext.free(ht->ext.data);
+                       }
+               }
 
                BLI_freelistN(&art->paneltypes);
                BLI_freelistN(&art->headertypes);
@@ -180,10 +187,35 @@ void BKE_spacedata_freelist(ListBase *lb)
        BLI_freelistN(lb);
 }
 
+static void panel_list_copy(ListBase *newlb, const ListBase *lb)
+{
+       BLI_listbase_clear(newlb);
+       BLI_duplicatelist(newlb, lb);
+
+       /* copy panel pointers */
+       Panel *newpa = newlb->first;
+       Panel *pa = lb->first;
+       for (; newpa; newpa = newpa->next, pa = pa->next) {
+               newpa->activedata = NULL;
+
+               Panel *newpatab = newlb->first;
+               Panel *patab = lb->first;
+               while (newpatab) {
+                       if (newpa->paneltab == patab) {
+                               newpa->paneltab = newpatab;
+                               break;
+                       }
+                       newpatab = newpatab->next;
+                       patab = patab->next;
+               }
+
+               panel_list_copy(&newpa->children, &pa->children);
+       }
+}
+
 ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
 {
        ARegion *newar = MEM_dupallocN(ar);
-       Panel *pa, *newpa, *patab;
        
        newar->prev = newar->next = NULL;
        BLI_listbase_clear(&newar->handlers);
@@ -191,9 +223,11 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
        BLI_listbase_clear(&newar->panels_category);
        BLI_listbase_clear(&newar->panels_category_active);
        BLI_listbase_clear(&newar->ui_lists);
-       newar->swinid = 0;
+       newar->visible = 0;
+       newar->manipulator_map = NULL;
        newar->regiontimer = NULL;
        newar->headerstr = NULL;
+       newar->draw_buffer = NULL;
        
        /* use optional regiondata callback */
        if (ar->regiondata) {
@@ -208,25 +242,10 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
        if (ar->v2d.tab_offset)
                newar->v2d.tab_offset = MEM_dupallocN(ar->v2d.tab_offset);
        
-       BLI_listbase_clear(&newar->panels);
-       BLI_duplicatelist(&newar->panels, &ar->panels);
+       panel_list_copy(&newar->panels, &ar->panels);
 
        BLI_listbase_clear(&newar->ui_previews);
        BLI_duplicatelist(&newar->ui_previews, &ar->ui_previews);
-
-       /* copy panel pointers */
-       for (newpa = newar->panels.first; newpa; newpa = newpa->next) {
-               patab = newar->panels.first;
-               pa = ar->panels.first;
-               while (patab) {
-                       if (newpa->paneltab == pa) {
-                               newpa->paneltab = patab;
-                               break;
-                       }
-                       patab = patab->next;
-                       pa = pa->next;
-               }
-       }
        
        return newar;
 }
@@ -301,6 +320,56 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
        }
 }
 
+/**
+ * Avoid bad-level calls to #WM_manipulatormap_tag_refresh.
+ */
+static void (*region_refresh_tag_manipulatormap_callback)(struct wmManipulatorMap *) = NULL;
+
+void BKE_region_callback_refresh_tag_manipulatormap_set(void (*callback)(struct wmManipulatorMap *))
+{
+       region_refresh_tag_manipulatormap_callback = callback;
+}
+
+void BKE_screen_manipulator_tag_refresh(struct bScreen *sc)
+{
+       if (region_refresh_tag_manipulatormap_callback == NULL) {
+               return;
+       }
+
+       ScrArea *sa;
+       ARegion *ar;
+       for (sa = sc->areabase.first; sa; sa = sa->next) {
+               for (ar = sa->regionbase.first; ar; ar = ar->next) {
+                       if (ar->manipulator_map != NULL) {
+                               region_refresh_tag_manipulatormap_callback(ar->manipulator_map);
+                       }
+               }
+       }
+}
+
+/**
+ * Avoid bad-level calls to #WM_manipulatormap_delete.
+ */
+static void (*region_free_manipulatormap_callback)(struct wmManipulatorMap *) = NULL;
+
+void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *))
+{
+       region_free_manipulatormap_callback = callback;
+}
+
+static void panel_list_free(ListBase *lb)
+{
+       Panel *pa, *pa_next;
+       for (pa = lb->first; pa; pa = pa_next) {
+               pa_next = pa->next;
+               if (pa->activedata) {
+                       MEM_freeN(pa->activedata);
+               }
+               panel_list_free(&pa->children);
+               MEM_freeN(pa);
+       }
+}
+
 /* not region itself */
 void BKE_area_region_free(SpaceType *st, ARegion *ar)
 {
@@ -323,16 +392,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
                ar->v2d.tab_offset = NULL;
        }
 
-       if (!BLI_listbase_is_empty(&ar->panels)) {
-               Panel *pa, *pa_next;
-               for (pa = ar->panels.first; pa; pa = pa_next) {
-                       pa_next = pa->next;
-                       if (pa->activedata) {
-                               MEM_freeN(pa->activedata);
-                       }
-                       MEM_freeN(pa);
-               }
-       }
+       panel_list_free(&ar->panels);
 
        for (uilst = ar->ui_lists.first; uilst; uilst = uilst->next) {
                if (uilst->dyn_data) {
@@ -350,6 +410,11 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
                        MEM_freeN(uilst->properties);
                }
        }
+
+       if (ar->manipulator_map != NULL) {
+               region_free_manipulatormap_callback(ar->manipulator_map);
+       }
+
        BLI_freelistN(&ar->ui_lists);
        BLI_freelistN(&ar->ui_previews);
        BLI_freelistN(&ar->panels_category);
@@ -365,6 +430,7 @@ void BKE_screen_area_free(ScrArea *sa)
        for (ar = sa->regionbase.first; ar; ar = ar->next)
                BKE_area_region_free(st, ar);
 
+       MEM_SAFE_FREE(sa->global);
        BLI_freelistN(&sa->regionbase);
        
        BKE_spacedata_freelist(&sa->spacedata);
@@ -372,10 +438,21 @@ void BKE_screen_area_free(ScrArea *sa)
        BLI_freelistN(&sa->actionzones);
 }
 
+void BKE_screen_area_map_free(ScrAreaMap *area_map)
+{
+       for (ScrArea *area = area_map->areabase.first, *area_next; area; area = area_next) {
+               area_next = area->next;
+               BKE_screen_area_free(area);
+       }
+
+       BLI_freelistN(&area_map->vertbase);
+       BLI_freelistN(&area_map->edgebase);
+       BLI_freelistN(&area_map->areabase);
+}
+
 /** Free (or release) any data used by this screen (does not free the screen itself). */
 void BKE_screen_free(bScreen *sc)
 {
-       ScrArea *sa, *san;
        ARegion *ar;
 
        /* No animdata here. */
@@ -384,15 +461,10 @@ void BKE_screen_free(bScreen *sc)
                BKE_area_region_free(NULL, ar);
 
        BLI_freelistN(&sc->regionbase);
-       
-       for (sa = sc->areabase.first; sa; sa = san) {
-               san = sa->next;
-               BKE_screen_area_free(sa);
-       }
-       
-       BLI_freelistN(&sc->vertbase);
-       BLI_freelistN(&sc->edgebase);
-       BLI_freelistN(&sc->areabase);
+
+       BKE_screen_area_map_free(AREAMAP_FROM_SCREEN(sc));
+
+       BKE_previewimg_free(&sc->preview);
 
        /* Region and timer are freed by the window manager. */
        MEM_SAFE_FREE(sc->tool_tip);
@@ -417,6 +489,174 @@ unsigned int BKE_screen_visible_layers(bScreen *screen, Scene *scene)
        return layer;
 }
 
+
+/* ***************** Screen edges & verts ***************** */
+
+ScrEdge *BKE_screen_find_edge(bScreen *sc, ScrVert *v1, ScrVert *v2)
+{
+       ScrEdge *se;
+
+       BKE_screen_sort_scrvert(&v1, &v2);
+       for (se = sc->edgebase.first; se; se = se->next) {
+               if (se->v1 == v1 && se->v2 == v2) {
+                       return se;
+               }
+       }
+
+       return NULL;
+}
+
+void BKE_screen_sort_scrvert(ScrVert **v1, ScrVert **v2)
+{
+       ScrVert *tmp;
+
+       if (*v1 > *v2) {
+               tmp = *v1;
+               *v1 = *v2;
+               *v2 = tmp;
+       }
+}
+
+void BKE_screen_remove_double_scrverts(bScreen *sc)
+{
+       ScrVert *v1, *verg;
+       ScrEdge *se;
+       ScrArea *sa;
+
+       verg = sc->vertbase.first;
+       while (verg) {
+               if (verg->newv == NULL) { /* !!! */
+                       v1 = verg->next;
+                       while (v1) {
+                               if (v1->newv == NULL) {   /* !?! */
+                                       if (v1->vec.x == verg->vec.x && v1->vec.y == verg->vec.y) {
+                                               /* printf("doublevert\n"); */
+                                               v1->newv = verg;
+                                       }
+                               }
+                               v1 = v1->next;
+                       }
+               }
+               verg = verg->next;
+       }
+
+       /* replace pointers in edges and faces */
+       se = sc->edgebase.first;
+       while (se) {
+               if (se->v1->newv) se->v1 = se->v1->newv;
+               if (se->v2->newv) se->v2 = se->v2->newv;
+               /* edges changed: so.... */
+               BKE_screen_sort_scrvert(&(se->v1), &(se->v2));
+               se = se->next;
+       }
+       sa = sc->areabase.first;
+       while (sa) {
+               if (sa->v1->newv) sa->v1 = sa->v1->newv;
+               if (sa->v2->newv) sa->v2 = sa->v2->newv;
+               if (sa->v3->newv) sa->v3 = sa->v3->newv;
+               if (sa->v4->newv) sa->v4 = sa->v4->newv;
+               sa = sa->next;
+       }
+
+       /* remove */
+       verg = sc->vertbase.first;
+       while (verg) {
+               v1 = verg->next;
+               if (verg->newv) {
+                       BLI_remlink(&sc->vertbase, verg);
+                       MEM_freeN(verg);
+               }
+               verg = v1;
+       }
+
+}
+
+void BKE_screen_remove_double_scredges(bScreen *sc)
+{
+       ScrEdge *verg, *se, *sn;
+
+       /* compare */
+       verg = sc->edgebase.first;
+       while (verg) {
+               se = verg->next;
+               while (se) {
+                       sn = se->next;
+                       if (verg->v1 == se->v1 && verg->v2 == se->v2) {
+                               BLI_remlink(&sc->edgebase, se);
+                               MEM_freeN(se);
+                       }
+                       se = sn;
+               }
+               verg = verg->next;
+       }
+}
+
+void BKE_screen_remove_unused_scredges(bScreen *sc)
+{
+       ScrEdge *se, *sen;
+       ScrArea *sa;
+       int a = 0;
+
+       /* sets flags when edge is used in area */
+       sa = sc->areabase.first;
+       while (sa) {
+               se = BKE_screen_find_edge(sc, sa->v1, sa->v2);
+               if (se == NULL) printf("error: area %d edge 1 doesn't exist\n", a);
+               else se->flag = 1;
+               se = BKE_screen_find_edge(sc, sa->v2, sa->v3);
+               if (se == NULL) printf("error: area %d edge 2 doesn't exist\n", a);
+               else se->flag = 1;
+               se = BKE_screen_find_edge(sc, sa->v3, sa->v4);
+               if (se == NULL) printf("error: area %d edge 3 doesn't exist\n", a);
+               else se->flag = 1;
+               se = BKE_screen_find_edge(sc, sa->v4, sa->v1);
+               if (se == NULL) printf("error: area %d edge 4 doesn't exist\n", a);
+               else se->flag = 1;
+               sa = sa->next;
+               a++;
+       }
+       se = sc->edgebase.first;
+       while (se) {
+               sen = se->next;
+               if (se->flag == 0) {
+                       BLI_remlink(&sc->edgebase, se);
+                       MEM_freeN(se);
+               }
+               else {
+                       se->flag = 0;
+               }
+               se = sen;
+       }
+}
+
+void BKE_screen_remove_unused_scrverts(bScreen *sc)
+{
+       ScrVert *sv, *svn;
+       ScrEdge *se;
+
+       /* we assume edges are ok */
+
+       se = sc->edgebase.first;
+       while (se) {
+               se->v1->flag = 1;
+               se->v2->flag = 1;
+               se = se->next;
+       }
+
+       sv = sc->vertbase.first;
+       while (sv) {
+               svn = sv->next;
+               if (sv->flag == 0) {
+                       BLI_remlink(&sc->vertbase, sv);
+                       MEM_freeN(sv);
+               }
+               else {
+                       sv->flag = 0;
+               }
+               sv = svn;
+       }
+}
+
 /* ***************** Utilities ********************** */
 
 /* Find a region of the specified type from the given area */
@@ -595,7 +835,7 @@ void BKE_screen_view3d_sync(View3D *v3d, struct Scene *scene)
        }
 }
 
-void BKE_screen_view3d_scene_sync(bScreen *sc)
+void BKE_screen_view3d_scene_sync(bScreen *sc, Scene *scene)
 {
        /* are there cameras in the views that are not in the scene? */
        ScrArea *sa;
@@ -604,56 +844,7 @@ void BKE_screen_view3d_scene_sync(bScreen *sc)
                for (sl = sa->spacedata.first; sl; sl = sl->next) {
                        if (sl->spacetype == SPACE_VIEW3D) {
                                View3D *v3d = (View3D *) sl;
-                               BKE_screen_view3d_sync(v3d, sc->scene);
-                       }
-               }
-       }
-}
-
-void BKE_screen_view3d_main_sync(ListBase *screen_lb, Scene *scene)
-{
-       bScreen *sc;
-       ScrArea *sa;
-       SpaceLink *sl;
-
-       /* from scene copy to the other views */
-       for (sc = screen_lb->first; sc; sc = sc->id.next) {
-               if (sc->scene != scene)
-                       continue;
-
-               for (sa = sc->areabase.first; sa; sa = sa->next)
-                       for (sl = sa->spacedata.first; sl; sl = sl->next)
-                               if (sl->spacetype == SPACE_VIEW3D)
-                                       BKE_screen_view3d_sync((View3D *)sl, scene);
-       }
-}
-
-void BKE_screen_view3d_twmode_remove(View3D *v3d, const int i)
-{
-       const int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
-       if (selected_index == i) {
-               v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
-       }
-       else if (selected_index > i) {
-               v3d->twmode--;
-       }
-}
-
-void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, Scene *scene, const int i)
-{
-       bScreen *sc;
-
-       for (sc = screen_lb->first; sc; sc = sc->id.next) {
-               if (sc->scene == scene) {
-                       ScrArea *sa;
-                       for (sa = sc->areabase.first; sa; sa = sa->next) {
-                               SpaceLink *sl;
-                               for (sl = sa->spacedata.first; sl; sl = sl->next) {
-                                       if (sl->spacetype == SPACE_VIEW3D) {
-                                               View3D *v3d = (View3D *)sl;
-                                               BKE_screen_view3d_twmode_remove(v3d, i);
-                                       }
-                               }
+                               BKE_screen_view3d_sync(v3d, scene);
                        }
                }
        }
@@ -677,25 +868,12 @@ float BKE_screen_view3d_zoom_from_fac(float zoomfac)
        return ((sqrtf(4.0f * zoomfac) - (float)M_SQRT2) * 50.0f);
 }
 
-void BKE_screen_gpu_fx_validate(GPUFXSettings *fx_settings)
+bool BKE_screen_is_fullscreen_area(const bScreen *screen)
 {
-       /* currently we use DOF from the camera _only_,
-        * so we never allocate this, only copy from the Camera */
-#if 0
-       if ((fx_settings->dof == NULL) &&
-           (fx_settings->fx_flag & GPU_FX_FLAG_DOF))
-       {
-               GPUDOFSettings *fx_dof;
-               fx_dof = fx_settings->dof = MEM_callocN(sizeof(GPUDOFSettings), __func__);
-       }
-#endif
-
-       if ((fx_settings->ssao == NULL) &&
-           (fx_settings->fx_flag & GPU_FX_FLAG_SSAO))
-       {
-               GPUSSAOSettings *fx_ssao;
-               fx_ssao = fx_settings->ssao = MEM_callocN(sizeof(GPUSSAOSettings), __func__);
+       return ELEM(screen->state, SCREENMAXIMIZED, SCREENFULL);
+}
 
-               GPU_fx_compositor_init_ssao_settings(fx_ssao);
-       }
+bool BKE_screen_is_used(const bScreen *screen)
+{
+       return (screen->winid != 0);
 }