ace7d6c2a03c2ad76c14134546785b8c3fa61ac2 kate Tue Jan 8 11:39:09 2019 -0800 Implement 'packDense' setting (tentative name) to support Regeneron 2nd contract amino acide display. This setting will pack items on a single line if they are adjacent (suppresses padding between packed items). refs #22739 diff --git src/lib/spaceSaver.c src/lib/spaceSaver.c index f5297a6..32e07c2 100644 --- src/lib/spaceSaver.c +++ src/lib/spaceSaver.c @@ -47,60 +47,60 @@ slFreeList(&ss->nodeList); freez(pSs); } } static boolean allClear(bool *b, int count) /* Return TRUE if count bools starting at b are all 0 */ { int i; for (i=0; i<count; ++i) if (b[i]) return FALSE; return TRUE; } -struct spaceNode *spaceSaverAddOverflowMulti(struct spaceSaver *ss, +struct spaceNode *spaceSaverAddOverflowMultiOptionalPadding(struct spaceSaver *ss, struct spaceRange *rangeList, struct spaceNode *nodeList, - boolean allowOverflow) + boolean allowOverflow, boolean doPadding) /* Add new nodes for multiple windows to space saver. Returns NULL if can't fit item in * and allowOverflow == FALSE. If allowOverflow == TRUE then put items * that won't fit in first row (ends up being last row after - * spaceSaverFinish()). */ + * spaceSaverFinish()). Allow caller to suppress padding between items + * (show adjacent items on single row */ { -//int cellStart, cellEnd, cellWidth; struct spaceRowTracker *srt, *freeSrt = NULL; int rowIx = 0; struct spaceNode *sn; if (ss->isFull) return NULL; struct spaceRange *range; struct spaceRange *cellRanges = NULL, *cellRange; for (range = rangeList; range; range = range->next) { AllocVar(cellRange); int start = range->start; int end = range->end; if ((start -= ss->winStart) < 0) start = 0; end -= ss->winStart; /* We'll clip this in cell coordinates. */ - cellRange->start = round(start * ss->scale); - cellRange->end = round(end * ss->scale)+1; + int padding = doPadding ? 1 : 0; + cellRange->end = round(end * ss->scale) + padding; if (cellRange->end > ss->cellsInRow) cellRange->end = ss->cellsInRow; cellRange->width = cellRange->end - cellRange->start; slAddHead(&cellRanges, cellRange); } slReverse(&cellRanges); if (ss->vis == 2) // tvFull for BEDLIKE tracks does not pack, so force a new line { rowIx = ss->rowCount; } else { /* Find free row. */ @@ -160,30 +160,40 @@ // struct spaceNode *snNext; for (sn=nodeList; sn; sn=snNext) { /* Make a space node. If allowing overflow it will all end up in the last row. */ //AllocVar(sn); sn->row = rowIx; //sn->val = val; snNext = sn->next; slAddHead(&sn->parentSs->nodeList, sn); } return nodeList; } +struct spaceNode *spaceSaverAddOverflowMulti(struct spaceSaver *ss, + struct spaceRange *rangeList, struct spaceNode *nodeList, + boolean allowOverflow) +/* Add new nodes for multiple windows to space saver. Returns NULL if can't fit item in + * and allowOverflow == FALSE. If allowOverflow == TRUE then put items + * that won't fit in first row (ends up being last row after + * spaceSaverFinish()). */ +{ +return spaceSaverAddOverflowMultiOptionalPadding(ss, rangeList, nodeList, allowOverflow, TRUE); +} struct spaceNode *spaceSaverAddOverflowExtended(struct spaceSaver *ss, int start, int end, void *val, boolean allowOverflow, struct spaceSaver *parentSs, bool noLabel) /* Add a new node to space saver. Returns NULL if can't fit item in * and allowOverflow == FALSE. If allowOverflow == TRUE then put items * that won't fit in last row. parentSs allows specification of destination for node from alternate window.*/ { struct spaceRange *range; AllocVar(range); range->start = start; range->end = end; struct spaceNode *node; AllocVar(node); node->val = val; node->parentSs = parentSs;