06be007e1b8b1724b61efcf0535089db5abb10da
kate
  Wed Aug 29 15:00:46 2018 -0700
Refactor in preparation for flipped display. refs #21917

diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c
index e469f8c..df88b5b 100644
--- src/hg/hgTracks/interactTrack.c
+++ src/hg/hgTracks/interactTrack.c
@@ -250,42 +250,40 @@
 safef(buf, sizeof(buf),"foot=%s", cgiEncode(endpointName));
 return(cloneString(buf));
 }
 
 static void interactDrawItems(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width, 
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw a list of interact structures. */
 {
 #define DRAW_LINE       0
 #define DRAW_CURVE      1
 #define DRAW_ELLIPSE    2
 
 // Determine drawing mode
 int draw = DRAW_LINE;
-boolean doDashes = FALSE;
 if (vis != tvDense)
     {
     char *drawMode = cartUsualStringClosestToHome(cart, tg->tdb, FALSE,
                                 INTERACT_DRAW, INTERACT_DRAW_DEFAULT);
     if (sameString(drawMode, INTERACT_DRAW_CURVE))
         draw = DRAW_CURVE;
     else if (sameString(drawMode, INTERACT_DRAW_ELLIPSE))
         draw = DRAW_ELLIPSE;
-    doDashes = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE,
-                                INTERACT_DIRECTION_DASHES, INTERACT_DIRECTION_DASHES_DEFAULT);
     }
+
 double scale = scaleForWindow(width, seqStart, seqEnd);
 struct interact *inter = NULL;
 char buffer[1024];
 char itemBuf[2048];
 int chromStart, chromEnd;
 
 // Gather info for layout
 struct interactTrackInfo *tInfo = interactGetTrackInfo(tg, seqStart, hvg, xOff, font, scale);
 
 // Get spectrum range
 int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMin", "0"));
 int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMax", "1000"));
 
 // Draw items
 struct hash *footHash = hashNew(0);
@@ -319,32 +317,31 @@
             }
         else
             {
             height = tInfo->otherHeight/2;
             yOffOther = yOff + tInfo->sameHeight;
             }
         unsigned r = interactRegionCenter(inter->chromStart, inter->chromEnd);
         int x = getX(r, seqStart, scale, xOff); 
         int footWidth = regionFootWidth(inter->chromStart, inter->chromEnd, scale);
         unsigned yPos = yOffOther + height;
 
         // draw the foot (2 pixels high)
         hvGfxBox(hvg, x - footWidth, yOffOther, footWidth + footWidth + 1, 2, color);
 
         // draw the vertical
-        boolean isReversed = tInfo->isDirectional && differentString(inter->chrom, inter->sourceChrom);
-        if (isReversed && doDashes)
+        if (tInfo->isDirectional && differentString(inter->chrom, inter->sourceChrom))
             hvGfxDottedLine(hvg, x, yOffOther, x, yPos, color, TRUE);
         else
             hvGfxLine(hvg, x, yOffOther, x, yPos, color);
         
         if (vis == tvDense)
             continue;
 
         // add map box to foot
         char *nameBuf = (inter->chromStart == inter->sourceStart ?      
                         inter->sourceName : inter->targetName);
         char *clickArg = endpointClickArg(nameBuf);
         if (isEmptyTextField(nameBuf))
             nameBuf = statusBuf;
         chromStart = inter->chromStart;
         chromEnd = inter->chromEnd;
