[Bf-blender-cvs] [63112dcc14] temp-workspace-multi-window: Make duplicating workspaces work

Julian Eisel noreply at git.blender.org
Mon Mar 6 15:19:58 CET 2017


Commit: 63112dcc14e15e59f8627a48877bc406531058d1
Author: Julian Eisel
Date:   Mon Mar 6 15:19:15 2017 +0100
Branches: temp-workspace-multi-window
https://developer.blender.org/rB63112dcc14e15e59f8627a48877bc406531058d1

Make duplicating workspaces work

===================================================================

M	source/blender/blenkernel/BKE_screen.h
M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/screen.c
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/editors/workspace/area.c
M	source/blender/editors/workspace/screen_edit.c
M	source/blender/editors/workspace/screen_intern.h
M	source/blender/editors/workspace/screen_ops.c
M	source/blender/editors/workspace/workspace_edit.c
M	source/blender/makesrna/intern/rna_workspace.c
M	source/blender/windowmanager/intern/wm_window.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index b33aa31b3f..65f2aa8462 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -288,6 +288,7 @@ void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID
 /* area/regions */
 struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
 void            BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
+void            BKE_screen_area_data_copy(struct ScrArea *sa_dst, struct ScrArea *sa_src, const bool do_free);
 void            BKE_screen_area_free(struct ScrArea *sa);
 /* Manipulator-maps of a region need to be freed with the region. Uses callback to avoid low-level call. */
 void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManipulatorMap *));
@@ -319,7 +320,10 @@ float BKE_screen_view3d_zoom_to_fac(float camzoom);
 float BKE_screen_view3d_zoom_from_fac(float zoomfac);
 
 /* screen */
-void BKE_screen_free(struct bScreen *sc); 
+void BKE_screen_free(struct bScreen *sc);
+struct bScreen *BKE_screen_create_from_screen_data(
+        struct Main *bmain, const ListBase *vertbase, const ListBase *areabase, const char *name) ATTR_NONNULL();
+struct ScrVert *BKE_screen_add_vert(struct bScreen *sc, short x, short y);
 unsigned int BKE_screen_visible_layers(struct bScreen *screen, struct Scene *scene);
 
 #endif
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 1ff1549c34..ac8bb9875c 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -74,12 +74,12 @@ void BKE_workspace_hook_delete(struct Main *bmain, WorkSpaceHook *hook) ATTR_NON
 		_workspace##_next = BKE_workspace_next_get(_workspace); /* support removing workspace from list */
 #define BKE_workspace_iter_end } (void)0
 
-void BKE_workspace_change_prepare(struct Main *bmain, WorkSpaceHook *workspace_hook) ATTR_NONNULL();
+void BKE_workspace_change_prepare(struct Main *bmain, WorkSpaceHook *workspace_hook, WorkSpace *workspace_new) ATTR_NONNULL();
 
 void BKE_workspaces_transform_orientation_remove(const struct ListBase *workspaces,
                                                  const struct TransformOrientation *orientation) ATTR_NONNULL();
 
