[Bf-blender-cvs] [9db17849292] temp-workspace-multi-window: Add/use template for browsing layout-types of a workspace/window combination

Julian Eisel noreply at git.blender.org
Thu Mar 9 19:21:02 CET 2017


Commit: 9db17849292d48e01fb80c59c74c0a80f5614adf
Author: Julian Eisel
Date:   Thu Mar 9 19:09:15 2017 +0100
Branches: temp-workspace-multi-window
https://developer.blender.org/rB9db17849292d48e01fb80c59c74c0a80f5614adf

Add/use template for browsing layout-types of a workspace/window combination

Tried adding a more generic template for this first, but this is really
such a special case that it would need to have quite a bunch of
exceptions.
Basically we're showing the active layer-instance of the workspace in
the text button and within the menu, the layout-type list of the
workspace and their previews from the screen wrapped by the
layout-instance :S

Also made renaming work properly.

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

M	release/scripts/startup/bl_ui/space_info.py
M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_templates.c
M	source/blender/makesdna/dna_workspace_types.h
M	source/blender/makesrna/intern/rna_ui_api.c

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

diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 1d330b1e019..7c4f85a0d94 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -45,7 +45,10 @@ class INFO_HT_header(Header):
             layout.separator()
         else:
             layout.template_ID(window, "workspace", new="workspace.workspace_new", unlink="workspace.workspace_delete")
-            layout.template_ID_preview(window, "screen", window, "screens", new="screen.new", unlink="screen.delete", rows=2, cols=6)
+            row = layout.row(align=True)
+            row.template_layouts(window, "workspace")
+            row.operator("screen.new", text="", icon='ZOOMIN')
+            row.operator("screen.delete", text="", icon='X')
 
         if hasattr(workspace, 'object_mode'):
             act_mode_item = bpy.types.Object.bl_rna.properties['mode'].enum_items[workspace.object_mode]
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 7dd3e7ac2f6..9ddd4423dcd 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -60,6 +60,7 @@ void BKE_workspace_remove(WorkSpace *workspace, struct Main *bmain);
 
 WorkSpaceLayout *BKE_workspace_layout_add_from_type(
         WorkSpaceHook *hook, WorkSpaceLayoutType *type, struct bScreen *screen) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+void BKE_workspace_layout_rename(WorkSpace *workspace, WorkSpaceLayoutType *layout_type, const char *name) ATTR_NONNULL();
 void BKE_workspace_layout_remove(WorkSpace *workspace, WorkSpaceLayout *layout, struct Main *bmain) ATTR_NONNULL();
 WorkSpaceLayoutType *BKE_workspace_layout_type_add(WorkSpace *workspace, const char *name,
                                                    struct ScreenLayoutData layout_blueprint) ATTR_NONNULL();
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 98b5a3c037a..5083ca3db0f 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -28,6 +28,8 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
 
 #include "BKE_global.h"
 #include "BKE_library.h"
@@ -114,9 +116,9 @@ WorkSpaceLayoutType *BKE_workspace_layout_type_add(
 {
 	WorkSpaceLayoutType *layout_type = MEM_mallocN(sizeof(*layout_type), __func__);
 
-	layout_type->name = name; /* XXX should probably copy name */
 	layout_type->layout_blueprint = layout_blueprint;
-	BLI_addhead(&workspace->layout_types, layout_type);
+	BKE_workspace_layout_rename(workspace, layout_type, name);
+	BLI_addtail(&workspace->layout_types, layout_type);
 
 	return layout_type;
 }
@@ -140,6 +142,13 @@ void BKE_workspace_layout_type_remove(WorkSpace *workspace, WorkSpaceLayoutType
 	BLI_freelinkN(&workspace->layout_types, layout_type);
 }
 
+void BKE_workspace_layout_rename(WorkSpace *workspace, WorkSpaceLayoutType *layout_type, const char *name)
+{
+	BLI_strncpy(layout_type->name, name, sizeof(layout_type->name));
+	BLI_uniquename(&workspace->layout_types, layout_type, "Layout", '.', offsetof(WorkSpaceLayoutType, name),
+	               sizeof(layout_type->name));
+}
+
 /**
  * Removes all variations of the layout-type of \a layout.
  */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 0df5e6ddb29..e51ea3deef6 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -917,6 +917,7 @@ void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA
                          const char *openop, const char *unlinkop, int rows, int cols);
 void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname, 
                      const char *proptypename, const char *text);
+void uiTemplateLayouts(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int rows, int cols);
 void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char *propname, 
                            struct PointerRNA *root_ptr, const char *text);
 uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 8ebfb64abab..2e1ed937e3e 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -70,6 +70,7 @@
 #include "BKE_sca.h"
 #include "BKE_screen.h"
 #include "BKE_texture.h"
+#include "BKE_workspace.h"
 
 #include "ED_screen.h"
 #include "ED_object.h"
@@ -844,6 +845,126 @@ void uiTemplateAnyID(
 	uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
 }
 
