74b175e14ae6469cdd645a969d170a46fe445d3e
tdreszer
  Wed Nov 2 15:38:13 2011 -0700
Checking in support for matrix squueze, but curently ifdef'd out
diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index b0f2ce6..3223c53 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -68,31 +68,31 @@
         struct hash *trackHash)
 // Returns an HTML string for a downloads link
 {
 // If has fileSortOrder, then link to new hgFileUi
 if (!nameIsFile && trackDbSetting(tdb, FILE_SORT_ORDER) != NULL)
     {
     char * link = needMem(PATH_LEN); // 512 should be enough
     safef(link,PATH_LEN,"<A HREF='%s?db=%s&g=%s' title='Downloadable Files...'>%s</A>", //  NOTE: TARGET=ucscDownloads   ??
         hgFileUiName(), database, /*cartSessionVarName(), cartSessionId(cart),*/ tdb->track, name); // Note the hgsid would be needed if downloads page ever saved fileSortOrder to cart.
     return link;
     }
 else if(trackDbSetting(tdb, "wgEncode") != NULL)  // Downloads directory if this is ENCODE
     {
     struct trackDb *dirKeeper = wgEncodeDownloadDirKeeper(database, tdb, trackHash);
     char *compositeDir = (sameWord(dirKeeper->type,"downloadsOnly")?dirKeeper->track:dirKeeper->table);
-    struct dyString *dyLink = dyStringCreate("<A HREF=\"http://%s/goldenPath/%s/%s/%s/%s\" title='Download %s' TARGET=ucscDownloads>%s</A>",
+    struct dyString *dyLink = dyStringCreate("<A HREF=\"http://%s/goldenPath/%s/%s/%s/%s\" title='Download %s' class='file' TARGET=ucscDownloads>%s</A>",
             hDownloadsServer(),
             trackDbSettingOrDefault(dirKeeper, "origAssembly",database),  // This may not be wise!!!
             ENCODE_DCC_DOWNLOADS, compositeDir, (nameIsFile?name:""), nameIsFile?"file":"files",name);
     return dyStringCannibalize(&dyLink);
     }
 return NULL;
 }
 
 static boolean makeNamedDownloadsLink(char *database, struct trackDb *tdb,char *name,
 	struct hash *trackHash)
 // Make a downloads link (if appropriate and then returns TRUE)
 {
 char *htmlString = htmlStringForDownloadsLink(database,trackDbTopLevelSelfOrParent(tdb),name,FALSE,trackHash);
 if (htmlString == NULL)
     return FALSE;
@@ -132,32 +132,32 @@
     if (isNotEmpty(tbOff) && sameString(nextWord(&tbOff), "off"))
 	return FALSE;
     char *hint = " title='Open table schema in new window'";
     if( label == NULL)
         label = " View table schema";
     struct trackDb *topLevel = trackDbTopLevelSelfOrParent(tdb);
     printf(SCHEMA_LINKED, db, topLevel->grp, topLevel->track, tdb->table, hint, label);
     return TRUE;
     }
 return FALSE;
 }
 
 char *controlledVocabLink(char *file,char *term,char *value,char *title, char *label,char *suffix)
 // returns allocated string of HTML link to controlled vocabulary term
 {
-#define VOCAB_LINK_WITH_FILE "<A HREF='hgEncodeVocab?ra=%s&%s=\"%s\"' title='%s details' TARGET=ucscVocab>%s</A>"
-#define VOCAB_LINK "<A HREF='hgEncodeVocab?%s=\"%s\"' title='%s details' TARGET=ucscVocab>%s</A>"
+#define VOCAB_LINK_WITH_FILE "<A HREF='hgEncodeVocab?ra=%s&%s=\"%s\"' title='%s details' class='cv' TARGET=ucscVocab>%s</A>"
+#define VOCAB_LINK "<A HREF='hgEncodeVocab?%s=\"%s\"' title='%s details' class='cv' TARGET=ucscVocab>%s</A>"
 struct dyString *dyLink = NULL;
 char *encTerm = cgiEncode(term);
 char *encValue = cgiEncode(value);
 if (file != NULL)
     {
     char *encFile = cgiEncode(file);
     dyLink = dyStringCreate(VOCAB_LINK_WITH_FILE,encFile,encTerm,encValue,title,label);
     freeMem(encFile);
     }
 else
     dyLink = dyStringCreate(VOCAB_LINK,encTerm,encValue,title,label);
 if (suffix != NULL)
     dyStringAppend(dyLink,suffix);  // Don't encode since this may contain HTML
 
 freeMem(encTerm);
@@ -6106,166 +6106,254 @@
     }
 freeMem(words[0]);
 freeMem(rootLabel);
 return cloneString(label);
 }
 
 #define PM_BUTTON_UC "<IMG height=18 width=18 onclick=\"return (matSetMatrixCheckBoxes(%s%s%s%s%s%s) == false);\" id='btn_%s' src='../images/%s'>"
 #define MATRIX_RIGHT_BUTTONS_AFTER 8
 #define MATRIX_BOTTOM_BUTTONS_AFTER 20
 
 static void buttonsForAll()
 {
 printf(PM_BUTTON_UC,"true", "", "", "", "", "",  "plus_all",    "add_sm.gif");
 printf(PM_BUTTON_UC,"false","", "", "", "", "", "minus_all", "remove_sm.gif");
 }