-WorkSpaceLayout *BKE_workspace_layout_find(const WorkSpace *ws, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+WorkSpaceLayout *BKE_workspace_layout_find(const WorkSpaceHook *hook, const struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
 
 #define BKE_workspace_layout_iter_begin(_layout, _start_layout) \
 	for (WorkSpaceLayout *_layout = _start_layout, *_layout##_next; _layout; _layout = _layout##_next) { \
@@ -114,7 +114,7 @@ const char *BKE_workspace_name_get(const WorkSpace *workspace) GETTER_ATTRS;
 WorkSpaceLayout *BKE_workspace_active_layout_get(const struct WorkSpace *ws) GETTER_ATTRS;
 void             BKE_workspace_active_layout_set(WorkSpace *ws, WorkSpaceLayout *layout) SETTER_ATTRS;
 struct bScreen *BKE_workspace_active_screen_get(const WorkSpace *ws) GETTER_ATTRS;
-void            BKE_workspace_active_screen_set(WorkSpace *ws, struct bScreen *screen) SETTER_ATTRS;
+void            BKE_workspace_active_screen_set(const WorkSpaceHook *hook, struct bScreen *screen) SETTER_ATTRS;
 enum ObjectMode BKE_workspace_object_mode_get(const WorkSpace *workspace) GETTER_ATTRS;
 #ifdef USE_WORKSPACE_MODE
 void            BKE_workspace_object_mode_set(WorkSpace *workspace, const enum ObjectMode mode) SETTER_ATTRS;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 2082975dcd..145bc334bd 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -52,6 +52,7 @@
 
 #include "BKE_icons.h"
 #include "BKE_idprop.h"
+#include "BKE_library.h"
 #include "BKE_screen.h"
 
 /* ************ Spacetype/regiontype handling ************** */
@@ -275,6 +276,45 @@ void BKE_spacedata_draw_locks(int set)
 	}
 }
 
+/**
+ * we swap spaces for fullscreen to keep all allocated data area vertices were set
+ */
+void BKE_screen_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free)
+{
+	SpaceType *st;
+	ARegion *ar;
+	const char spacetype = sa_dst->spacetype;
+	const short flag_copy = HEADER_NO_PULLDOWN;
+
+	sa_dst->headertype = sa_src->headertype;
+	sa_dst->spacetype = sa_src->spacetype;
+	sa_dst->type = sa_src->type;
+	sa_dst->butspacetype = sa_src->butspacetype;
+
+	sa_dst->flag = (sa_dst->flag & ~flag_copy) | (sa_src->flag & flag_copy);
+
+	/* area */
+	if (do_free) {
+		BKE_spacedata_freelist(&sa_dst->spacedata);
+	}
+	BKE_spacedata_copylist(&sa_dst->spacedata, &sa_src->spacedata);
+
+	/* Note; SPACE_EMPTY is possible on new screens */
+
+	/* regions */
+	if (do_free) {
+		st = BKE_spacetype_from_id(spacetype);
+		for (ar = sa_dst->regionbase.first; ar; ar = ar->next)
+			BKE_area_region_free(st, ar);
+		BLI_freelistN(&sa_dst->regionbase);
+	}
+	st = BKE_spacetype_from_id(sa_src->spacetype);
+	for (ar = sa_src->regionbase.first; ar; ar = ar->next) {
+		ARegion *newar = BKE_area_region_copy(st, ar);
+		BLI_addtail(&sa_dst->regionbase, newar);
+	}
+}
+
 static void (*spacedata_id_remap_cb)(struct ScrArea *sa, struct SpaceLink *sl, ID *old_id, ID *new_id) = NULL;
 
 void BKE_spacedata_callback_id_remap_set(void (*func)(ScrArea *sa, SpaceLink *sl, ID *, ID *))
@@ -399,6 +439,42 @@ void BKE_screen_free(bScreen *sc)
 	BKE_previewimg_free(&sc->preview);
 }
 
