[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42705] trunk/blender/source/blender/ editors: Fix for toggle buttons in node headers.

Lukas Toenne lukas.toenne at googlemail.com
Sun Dec 18 13:51:57 CET 2011


Revision: 42705
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42705
Author:   lukastoenne
Date:     2011-12-18 12:51:50 +0000 (Sun, 18 Dec 2011)
Log Message:
-----------
Fix for toggle buttons in node headers.

The buttons for "hiding" (collapsing) a node, hiding unlinked sockets, additional options, the preview and for opening a node group were all using a custom mouse test function, which was broken. They now use actual buttons instead of just displaying icons. Before executing the respective operators the button's node has to be selected and activated, so the buttons use an intermediate handle function, which selects the node and then calls the operator.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface_panel.c
    trunk/blender/source/blender/editors/space_node/node_draw.c
    trunk/blender/source/blender/editors/space_node/node_edit.c
    trunk/blender/source/blender/editors/space_node/node_intern.h
    trunk/blender/source/blender/editors/space_node/node_ops.c
    trunk/blender/source/blender/editors/space_node/node_select.c
    trunk/blender/source/blender/editors/space_node/node_state.c

Modified: trunk/blender/source/blender/editors/interface/interface_panel.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_panel.c	2011-12-18 09:36:47 UTC (rev 42704)
+++ trunk/blender/source/blender/editors/interface/interface_panel.c	2011-12-18 12:51:50 UTC (rev 42705)
@@ -330,7 +330,6 @@
 #endif
 
 /* triangle 'icon' for panel header */
-/* NOTE - this seems to be only used for hiding nodes now */
 void UI_DrawTriIcon(float x, float y, char dir)
 {
 	if(dir=='h') {

Modified: trunk/blender/source/blender/editors/space_node/node_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_draw.c	2011-12-18 09:36:47 UTC (rev 42704)
+++ trunk/blender/source/blender/editors/space_node/node_draw.c	2011-12-18 12:51:50 UTC (rev 42705)
@@ -562,6 +562,18 @@
 	
 }
 
+/* common handle function for operator buttons that need to select the node first */
+static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_argv)
+{
+	bNode *node = (bNode*)node_argv;
+	const char *opname = (const char *)op_argv;
+	
+	/* select & activate only the button's node */
+	node_select_single(C, node);
+	
+	WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
+}
+
 static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node)
 {
 	bNodeSocket *sock;
@@ -601,39 +613,54 @@
 	uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
 	uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
 	
-	/* show/hide icons, note this sequence is copied in do_header_node() node_state.c */
+	/* show/hide icons */
 	iconofs= rct->xmax - 7.0f;
 	
+	/* preview */
 	if(node->typeinfo->flag & NODE_PREVIEW) {
-		float alpha = (node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))? 1.0f: 0.5f;
-		
+		uiBut *but;
 		iconofs-=iconbutw;
-		uiDefIconBut(node->block, LABEL, B_REDR, ICON_MATERIAL, iconofs, rct->ymax-NODE_DY,
-					 iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, alpha, "");
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_MATERIAL,
+						   iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_preview_toggle");
+		/* XXX this does not work when node is activated and the operator called right afterwards,
+		 * since active ID is not updated yet (needs to process the notifier).
+		 * This can only work as visual indicator!
+		 */
+//		if (!(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT)))
+//			uiButSetFlag(but, UI_BUT_DISABLED);
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
 	}
