5b4f3f94dc828128ddd13c8a192d7762b3f74878
kate
  Thu Oct 11 11:01:39 2018 -0700
Fix grab box peak location for all drawing modes. refs #21917

diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c
index 14af2fb..c07e5bd 100644
--- src/hg/hgTracks/interactTrack.c
+++ src/hg/hgTracks/interactTrack.c
@@ -441,30 +441,36 @@
     if (inter->value != 0.0)
         dyStringPrintf(ds, " %0.2f", inter->value);
     return dyStringCannibalize(&ds);
 }
 
 int regionFootWidth(int start, int end, double scale)
     /* Return half foot width in pixels */
 {
     unsigned size = end - start;
     int width = scale * (double)size / 2;
     if (width == 0)
         width = 1;
     return width;
 }
 
+/* Draw helper routines */
+
+#define DRAW_LINE       0
+#define DRAW_CURVE      1
+#define DRAW_ELLIPSE    2
+
 static void drawFoot(struct track *tg, struct hvGfx *hvg, char *seq, int seqStart, int seqEnd, 
         int x, int y, int width, Color color, boolean drawUp, struct hash *footHash)
 /* Draw interaction end, 2 pixels high.  Force to black if it exactly overlaps another */
 {
 char buf[256];
 safef(buf, sizeof(buf), "%s:%d-%d", seq, seqStart, seqEnd);
 char *pos = cloneString(buf);
 Color footColor = color;
 if (hashLookup(footHash, pos))
     footColor = MG_BLACK;
 else
     hashStore(footHash, pos);
 if (drawUp)
     y = flipY(tg, y) - 2;
 hvGfxBox(hvg, x, y, width, 2, footColor);
@@ -494,51 +500,49 @@
 if (!isEmptyTextField(item))
     {
     char buf[256];
     safef(buf, sizeof(buf),"foot=%s", cgiEncode(item));
     clickArg = cloneString(buf);
     }
 char *itemBuf = isEmptyTextField(item) ? status : item;
 if (drawUp)
     y = flipY(tg, y) - 3;
 hvGfxBox(hvg, x-1, y, 3, 2, peakColor);
 hvGfxBox(hvg, x, y, 1, 1, highlightColor);
 mapBoxHgcOrHgGene(hvg, start, end, x - width, y, width * 2, 4,
                    tg->track, item, itemBuf, NULL, TRUE, clickArg);
 }
 
-void drawPeakMapbox(struct track *tg, struct hvGfx *hvg, int seqStart, int seqEnd, char *item, char *status,
-                        int x, int y, Color peakColor, Color highlightColor, boolean drawUp)
+void drawPeakMapbox(struct track *tg, struct hvGfx *hvg, int seqStart, int seqEnd, 
+                        char *item, char *status, int x, int y, 
+                        Color peakColor, Color highlightColor, boolean drawUp, int drawMode)
 /* Draw grab box and add map box */
 {
+int yAdjust = (drawMode == DRAW_CURVE ? 3 : 0);
 if (drawUp)
-    y = flipY(tg, y) - 3;
+    y = flipY(tg, y) - yAdjust;
 hvGfxBox(hvg, x-1, y-1, 3, 3, peakColor);
 hvGfxBox(hvg, x, y, 1, 1, highlightColor);
 mapBoxHgcOrHgGene(hvg, seqStart, seqEnd, x-1, y-1, 3, 3,
                    tg->track, item, status, NULL, TRUE, NULL);
 }
 
 static void drawInteractItems(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 items with connectors (e.g. curves) */
 {
-#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);
@@ -722,74 +726,74 @@
         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
         drawLine(tg, hvg, lowerX, peak, upperX, peak, color, isReversed && doDashes, drawUp);
 
         // draw grab box and map box on mid-point of horizontal line
         int xMap = lowerX + (double)(upperX-lowerX)/2;
         drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, itemBuf, statusBuf,
-                            xMap, peak, peakColor, highlightColor, drawUp);
+                            xMap, peak, peakColor, highlightColor, drawUp, draw);
         continue;
         }
     // Draw curves
     if (draw == DRAW_CURVE)
         {
         int peakX = ((upperX - lowerX + 1) / 2) + lowerX;
         int fudge = 30;
         int peakY = peak + fudge; // admittedly a hack (obscure how to define ypeak of curve)
         int y1 = isReversed ? yTarget : ySource;
         int y2 = isReversed ? ySource : yTarget;
         if (drawUp)
             {
             y1 = flipY(tg, y1);
             y2 = flipY(tg, y2);
             peakY = flipY(tg, peakY);
             }
         int maxY = hvGfxCurve(hvg, lowerX, y1, peakX, peakY, upperX, y2, color, isReversed && doDashes);
         // curve drawer does not use peakY as expected, so it returns actual max Y used
         // draw grab box and map box on peak
         if (drawUp)
             maxY = (maxY - peakY)/2 + tg->customInt;
         drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf,
-                            peakX, maxY, peakColor, highlightColor, drawUp);
+                            peakX, maxY, peakColor, highlightColor, drawUp, draw);
         }
     else if (draw == DRAW_ELLIPSE)
         {
         // can not support offsets
         int yLeft = yOff + peakHeight;
         int yTop = yOff - peakHeight;
         int ellipseOrient = ELLIPSE_BOTTOM;
         if (drawUp)
             {
             ellipseOrient = ELLIPSE_TOP;
             yLeft = yOff + tg->height - peakHeight;
             yTop = yOff + tg->height + peakHeight;
             }
         hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ellipseOrient,
                                 isReversed && doDashes);
         // draw grab box and map box on peak
         int maxY = peakHeight + yOff;
         int peakX = ((upperX - lowerX + 1) / 2) + lowerX;
         drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf,
-                            peakX, maxY, peakColor, highlightColor, drawUp);
+                            peakX, maxY, peakColor, highlightColor, drawUp, draw);
         }
     }
 }
 
 void interactLinkedFeaturesDrawAt(struct track *tg, void *item,
                           struct hvGfx *hvg, int xOff, int y, double scale,
                           MgFont *font, Color color, enum trackVisibility vis)
 /* Draw an item with target in contrasting color */
 {
 struct linkedFeatures *lf = item;
 if (vis == tvDense)
     {
     lf->filterColor = slightlyDarkerColor(hvg, MG_GRAY);
                 // can't distinguish overlapping colors, so force to gray
     }