+bScreen *BKE_screen_create_from_screen_data(
+        struct Main *bmain, const ListBase *vertbase, const ListBase *areabase, const char *name)
+{
+	bScreen *screen = BKE_libblock_alloc(bmain, ID_SCR, name);
+
+	for (ScrVert *sv = vertbase->first; sv; sv = sv->next) {
+		ScrVert *sv_new = MEM_callocN(sizeof(ScrVert), "workspace_change_add_screenvert");
+		*sv_new = *sv;
+		BLI_addtail(&screen->vertbase, sv_new);
+	}
+	for (ScrArea *sa = areabase->first; sa; sa = sa->next) {
+		ScrArea *sa_new = MEM_callocN(sizeof(ScrArea), "workspace_change_add_screenarea");
+
+		sa_new->v1 = BKE_screen_add_vert(screen, sa->v1->vec.x, sa->v1->vec.y);
+		sa_new->v2 = BKE_screen_add_vert(screen, sa->v2->vec.x, sa->v2->vec.y);
+		sa_new->v3 = BKE_screen_add_vert(screen, sa->v3->vec.x, sa->v3->vec.y);
+		sa_new->v4 = BKE_screen_add_vert(screen, sa->v4->vec.x, sa->v4->vec.y);
+
+		BKE_screen_area_data_copy(sa_new, sa, false);
+		BLI_addtail(&screen->areabase, sa_new);
+	}
+
+	return screen;
+}
+
+ScrVert *BKE_screen_add_vert(bScreen *sc, short x, short y)
+{
+	ScrVert *sv = MEM_callocN(sizeof(ScrVert), __func__);
+
+	sv->vec.x = x;
+	sv->vec.y = y;
+	BLI_addtail(&sc->vertbase, sv);
+
+	return sv;
+}
+
 /* for depsgraph */
 unsigned int BKE_screen_visible_layers(bScreen *screen, Scene *scene)
 {
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 5a07e7c09c..b5c81caa93 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -105,7 +105,7 @@ WorkSpaceLayout *BKE_workspace_layout_add_from_type(WorkSpace *workspace, WorkSp
 {
 	WorkSpaceLayout *layout = MEM_mallocN(sizeof(*layout), __func__);
 
-	BLI_assert(!workspaces_is_screen_used(G.main, screen));
+//	BLI_assert(!workspaces_is_screen_used(G.main, screen));
 
 	layout->type = type;
 	layout->screen = screen;
@@ -154,27 +154,20 @@ void BKE_workspace_hook_delete(Main *bmain, WorkSpaceHook *hook)
 /* -------------------------------------------------------------------- */
 /* General Utils */
 
-void BKE_workspace_change_prepare(Main *bmain, WorkSpaceHook *workspace_hook)
+void BKE_workspace_change_prepare(Main *bmain, WorkSpaceHook *workspace_hook, WorkSpace *workspace_new)
 {
-	WorkSpace *workspace = workspace_hook->act_workspace;
 	BLI_freelistN(&workspace_hook->layouts);
 
-	for (WorkSpaceLayoutType *type = workspace->layout_types.first; type; type = type->next) {
-		bScreen *screen = BKE_libblock_alloc(bmain, ID_SCR, type->name);
-		WorkSpaceLayout *layout;
+	for (WorkSpaceLayoutType *type = workspace_new->layout_types.first; type; type = type->next) {
+		bScreen *screen = BKE_screen_create_from_screen_data(bmain, type->vertbase, type->areabase, type->name);
+		WorkSpaceLayout *layout = BKE_workspace_layout_add_from_type(workspace_new, type, screen);
 
-		for (ScrVert *sv = type->vertbase->first; sv; sv = sv->next) {
-			ScrVert *sv_new = MEM_callocN(sizeof(ScrVert), "workspace_change_add_screenvert");
-			*sv_new = *sv;
-			BLI_addtail(&screen->vertbase, sv_new);
-		}
-		for (ScrArea *sa = type->areabase->first; sa; sa = sa->next) {
-			ScrArea *sa_new = MEM_callocN(sizeof(ScrArea), "workspace_change_add_screenarea");
-			*sa_new = *sa;
-			BLI_addtail(&screen->areabase, sa_new);
-		}
-		layout = BKE_workspace_layout_add_from_type(workspace, type, screen);
 		BLI_addtail(&workspace_hook->layouts, layout);
+
+		/* XXX Just setting the active layout matching the active type stored in workspace */
+		if (type == workspace_new->act_layout_type) {
+			workspace_new->act_layout = layout;
+		}
 	}
 }
 
@@ -196,9 +189,9 @@ void BKE_workspaces_transform_orientation_remove(const ListBase *workspaces, con
  * a layout within \a workspace that wraps \a screen. Usually - especially outside
  * of BKE_workspace - #BKE_workspace_layout_find should be used!
  */
-static WorkSpaceLayout *workspace_layout_find(const WorkSpace *ws, const bScreen *screen)
+static WorkSpaceLayout *workspace_layout_find(const WorkSpaceHook *hook, const bScreen *screen)
 {
-	for (WorkSpaceLayout *layout = ws->layouts.first; layout; layout = layout->next) {
+	for (WorkSpaceLayout *layout = hook->layouts.first; layout; layout = layout->next) {
 		if (layout->screen == screen) {
 			return layout;
 		}
@@ -207,6 +200,7 @@ static WorkSpaceLayout *workspace_layout_find(const WorkSpace *ws, const bScreen
 	return NULL;
 }
 
+#if 0
 /**
  * Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
  * WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -222,10

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list