@@ -409,52 +406,52 @@
     if (sOnScreen)
         {
         safef(footBuf, sizeof(footBuf), "%s:%d-%d", inter->sourceChrom,
                                                         inter->sourceStart, inter->sourceEnd);
         char *footPos = cloneString(footBuf);
         if (hashLookup(footHash, footPos))
             footColor = MG_BLACK;
         else
             hashStore(footHash, footPos);
 
         // draw foot of source region (2 pixels high)
         hvGfxBox(hvg, sX - sWidth, ySource, sWidth + sWidth + 1, 2, footColor);
         if (vis == tvDense || !tOnScreen || draw == DRAW_LINE || hvg->rc)
             {
             // draw vertical
-            if (isReversed && doDashes)
+            if (isReversed && (!tInfo->offset || draw == DRAW_ELLIPSE))
                 hvGfxDottedLine(hvg, sX, ySource, sX, peak, color, TRUE);
             else
                 hvGfxLine(hvg, sX, ySource, sX, peak, color);
             }
         }
     if (tOnScreen)
         {
         safef(footBuf, sizeof(footBuf), "%s:%d-%d", inter->targetChrom,
                                                         inter->targetStart, inter->targetEnd);
         char *footPos = cloneString(footBuf);
         if (hashLookup(footHash, footPos))
             footColor = MG_BLACK;
         else
             hashStore(footHash, footPos);
 
         // draw foot of target region (2 pixels high)
         hvGfxBox(hvg, tX - tWidth, yTarget, tWidth + tWidth + 1, 2, footColor);
         if (vis == tvDense || !sOnScreen || draw == DRAW_LINE || hvg->rc)
             {
             // draw vertical
-            if (isReversed && doDashes)
+            if (isReversed && (!tInfo->offset || draw == DRAW_ELLIPSE))
                 hvGfxDottedLine(hvg, tX, yTarget, tX, peak, color, TRUE);
             else
                 hvGfxLine(hvg, tX, yTarget, tX, peak, color);
             }
         }
     if (vis == tvDense)
         continue;
 
     // Full mode: add map boxes and draw interaction
     int highlightColor = MG_WHITE;
     chromStart = inter->chromStart;
     chromEnd = inter->chromEnd;
     char *nameBuf = NULL;
     if (sOnScreen)
         {
@@ -491,66 +488,68 @@
     // Draw interaction and map boxes
     int lowerX = 0, upperX = 0;
     if (s < t)
         {
         lowerX = sOnScreen ? sX : xOff;
         upperX = tOnScreen ? tX : xOff + width;
         }
     else
         {
         lowerX = tOnScreen ? tX : xOff;
         upperX = sOnScreen ? sX : xOff + width;
         }
     if (draw == DRAW_LINE || !sOnScreen || !tOnScreen || hvg->rc)
         {
         // draw horizontal line between region centers at 'peak' height
-        if (isReversed && doDashes)
+        if (isReversed)
             hvGfxDottedLine(hvg, lowerX, peak, upperX, peak, color, TRUE);
         else
             hvGfxLine(hvg, lowerX, peak, upperX, peak, color);
 
         // map box on mid-point of horizontal line
         int xMap = lowerX + (double)(upperX-lowerX)/2;
         int yMap = peak-1;
         hvGfxBox(hvg, xMap-1, peak-1, 3, 3, peakColor);
         hvGfxBox(hvg, xMap, peak, 1, 1, highlightColor);
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, xMap-1, yMap-1, 3, 3,
                            tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
         continue;
         }
     // Draw curves
     if (draw == DRAW_CURVE)
         {
         int peakX = ((upperX - lowerX + 1) / 2) + lowerX;
         int peakY = peak + 30; // admittedly a hack (obscure how to define ypeak of curve)
+        boolean drawDashed = isReversed;
+        if (tInfo->offset)
+            drawDashed = FALSE;
         int maxY = hvGfxCurve(hvg, lowerX, 
                                 (isReversed ? yTarget : ySource), peakX, peakY, upperX, 
-                                (isReversed ? ySource : yTarget), color, isReversed && doDashes);
+                                (isReversed ? ySource : yTarget), color, drawDashed);
         // curve drawer does not use peakY as expected, so it returns actual max Y used
         // draw map box on peak
         hvGfxBox(hvg, peakX-1, maxY-1, 3, 3, peakColor);
         hvGfxBox(hvg, peakX, maxY, 1, 1, highlightColor);
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, peakX-1, maxY-1, 3, 3,
                        tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
         }
     else if (draw == DRAW_ELLIPSE)
         {
         // can not support offsets
         int yLeft = yOff + peakHeight;
         int yTop = yOff - peakHeight;
-        hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ELLIPSE_BOTTOM, 
-                                isReversed && doDashes);
+        hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ELLIPSE_BOTTOM, isReversed);
         // draw map box on peak
         int maxY = peakHeight + yOff;
         int peakX = ((upperX - lowerX + 1) / 2) + lowerX;
         hvGfxBox(hvg, peakX-1, maxY-1, 3, 3, peakColor);
         hvGfxBox(hvg, peakX, maxY, 1, 1, highlightColor);
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, peakX-1, maxY-1, 3, 3,
                        tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
         }
     }
 }
 
 void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd,
     struct hvGfx *hvg, int xOff, int yOff, int width, int height,
     boolean withCenterLabels, MgFont *font,
     Color color, enum trackVisibility vis)