-static void buttonsForOne(char *name,char *class)
+static void buttonsForOne(char *name,char *class,boolean vertical)
 {
 printf(PM_BUTTON_UC, "true",  ",'", class, "'", "", "", name,    "add_sm.gif");
+if (vertical)
+    puts("<BR>");
 printf(PM_BUTTON_UC, "false", ",'", class, "'", "", "", name, "remove_sm.gif");
 }
 
-static void matrixXheadingsRow1(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,boolean top)
+//#define MATRIX_SQUEEZE 10
+#ifdef MATRIX_SQUEEZE
+static int matrixSqueeze(membersForAll_t* membersForAll)
+// Returns non-zero if the matrix will be squeezed.  Non-zero is actually squeezedLabelHeight
+{
+boolean labelHeight = 0;
+members_t *dimensionX = membersForAll->members[dimX];
+members_t *dimensionY = membersForAll->members[dimY];
+if(dimensionX && dimensionY)
+    {
+    if(dimensionX->count>MATRIX_SQUEEZE)
+        {
+        int ixX,cntX=0;
+        for (ixX = 0; ixX < dimensionX->count; ixX++)
+            {
+            if(dimensionX->subtrackList && dimensionX->subtrackList[ixX] && dimensionX->subtrackList[ixX]->val)
+                {
+                cntX++;
+                char *ptr = dimensionX->titles[ixX];
+                int ttlLen = strlen(ptr);
+                while((ptr = strstr(ptr+1,"&nbsp;")) != NULL)  // &nbsp; ????
+                    ttlLen -= 5;
+                if (labelHeight < ttlLen)
+                    labelHeight = ttlLen;
+                }
+            }
+        if(cntX>MATRIX_SQUEEZE)
+            labelHeight = (labelHeight * 8) + 5;//0.50;
+        else
+            labelHeight = 0;
+        }
+    }
+return labelHeight;
+}
+#else///ifndef MATRIX_SQUEEZE
+#define matrixSqueeze(membersForAll) 0
+#endif///ndef MATRIX_SQUEEZE
+
+static void matrixXheadingsRow1(char *db,struct trackDb *parentTdb,int squeeze, membersForAll_t* membersForAll,boolean top)
 /* prints the top row of a matrix: 'All' buttons; X titles; buttons 'All' */
 {
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 
 printf("<TR ALIGN=CENTER BGCOLOR='%s' valign=%s>\n",COLOR_BG_ALTDEFAULT,top?"BOTTOM":"TOP");
 if(dimensionX && dimensionY)
     {
     printf("<TH ALIGN=LEFT valign=%s>",top?"TOP":"BOTTOM");
     buttonsForAll();
     puts("&nbsp;All</TH>");
     }
 
 // If there is an X dimension, then titles go across the top
 if(dimensionX)
     {
     int ixX,cntX=0;
     if(dimensionY)
+        {
+        #ifdef MATRIX_SQUEEZE
+        if(squeeze>0)
+            printf("<TH align=RIGHT style='height:%dpx;'><div class='%s'><B><EM>%s</EM></B></div></TH>",
+                   squeeze, (top?"up45":"dn45"), dimensionX->groupTitle);
+        else
+        #endif///def MATRIX_SQUEEZE
         printf("<TH align=RIGHT><B><EM>%s</EM></B></TH>", dimensionX->groupTitle);
+        }
     else
         printf("<TH ALIGN=RIGHT valign=%s>&nbsp;&nbsp;<B><EM>%s</EM></B></TH>",(top?"TOP":"BOTTOM"), dimensionX->groupTitle);
 
     for (ixX = 0; ixX < dimensionX->count; ixX++)
         {
         if(dimensionX->subtrackList && dimensionX->subtrackList[ixX] && dimensionX->subtrackList[ixX]->val)
             {
+        #ifdef MATRIX_SQUEEZE
+            if(dimensionY && squeeze>0)
+                printf("<TH nowrap='' class='%s'><div class='%s'>%s</div></TH>",dimensionX->tags[ixX],(top?"up45":"dn45"),
+                       compositeLabelWithVocabLink(db,parentTdb,dimensionX->subtrackList[ixX]->val,dimensionX->groupTag,dimensionX->titles[ixX]));
+            else
+        #endif///def MATRIX_SQUEEZE
+                {
             char *label =replaceChars(dimensionX->titles[ixX]," (","<BR>(");
-            printf("<TH WIDTH='60'>&nbsp;%s&nbsp;</TH>",compositeLabelWithVocabLink(db,parentTdb,dimensionX->subtrackList[ixX]->val,dimensionX->groupTag,label));
+        #ifdef MATRIX_SQUEEZE
+                printf("<TH WIDTH='60' class='%s'>&nbsp;%s&nbsp;</TH>",dimensionX->tags[ixX],
+        #else///ifndef MATRIX_SQUEEZE
+                printf("<TH WIDTH='60'>&nbsp;%s&nbsp;</TH>",
+        #endif///ndef MATRIX_SQUEEZE
+                       compositeLabelWithVocabLink(db,parentTdb,dimensionX->subtrackList[ixX]->val,dimensionX->groupTag,label));
             freeMem(label);
+                }
             cntX++;
             }
         }
     // If dimension is big enough, then add Y buttons to right as well
     if(cntX>MATRIX_RIGHT_BUTTONS_AFTER)
         {
         if(dimensionY)
             {
+            #ifdef MATRIX_SQUEEZE
+            if(squeeze>0)
+                printf("<TH align=LEFT><div class='%s'><B><EM>%s</EM></B></div></TH>",
+                    (top?"up45":"dn45"), dimensionX->groupTitle);
+            else
+            #endif///def MATRIX_SQUEEZE
             printf("<TH align=LEFT><B><EM>%s</EM></B></TH>", dimensionX->groupTitle);
             printf("<TH ALIGN=RIGHT valign=%s>All&nbsp;",top?"TOP":"BOTTOM");
             buttonsForAll();
             puts("</TH>");
             }
         else
             printf("<TH ALIGN=LEFT valign=%s><B><EM>%s</EM></B>&nbsp;&nbsp;</TH>",top?"TOP":"BOTTOM", dimensionX->groupTitle);
         }
     }
 else if(dimensionY)
     {
     printf("<TH ALIGN=RIGHT WIDTH=100 nowrap>");
     printf("<B><EM>%s</EM></B>", dimensionY->groupTitle);
     printf("</TH><TH ALIGN=CENTER WIDTH=60>");
     buttonsForAll();
     puts("</TH>");
     }
 puts("</TR>\n");
 }
 
-static void matrixXheadingsRow2(struct trackDb *parentTdb, membersForAll_t* membersForAll)
+static void matrixXheadingsRow2(struct trackDb *parentTdb, int squeeze, membersForAll_t* membersForAll)
 /* prints the 2nd row of a matrix: Y title; X buttons; title Y */
 {
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 
 // If there are both X and Y dimensions, then there is a row of buttons in X
 if(dimensionX && dimensionY)
     {
     int ixX,cntX=0;
     printf("<TR ALIGN=CENTER BGCOLOR=\"%s\"><TH ALIGN=CENTER colspan=2><B><EM>%s</EM></B></TH>",COLOR_BG_ALTDEFAULT, dimensionY->groupTitle);
     for (ixX = 0; ixX < dimensionX->count; ixX++)    // Special row of +- +- +-
         {
         if(dimensionX->subtrackList && dimensionX->subtrackList[ixX] && dimensionX->subtrackList[ixX]->val)
             {
             char objName[SMALLBUF];
+            #ifdef MATRIX_SQUEEZE
+            puts("<TD nowrap>");
+            #else///ifndef MATRIX_SQUEEZE
             puts("<TD>");
+            #endif///ndef MATRIX_SQUEEZE
             safef(objName, sizeof(objName), "plus_%s_all", dimensionX->tags[ixX]);
-            buttonsForOne( objName, dimensionX->tags[ixX] );
+            boolean vertical = FALSE;
+            #ifdef MATRIX_SQUEEZE
+            vertical = (squeeze>0);
+            #endif///def MATRIX_SQUEEZE
+            buttonsForOne( objName, dimensionX->tags[ixX], vertical );
             puts("</TD>");
             cntX++;
             }
         }
     // If dimension is big enough, then add Y buttons to right as well
     if(cntX>MATRIX_RIGHT_BUTTONS_AFTER)
         printf("<TH ALIGN=CENTER colspan=2><B><EM>%s</EM></B></TH>", dimensionY->groupTitle);
     puts("</TR>\n");
     }
 }
 
-static void matrixXheadings(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,boolean top)
+static int matrixXheadings(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,boolean top)
 /* UI for X headings in matrix */
 {
+int squeeze = matrixSqueeze(membersForAll);
+
 if(top)
-    matrixXheadingsRow1(db,parentTdb,membersForAll,top);
+    matrixXheadingsRow1(db,parentTdb,squeeze,membersForAll,top);
 
-    matrixXheadingsRow2(parentTdb,membersForAll);
+    matrixXheadingsRow2(parentTdb,squeeze,membersForAll);
 
 if(!top)
-    matrixXheadingsRow1(db,parentTdb,membersForAll,top);
+    matrixXheadingsRow1(db,parentTdb,squeeze,membersForAll,top);
+
+return squeeze;
 }
 
 static void matrixYheadings(char *db,struct trackDb *parentTdb, membersForAll_t* membersForAll,int ixY,boolean left)
 /* prints the column of Y labels and buttons */
 {
 members_t *dimensionX = membersForAll->members[dimX];
 members_t *dimensionY = membersForAll->members[dimY];
 
 struct trackDb *childTdb = NULL;
 if(dimensionY && dimensionY->subtrackList && dimensionY->subtrackList[ixY] && dimensionY->subtrackList[ixY]->val)
     childTdb = dimensionY->subtrackList[ixY]->val;
 
 if(dimensionX && dimensionY && childTdb != NULL) // Both X and Y, then column of buttons
     {
     char objName[SMALLBUF];
+    #ifdef MATRIX_SQUEEZE
+    printf("<TH class='%s' ALIGN=%s nowrap colspan=2>",dimensionY->tags[ixY],left?"RIGHT":"LEFT");
+    #else///ifndef MATRIX_SQUEEZE
     printf("<TH ALIGN=%s nowrap colspan=2>",left?"RIGHT":"LEFT");
+    #endif///ndef MATRIX_SQUEEZE
     if(left)
         printf("%s&nbsp;",compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,dimensionY->titles[ixY]));
     safef(objName, sizeof(objName), "plus_all_%s", dimensionY->tags[ixY]);
-    buttonsForOne( objName, dimensionY->tags[ixY] );
+    buttonsForOne( objName, dimensionY->tags[ixY], FALSE );
     if(!left)
         printf("&nbsp;%s",compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,dimensionY->titles[ixY]));
     puts("</TH>");
     }
 else if (dimensionX)
     {
     printf("<TH ALIGN=%s>",left?"RIGHT":"LEFT");
     buttonsForAll();
     puts("</TH>");
     }
 else if (left && dimensionY && childTdb != NULL)