+	/* group edit */
 	if(node->type == NODE_GROUP) {
-		
+		uiBut *but;
 		iconofs-=iconbutw;
-		uiDefIconBut(node->block, LABEL, B_REDR, ICON_NODETREE, iconofs, rct->ymax-NODE_DY,
-					 iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_NODETREE,
+						   iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_group_edit");
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
 	}
+	/* option buttons */
 	if(node->typeinfo->flag & NODE_OPTIONS) {
+		uiBut *but;
 		iconofs-=iconbutw;
-		uiDefIconBut(node->block, LABEL, B_REDR, ICON_BUTS, iconofs, rct->ymax-NODE_DY,
-					 iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_BUTS,
+						   iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_options_toggle");
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
 	}
-	{	/* always hide/reveal unused sockets */ 
-		// XXX re-enable
-		/* int shade;
-		if(node_has_hidden_sockets(node))
-			shade= -40;
-		else
-			shade= -90; */
-
+	/* hide unused sockets */
+	{
+		uiBut *but;
 		iconofs-=iconbutw;
-
-		uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY,
-						  iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_PLUS,
+						   iconofs, rct->ymax-NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_socket_toggle");
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
 	}
 	
 	/* title */
@@ -643,7 +670,19 @@
 		UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
 	
 	/* open/close entirely? */
-	UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v');
+	{
+		uiBut *but;
+		int but_size = UI_UNIT_X *0.6f;
+		/* XXX button uses a custom triangle draw below, so make it invisible without icon */
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefBut(node->block, TOGBUT, B_REDR, "",
+					   rct->xmin+10.0f-but_size/2, rct->ymax-NODE_DY/2.0f-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle");
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
+		
+		/* custom draw function for this button */
+		UI_DrawTriIcon(rct->xmin+10.0f, rct->ymax-NODE_DY/2.0f, 'v');
+	}
 	
 	/* this isn't doing anything for the label, so commenting out
 	if(node->flag & SELECT) 
@@ -789,7 +828,19 @@
 		UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.4f, 10);
 	
 	/* open entirely icon */
-	UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h');	
+	{
+		uiBut *but;
+		int but_size = UI_UNIT_X *0.6f;
+		/* XXX button uses a custom triangle draw below, so make it invisible without icon */
+		uiBlockSetEmboss(node->block, UI_EMBOSSN);
+		but = uiDefBut(node->block, TOGBUT, B_REDR, "",
+					   rct->xmin+10.0f-but_size/2, centy-but_size/2, but_size, but_size, NULL, 0, 0, 0, 0, "");
+		uiButSetFunc(but, node_toggle_button_cb, node, (void*)"NODE_OT_hide_toggle");
+		uiBlockSetEmboss(node->block, UI_EMBOSS);
+		
+		/* custom draw function for this button */
+		UI_DrawTriIcon(rct->xmin+10.0f, centy, 'h');
+	}
 	
 	/* disable lines */
 	if(node->flag & NODE_MUTED)

Modified: trunk/blender/source/blender/editors/space_node/node_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_edit.c	2011-12-18 09:36:47 UTC (rev 42704)
+++ trunk/blender/source/blender/editors/space_node/node_edit.c	2011-12-18 12:51:50 UTC (rev 42705)
@@ -690,108 +690,6 @@
 	}
 }
 
-static int compare_nodes(bNode *a, bNode *b)
-{
-	bNode *parent;
-	/* These tell if either the node or any of the parent nodes is selected.
-	 * A selected parent means an unselected node is also in foreground!
-	 */
-	int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
-	int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
-	
-	/* if one is an ancestor of the other */
-	/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
-	for (parent = a->parent; parent; parent=parent->parent) {
-		/* if b is an ancestor, it is always behind a */
-		if (parent==b)
-			return 1;
-		/* any selected ancestor moves the node forward */
-		if (parent->flag & NODE_ACTIVE)
-			a_active = 1;
-		if (parent->flag & NODE_SELECT)
-			a_select = 1;
-	}
-	for (parent = b->parent; parent; parent=parent->parent) {
-		/* if a is an ancestor, it is always behind b */
-		if (parent==a)
-			return 0;
-		/* any selected ancestor moves the node forward */
-		if (parent->flag & NODE_ACTIVE)
-			b_active = 1;
-		if (parent->flag & NODE_SELECT)
-			b_select = 1;
-	}
-
-	/* if one of the nodes is in the background and the other not */
-	if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
-		return 0;
-	else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
-		return 1;
-	
-	/* if one has a higher selection state (active > selected > nothing) */
-	if (!b_active && a_active)
-		return 1;
-	else if (!b_select && (a_active || a_select))
-		return 1;
-	
-	return 0;
-}
-/* Sorts nodes by selection: unselected nodes first, then selected,
- * then the active node at the very end. Relative order is kept intact!
- */
-void node_sort(bNodeTree *ntree)
-{
-	/* merge sort is the algorithm of choice here */
-	bNode *first_a, *first_b, *node_a, *node_b, *tmp;
-	int totnodes= BLI_countlist(&ntree->nodes);
-	int k, a, b;
-	
-	k = 1;
-	while (k < totnodes) {
-		first_a = first_b = ntree->nodes.first;
-		
-		do {
-			/* setup first_b pointer */
-			for (b=0; b < k && first_b; ++b) {
-				first_b = first_b->next;
-			}
-			/* all batches merged? */
-			if (first_b==NULL)
-				break;
-			
-			/* merge batches */
-			node_a = first_a;
-			node_b = first_b;
-			a = b = 0;
-			while (a < k && b < k && node_b) {
-				if (compare_nodes(node_a, node_b)==0) {
-					node_a = node_a->next;
-					++a;
-				}
-				else {
-					tmp = node_b;
-					node_b = node_b->next;
-					++b;
-					BLI_remlink(&ntree->nodes, tmp);
-					BLI_insertlinkbefore(&ntree->nodes, node_a, tmp);
-				}
-			}
-
-			/* setup first pointers for next batch */
-			first_b = node_b;
-			for (; b < k; ++b) {
-				/* all nodes sorted? */
-				if (first_b==NULL)
-					break;
-				first_b = first_b->next;
-			}
-			first_a = first_b;
-		} while (first_b);
-		
-		k = k << 1;
-	}
-}
-
 static int inside_rctf(rctf *bounds, rctf *rect)
 {
 	return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax
@@ -940,7 +838,7 @@
 	ED_preview_kill_jobs(C);
 
 	if (snode->nodetree==snode->edittree) {
-		bNode *gnode= nodeGetActive(snode->nodetree);
+		bNode *gnode = nodeGetActive(snode->edittree);
 		snode_make_group_editable(snode, gnode);
 	}
 	else
@@ -955,8 +853,11 @@
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
 	bNode *gnode;
-
-	gnode= nodeGetActive(snode->edittree);
+	
+	gnode = nodeGetActive(snode->edittree);
+	if (!gnode)
+		return OPERATOR_CANCELLED;
+	
 	/* XXX callback? */
 	if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) {
 		uiPupMenuOkee(C, op->type->idname, "Make group local?");
@@ -1696,91 +1597,9 @@
 	ot->flag= OPTYPE_BLOCKING;
 }
 
-/* ********************** select ******************** */
 
+/* ********************** hidden sockets ******************** */
 
-/* no undo here! */
-void node_deselectall(SpaceNode *snode)
-{
-	bNode *node;
-	
-	for(node= snode->edittree->nodes.first; node; node= node->next)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list