[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58497] branches/soc-2013-ui_replay/source /blender: Quick test to see how to implement default operator properties in a button 's right click popup menu.

Vincent Akkermans vincent at ack-err.net
Mon Jul 22 11:32:07 CEST 2013


Revision: 58497
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58497
Author:   ack-err
Date:     2013-07-22 09:32:07 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
Quick test to see how to implement default operator properties in a button's right click popup menu.

Some not so nice, rough corners:
* default properties are stored in a wmOperator in wmOperatorType and duplicated in default_properties.
* wmOperators in wmOperatorType aren't cleaned on exit yet.
* the widgets in the popup are not properly aligned.
* lots of properties are ignored upon executing an operator.

Modified Paths:
--------------
    branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c
    branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/WM_api.h
    branches/soc-2013-ui_replay/source/blender/windowmanager/WM_types.h
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_event_system.c
    branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_operators.c

Modified: branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/editors/include/UI_interface.h	2013-07-22 09:32:07 UTC (rev 58497)
@@ -760,6 +760,7 @@
 void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op,
                           bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
                           const char label_align, const short flag);
+void uiLayoutOperatorTypeDefaultsButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op);
 struct MenuType *uiButGetMenuType(uiBut *but);
 
 void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext);

Modified: branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/editors/interface/interface_handlers.c	2013-07-22 09:32:07 UTC (rev 58497)
@@ -4927,6 +4927,11 @@
 	uiPupBlock(C, menu_add_shortcut, but);
 }
 
+static void ui_but_menu_set_last_properties(bContext *UNUSED(C), void *arg_op, int UNUSED(arg_event))
+{
+	wmOperator *op = (wmOperator*)arg_op;
+	WM_operator_default_properties_store(op);
+}
 
 static bool ui_but_menu(bContext *C, uiBut *but)
 {
@@ -5123,6 +5128,36 @@
 		wmKeyMap *km;
 		wmKeyMapItem *kmi = NULL;
 		int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
+		wmOperator *op;
+		
+		uiItemS(layout);
+		
+		/* operator defaults */
+		
+		/* initialise the operator type's default properties from the temporary operator */
+		if (but->optype->default_properties_op) {
+			// make sure the temporary operator has the latest default properties set.
+			WM_operator_properties_init(but->optype->default_properties_op);
+		} else {
+			// make sure the last_properties are set from the new operator.
+			but->optype->default_properties_op = WM_operator_create(C, but->optype, NULL, NULL);
+		}
+		
+		uiBlockSetHandleFunc(block, &ui_but_menu_set_last_properties, but->optype->default_properties_op);
+		
+		// add panels for all operators in a macro
+		if (but->optype->flag & OPTYPE_MACRO) {
+			for (op = but->optype->default_properties_op->macro.first; op; op = op->next) {
+				uiLayoutOperatorTypeDefaultsButs(C, layout, op);
+			}
+		}
+		else {
+			uiLayoutOperatorTypeDefaultsButs(C, layout, but->optype->default_properties_op);
+		}
+		
+		uiItemS(layout);
+		
+		
 
 		if (kmi_id)
 			kmi = WM_keymap_item_find_id(km, kmi_id);

Modified: branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/editors/interface/interface_layout.c	2013-07-22 09:32:07 UTC (rev 58497)
@@ -3087,6 +3087,69 @@
 	}
 }
 