+/********************* Screen-layout Template ********************/
+
+struct ScreenLayoutTemplate {
+	WorkSpace *workspace;
+	int prv_rows, prv_cols;
+};
+
+static void layout_search_call_cb(bContext *C, void *UNUSED(arg), void *item)
+{
+	WorkSpaceLayout *layout = item;
+	WM_event_add_notifier(C, NC_WORKSPACE | ND_SCREENBROWSE, layout);
+}
+
+static void layout_search_cb(const bContext *C, void *arg, const char *str, uiSearchItems *items)
+{
+	struct ScreenLayoutTemplate *templ = arg;
+	wmWindow *win = CTX_wm_window(C);
+	ListBase *layout_types = BKE_workspace_layout_types_get(templ->workspace);
+
+	BKE_workspace_layout_type_iter_begin(layout_type, layout_types->first)
+	{
+		WorkSpaceLayout *layout = BKE_workspace_layout_find_from_type(win->workspace_hook, layout_type);
+		bScreen *screen = BKE_workspace_layout_screen_get(layout);
+		const char *name = BKE_workspace_layout_type_name_get(layout_type);
+
+		if (*str == '\0' || BLI_strcasestr(name, str)) {
+			int iconid = ui_id_icon_get(C, &screen->id, true);
+
+			if (UI_search_item_add(items, name, layout, iconid) == false) {
+				break;
+			}
+		}
+	}
+	BKE_workspace_layout_type_iter_end;
+}
+
+static uiBlock *layout_search_menu(bContext *C, ARegion *ar, void *arg)
+{
+	struct ScreenLayoutTemplate *templ = arg;
+	wmWindow *win = CTX_wm_window(C);
+	uiBlock *block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+	int w = 4 * U.widget_unit * templ->prv_cols;
+	int h = 5 * U.widget_unit * templ->prv_rows;
+	uiBut *but;
+	static char search[256];
+
+	/* clear initial search string, then all items show */
+	search[0] = 0;
+	UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
+
+	/* fake button, it holds space for search items */
+	uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
+	/* search button (layout items are added through callbacks) */
+	but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
+	                     templ->prv_rows, templ->prv_cols, "");
+	UI_but_func_search_set(
+	        but, ui_searchbox_create_generic, layout_search_cb,
+	        templ, layout_search_call_cb, NULL);
+
+	UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+	UI_block_direction_set(block, UI_DIR_DOWN);
+
+	/* give search-field focus */
+	UI_but_focus_on_enter_event(win, but);
+	/* this type of search menu requires undo */
+	but->flag |= UI_BUT_UNDO;
+
+	return block;
+}
+
+static void template_layouts_draw(uiLayout *layout, struct ScreenLayoutTemplate *templ)
+{
+	WorkSpaceLayoutType *layout_type = BKE_workspace_active_layout_type_get(templ->workspace);
+	const char *layout_name = BKE_workspace_layout_type_name_get(layout_type);
+	uiBlock *block = uiLayoutGetBlock(layout);
+	uiBut *but;
+
+	/* menu button */
+	but = uiDefBlockButN(block, layout_search_menu, templ, "", 0, 0, UI_UNIT_X * 1.6f, UI_UNIT_Y,
+	                    "Browse the screen-layouts of this workspace");
+	ui_def_but_icon(but, RNA_struct_ui_icon(&RNA_Screen), UI_HAS_ICON);
+	UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+	/* text button with name */
+	but = uiDefBut(block, UI_BTYPE_TEXT, 0, "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, (void *)layout_name,
+	               0.0f, 64, 0.0f, 0.0f, "Name of the layout");
+	UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
+}
+
+void uiTemplateLayouts(uiLayout *layout, PointerRNA *ptr, const char *propname, int rows, int cols)
+{
+	struct ScreenLayoutTemplate *templ;
+	PropertyRNA *prop;
+	PointerRNA workspace_ptr;
+
+	if (!ptr->data) {
+		return;
+	}
+
+	prop = RNA_struct_find_property(ptr, propname);
+
+	if (!prop) {
+		printf("%s: property not found: %s.%s\n",
+		       __func__, RNA_struct_identifier(ptr->type), propname);
+		return;
+	}
+
+	if (RNA_property_type(prop) != PROP_POINTER) {
+		printf("%s: expected pointer property for %s.%s\n",
+		       __func__, RNA_struct_identifier(ptr->type), propname);
+		return;
+	}
+
+	workspace_ptr = RNA_property_pointer_get(ptr, prop);
+	templ = MEM_callocN(sizeof(*templ), __func__);
+	templ->workspace = workspace_ptr.data;
+	templ->prv_rows = rows;
+	templ->prv_cols = cols;
+	template_layouts_draw(layout, templ);
+}
+
 /********************* RNA Path Builder Template ********************/
 
 /* ---------- */
diff --git a/source/blender/makesdna/dna_workspace_types.h b/source/blender/makesdna/dna_workspace_types.h
index 3e3796da11a..a5819d47ad7 100644
--- a/source/blender/makesdna/dna_workspace_types.h
+++ b/source/blender/makesdna/dna_workspace_types.h
@@ -49,7 +49,7 @@ typedef struct WorkSpaceLayout {
 
 typedef struct WorkSpaceLayoutType {
 	struct WorkSpaceLayoutType *next, *prev;
-	const char *name;
+	char name[64];
 
 	/* this contains the data we use for creating a new WorkSpaceLayout from this type. */
 	ScreenLayoutData layout_blueprint;
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index b78e829aac3..eac5112f2de 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -931,6 +931,12 @@ void RNA_api_ui_layout(StructRNA *srna)
 	RNA_def_function_ui_description(func, "Item(s). User interface for selecting cache files and their source paths");
 	RNA_def_function_flag(func, FUNC_USE_CONTEXT);
 	api_ui_item_rna_common(func);
+
+	func = RN

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list