Node Editor: A bunch of new utility functions

Needed for node insert offset (Auto-offset in UI), but kept separate so people notice it without having to check insert offset commit (not for commit ratio of course ;) )
This commit is contained in:
Julian Eisel 2015-08-01 16:16:16 +02:00
parent fa1945c9e5
commit 31bf82c17d
5 changed files with 106 additions and 2 deletions

View File

@ -373,6 +373,7 @@ void ntreeFreeCache(struct bNodeTree *ntree);
int ntreeNodeExists(struct bNodeTree *ntree, struct bNode *testnode);
int ntreeOutputExists(struct bNode *node, struct bNodeSocket *testsock);
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable);
struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree);
@ -475,6 +476,15 @@ void nodeDetachNode(struct bNode *node);
struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name);
int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex);
struct bNode *nodeFindRootParent(bNode *node);
bool nodeIsChildOf(const bNode *parent, const bNode *child);
void nodeChainIter(
const bNodeTree *ntree, const bNode *node_start,
bool (*callback)(bNode *, bNode *, void *, const bool), void *userdata,
const bool reversed);
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to);
int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);

View File

@ -775,6 +775,78 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin
return 0;
}
/**
* \note Recursive
*/
bNode *nodeFindRootParent(bNode *node)
{
if (node->parent) {
return nodeFindRootParent(node->parent);
}
else {
return node->type == NODE_FRAME ? node : NULL;
}
}
/**
* \returns true if \a child has \a parent as a parent/grandparent/...
* \note Recursive
*/
bool nodeIsChildOf(const bNode *parent, const bNode *child)
{
if (parent == child) {
return true;
}
else if (child->parent) {
return nodeIsChildOf(parent, child->parent);
}
return false;
}
/**
* Iterate over a chain of nodes, starting with \a node_start, executing
* \a callback for each node (which can return false to end iterator).
*
* \param reversed for backwards iteration
* \note Recursive
*/
void nodeChainIter(
const bNodeTree *ntree, const bNode *node_start,
bool (*callback)(bNode *, bNode *, void *, const bool), void *userdata,
const bool reversed)
{
bNodeLink *link;
for (link = ntree->links.first; link; link = link->next) {
if (link->tonode && link->fromnode) {
/* is the link part of the chain meaning node_start == fromnode (or tonode for reversed case)? */
if ((reversed && (link->tonode == node_start)) ||
(!reversed && link->fromnode == node_start))
{
if (!callback(link->fromnode, link->tonode, userdata, reversed)) {
return;
}
nodeChainIter(ntree, reversed ? link->fromnode : link->tonode, callback, userdata, reversed);
}
}
}
}
/**
* Iterate over all parents of \a node, executing \a callback for each parent (which can return false to end iterator)
*
* \note Recursive
*/
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata)
{
if (node->parent) {
if (!callback(node->parent, userdata)) {
return;
}
nodeParentsIter(node->parent, callback, userdata);
}
}
/* ************** Add stuff ********** */
/* Find the first available, non-duplicate name for a given node */
@ -1963,6 +2035,20 @@ int ntreeOutputExists(bNode *node, bNodeSocket *testsock)
return 0;
}
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
{
bNode *node = ntree->nodes.first;
for (; node; node = node->next) {
if (enable) {
node->flag |= flag;
}
else {
node->flag &= ~flag;
}
}
}
/* returns localized tree for execution in threads */
bNodeTree *ntreeLocalize(bNodeTree *ntree)
{

View File

@ -308,6 +308,12 @@ void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry)
*ry *= UI_DPI_FAC;
}
void node_to_updated_rect(struct bNode *node, rctf *r_rect)
{
node_to_view(node, node->offsetx, node->offsety, &r_rect->xmin, &r_rect->ymax);
node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &r_rect->xmax, &r_rect->ymin);
}
void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry)
{
x /= UI_DPI_FAC;

View File

@ -84,6 +84,7 @@ void drawnodespace(const bContext *C, ARegion *ar);
void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode, float cursor[2]);
/* DPI scaled coords */
void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry);
void node_to_updated_rect(struct bNode *node, rctf *r_rect);
void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry);
/* node_buttons.c */
@ -225,7 +226,8 @@ extern const char *node_context_dir[];
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
#define NODE_SOCKDY (0.08f * U.widget_unit)
#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
#define NODE_HEIGHT(node) (node->height * UI_DPI_FAC)
#define NODE_MARGIN_X (0.75f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_LINK_RESOL 12

View File

@ -1006,7 +1006,7 @@ int WM_modalkeymap_items_to_string(
int WM_modalkeymap_operator_items_to_string(
wmOperatorType *ot, const int propvalue, const bool compact, const int len, char *r_str)
{
return WM_modalkeymap_items_to_string(ot->modalkeymap, propvalue, compact, len, r_str);
return WM_modalkeymap_items_to_string(ot->modalkeymap, propvalue, compact, len, r_str);
}
char *WM_modalkeymap_operator_items_to_string_buf(