+void uiLayoutOperatorTypeDefaultsButs(const bContext *C, uiLayout *layout, wmOperator *op)
+{
+	char *h = BLI_sprintfN("Default parameters: %s", RNA_struct_ui_name(op->type->srna));
+	
+	uiItemL(layout, h, ICON_NONE);
+	MEM_freeN(h);
+	
+	// use operator's custom panel
+	if (op->type->ui) {
+		op->layout = layout;
+		op->type->ui((bContext *)C, op);
+		op->layout = NULL;
+	}
+	// autogenerate panel
+	else {
+		wmWindowManager *wm = CTX_wm_manager(C);
+		PointerRNA ptr;
+		int empty;
+		
+		RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+		
+		empty = uiDefAutoButsRNA(layout, &ptr, NULL, 'V') == 0;
+		
+		if (empty) {
+			uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
+		}
+	}
+	
+#ifdef USE_OP_RESET_BUT
+	/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
+	 * but this is not so important if this button is drawn in those cases
+	 * (which isn't all that likely anyway) - campbell */
+	if (op->properties->len) {
+		uiBlock *block;
+		uiBut *but;
+		uiLayout *col; /* needed to avoid alignment errors with previous buttons */
+		
+		col = uiLayoutColumn(layout, FALSE);
+		block = uiLayoutGetBlock(col);
+		but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
+		                       NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
+		uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
+	}
+#endif
+	
+	/* set various special settings for buttons */
+	{
+		uiBut *but;
+		
+		for (but = uiLayoutGetBlock(layout)->buttons.first; but; but = but->next) {
+			/* no undo for buttons for operator redo panels */
+			uiButClearFlag(but, UI_BUT_UNDO);
+			
+			/* if button is operator's default property, and a text-field, enable focus for it
+			 *	- this is used for allowing operators with popups to rename stuff with fewer clicks
+			 */
+			if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
+				uiButSetFocusOnEnter(CTX_wm_window(C), but);
+			}
+		}
+	}
+}
+
 /* this is a bit of a hack but best keep it in one place at least */
 MenuType *uiButGetMenuType(uiBut *but)
 {

Modified: branches/soc-2013-ui_replay/source/blender/windowmanager/WM_api.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/windowmanager/WM_api.h	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/windowmanager/WM_api.h	2013-07-22 09:32:07 UTC (rev 58497)
@@ -252,9 +252,12 @@
 bool        WM_operator_check_ui_enabled(const struct bContext *C, const char *idname);
 wmOperator *WM_operator_last_redo(const struct bContext *C);
 
+wmOperator *WM_operator_create(const struct bContext *C, struct wmOperatorType *ot,
+							   struct PointerRNA *properties, struct ReportList *reports);
 wmOperator *WM_operator_copy(struct bContext *C, wmOperator *op, bool copylink);
-bool        WM_operator_last_properties_init(struct wmOperator *op);
+bool        WM_operator_properties_init(struct wmOperator *op);
 bool        WM_operator_last_properties_store(struct wmOperator *op);
+bool		WM_operator_default_properties_store(struct wmOperator *op);
 
 /* MOVE THIS SOMEWHERE ELSE */
 #define	SEL_TOGGLE		0

Modified: branches/soc-2013-ui_replay/source/blender/windowmanager/WM_types.h
===================================================================
--- branches/soc-2013-ui_replay/source/blender/windowmanager/WM_types.h	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/windowmanager/WM_types.h	2013-07-22 09:32:07 UTC (rev 58497)
@@ -564,6 +564,10 @@
 	/* rna for properties */
 	struct StructRNA *srna;
 
+	/* default settings - for initializing */
+	struct IDProperty *default_properties;
+	struct wmOperator *default_properties_op;
+	
 	/* previous settings - for initializing on re-use */
 	struct IDProperty *last_properties;
 

Modified: branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_event_system.c	2013-07-22 08:56:51 UTC (rev 58496)
+++ branches/soc-2013-ui_replay/source/blender/windowmanager/intern/wm_event_system.c	2013-07-22 09:32:07 UTC (rev 58497)
@@ -837,6 +837,13 @@
 	return op;
 }
 
+wmOperator *WM_operator_create(const bContext *C, wmOperatorType *ot,
+							   PointerRNA *properties, ReportList *reports)
+{
+	wmWindowManager *wm = CTX_wm_manager(C);
+	return wm_operator_create(wm, ot, properties, reports);
+}
+
 wmOperator *WM_operator_copy(bContext *C, wmOperator *op, bool copylink)
 {
 	/* The logic wm_operator_create is used as it already
@@ -845,9 +852,7 @@
 	wmWindowManager *wm = CTX_wm_manager(C);
 	wmOperator *newop = wm_operator_create(wm, op->type, op->ptr, NULL);
 
-	/* This likely isn't necessary, have to look closer at
-	 * what BLI_addTail does, or whether these links are
-	 * used in anywhere. However, better safe than sorry. */
+	/* This likely isn't necessary. */
 	if(!copylink)
 	{
 		newop->next = NULL;
@@ -871,59 +876,68 @@
 	}
 }
 
+static bool wm_operator_properties_init_set(wmOperator *op, IDProperty **properties, bool respect_skip_save, bool respect_already_set) {
+	PropertyRNA *iterprop = iterprop = RNA_struct_iterator_property(op->type->srna);
+	bool change = false;
+	RNA_PROP_BEGIN (op->ptr, itemptr, iterprop)
+	{
+		PropertyRNA *prop = itemptr.data;
+		if (!respect_skip_save || (RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
+			if (!respect_already_set || !RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */
+				const char *identifier = RNA_property_identifier(prop);
+				IDProperty *idp_src = IDP_GetPropertyFromGroup(*properties, identifier);
+				if (idp_src) {
+					IDProperty *idp_dst = IDP_CopyProperty(idp_src);
+					
+					/* note - in the future this may need to be done recursively,
+					 * but for now RNA doesn't access nested operators */
+					idp_dst->flag |= IDP_FLAG_GHOST;
+					
+					IDP_ReplaceInGroup(op->properties, idp_dst);
+					change = true;
+				}
+			}
+		}
+	}
+	RNA_PROP_END;
+	return change;
+}
+
 #if 1 /* may want to disable operator remembering previous state for testing */
-bool WM_operator_last_properties_init(wmOperator *op)
+bool WM_operator_properties_init(wmOperator *op)
 {
 	bool change = false;
 
+	if (op->type->default_properties) {
+		if (G.debug & G_DEBUG_WM) {
+			printf("%s: loading default properties for '%s'\n", __func__, op->type->idname);
+		}
+		change = wm_operator_properties_init_set(op, &(op->type->default_properties), FALSE, FALSE);
+	}
 	if (op->type->last_properties) {
-		PropertyRNA *iterprop;
-
 		if (G.debug & G_DEBUG_WM) {
 			printf("%s: loading previous properties for '%s'\n", __func__, op->type->idname);
 		}
-
-		iterprop = RNA_struct_iterator_property(op->type->srna);
-
-		RNA_PROP_BEGIN (op->ptr, itemptr, iterprop)
-		{
-			PropertyRNA *prop = itemptr.data;
-			if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
-				if (!RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */
-					const char *identifier = RNA_property_identifier(prop);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list