+    #ifdef MATRIX_SQUEEZE
+    printf("<TH class='%s' ALIGN=RIGHT nowrap>%s</TH>\n",dimensionY->tags[ixY],
+           compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,dimensionY->titles[ixY]));
+    #else///ifndef MATRIX_SQUEEZE
     printf("<TH ALIGN=RIGHT nowrap>%s</TH>\n",compositeLabelWithVocabLink(db,parentTdb,childTdb,dimensionY->groupTag,dimensionY->titles[ixY]));
+    #endif///ndef MATRIX_SQUEEZE
 }
 
 static int displayABCdimensions(char *db,struct cart *cart, struct trackDb *parentTdb, struct slRef *subtrackRefList, membersForAll_t* membersForAll)
 /* This will walk through all declared nonX&Y dimensions (X and Y is the 2D matrix of CBs.
    NOTE: ABC dims are only supported if there are X & Y both.  Also expected number should be passed in */
 {
 int count=0,ix;
 for(ix=dimA;ix<membersForAll->dimMax;ix++)
     {
     if(membersForAll->members[ix]==NULL)
         continue;
     if(membersForAll->members[ix]->count<1)
         continue;
     count++;
 
@@ -6543,43 +6631,48 @@
 puts(strLower(javascript));
 
 if(!subgroupingExists(parentTdb,"view"))
     puts("(<A HREF=\"../goldenPath/help/multiView.html\" title='Help on subtrack selection' TARGET=_BLANK>help</A>)\n");
 
 puts("<BR>\n");
 
 if(membersForAll->abcCount > 0 && membersForAll->filters == FALSE)
     {
     displayABCdimensions(db,cart,parentTdb,subtrackRefList,membersForAll);
     }
 
 if(dimensionX == NULL && dimensionY == NULL) // Could have been just filterComposite. Must be an X or Y dimension
     return FALSE;
 
+#ifdef MATRIX_SQUEEZE
+printf("<TABLE class='greenBox' cellspacing=0 style='background-color:%s;'>\n",COLOR_BG_ALTDEFAULT);
+#else///ifndef MATRIX_SQUEEZE
 printf("<TABLE class='greenBox' style='background-color:%s;'>\n",COLOR_BG_DEFAULT);
+#endif///ndef MATRIX_SQUEEZE
 
-matrixXheadings(db,parentTdb,membersForAll,TRUE);
+//int squeeze = matrixXheadings(db,parentTdb,membersForAll,TRUE); // right side labels could be dependent upon squeeze
+(void)matrixXheadings(db,parentTdb,membersForAll,TRUE);
 
 // Now the Y by X matrix
 int cntX=0,cntY=0;
 for (ixY = 0; ixY < sizeOfY; ixY++)
     {
     if(dimensionY == NULL || (dimensionY->tags[ixY]))
         {
         cntY++;
         assert(!dimensionY || ixY < dimensionY->count);
-        printf("<TR ALIGN=CENTER BGCOLOR=\"#FFF9D2\">");
+        printf("<TR ALIGN=CENTER BGCOLOR='%s'>",COLOR_BG_ALTDEFAULT);
 
         matrixYheadings(db,parentTdb, membersForAll,ixY,TRUE);
 
 #define MAT_CB_SETUP "<INPUT TYPE=CHECKBOX NAME='%s' VALUE=on %s>"
 #define MAT_CB(name,js) printf(MAT_CB_SETUP,(name),(js));
         for (ixX = 0; ixX < sizeOfX; ixX++)
             {
             if(dimensionX == NULL || (dimensionX->tags[ixX]))
                 {
                 assert(!dimensionX || ixX < dimensionX->count);
 
                 if(cntY==1) // Only do this on the first good Y
                     cntX++;
 
                 if(dimensionX && ixX == dimensionX->count)
@@ -6600,58 +6693,72 @@
                     }
                 if(cells[ixX][ixY] > 0)
                     {
                     boolean halfChecked = (chked[ixX][ixY] > 0 && chked[ixX][ixY] < enabd[ixX][ixY]);
 
                     struct dyString *dyJS = dyStringCreate("onclick='matCbClick(this);'");
                     if(dimensionX && dimensionY)
                         {
                         safef(objName, sizeof(objName), "mat_%s_%s_cb", dimensionX->tags[ixX],dimensionY->tags[ixY]);
                         }
                     else
                         {
                         safef(objName, sizeof(objName), "mat_%s_cb", (dimensionX ? dimensionX->tags[ixX] : dimensionY->tags[ixY]));
                         }
                     //printf("<TD title='subCBs:%d  checked:%d enabled:%d'>\n",cells[ixX][ixY],chked[ixX][ixY],enabd[ixX][ixY]);
+                #ifdef MATRIX_SQUEEZE
+                    if(ttlX && ttlY)
+                        printf("<TD class='matCell %s %s'>\n",dimensionX->tags[ixX],dimensionY->tags[ixY]);
+                    else
+                        printf("<TD class='matCell %s'>\n", (dimensionX ? dimensionX->tags[ixX] : dimensionY->tags[ixY]));
+                #else///ifndef MATRIX_SQUEEZE
                     if(ttlX && ttlY)
                         printf("<TD title='%s and %s'>\n",ttlX,ttlY);
                     else
                         printf("<TD title='%s'>\n",(ttlX ? ttlX : ttlY));
+                #endif///ndef MATRIX_SQUEEZE
                     dyStringPrintf(dyJS, " class=\"matCB");
                     if(halfChecked)
                         dyStringPrintf(dyJS, " halfVis");  // needed for later js identification!
                     if(dimensionX)
                         dyStringPrintf(dyJS, " %s",dimensionX->tags[ixX]);
                     if(dimensionY)
                         dyStringPrintf(dyJS, " %s",dimensionY->tags[ixY]);
                     dyStringAppendC(dyJS,'"');
                     if(chked[ixX][ixY] > 0)
                         dyStringAppend(dyJS," CHECKED");
                     if(halfChecked)
                         {
                         //dyStringAppend(dyJS," style='filter:alpha(opacity=50)'"); // Doesn't get set overkill with class=halfVis but IE doesn't cooperate!
                         dyStringAppend(dyJS," title='Not all associated subtracks have been selected'"); // overkill with class=halfVis but IE doesn't cooperate!
                         }
                     MAT_CB(objName,dyStringCannibalize(&dyJS)); // X&Y are set by javascript page load
                     puts("</TD>");
                     }
                 else
                     {
+                #ifdef MATRIX_SQUEEZE
+                    if(ttlX && ttlY)
+                        printf("<TD class='matCell %s %s'></TD>\n",dimensionX->tags[ixX],dimensionY->tags[ixY]);
+                    else
+                        printf("<TD class='matCell %s'></TD>\n", (dimensionX ? dimensionX->tags[ixX] : dimensionY->tags[ixY]));
+                #else///ifndef MATRIX_SQUEEZE
                     if(ttlX && ttlY)
                         printf("<TD title='%s and %s'></TD>\n",ttlX,ttlY);
                     else
                         printf("<TD title='%s'></TD>\n",(ttlX ? ttlX : ttlY));
+                #endif///ndef MATRIX_SQUEEZE
                     //puts("<TD>&nbsp;</TD>");
                     }
                 }
             }
         if(dimensionX && cntX>MATRIX_RIGHT_BUTTONS_AFTER)
             matrixYheadings(db,parentTdb, membersForAll,ixY,FALSE);
         puts("</TR>\n");
         }
     }
 if(dimensionY && cntY>MATRIX_BOTTOM_BUTTONS_AFTER)
     matrixXheadings(db,parentTdb,membersForAll,FALSE);
 
 puts("</TD></TR></TABLE>");
 
 // If any filter additional filter composites, they can be added at the end.