src/hg/lib/hui.c 1.212

1.212 2009/06/12 21:05:51 tdreszer
Huge Yale matrix requires right buttons and bottom buttons
Index: src/hg/lib/hui.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/lib/hui.c,v
retrieving revision 1.211
retrieving revision 1.212
diff -b -B -U 4 -r1.211 -r1.212
--- src/hg/lib/hui.c	12 Jun 2009 15:52:22 -0000	1.211
+++ src/hg/lib/hui.c	12 Jun 2009 21:05:51 -0000	1.212
@@ -4628,9 +4628,9 @@
 if((count = chopByWhite(cloneString(vocab), words,15)) <= 1)
     return cloneString(label);
 for(ix=1;ix<count && !found;ix++)
     {
-#define VOCAB_LINK "<A HREF='hgEncodeVocab?ra=/usr/local/apache/cgi-bin/%s&term=\"%s\"' title='%s details' TARGET=ucscVocab>%s</A>\n"
+#define VOCAB_LINK "<A HREF='hgEncodeVocab?ra=/usr/local/apache/cgi-bin/%s&term=\"%s\"' title='%s details' TARGET=ucscVocab>%s</A>"
     if(sameString(vocabType,words[ix])) // controlledVocabulary setting matches tag so all labels are linked
         {
         int sz=strlen(VOCAB_LINK)+strlen(words[0])+strlen(words[ix])+2*strlen(label) + 2;
         char *link=needMem(sz);
@@ -4660,8 +4660,139 @@
 freeMem(words[0]);
 return cloneString(label);
 }
 
+#define PM_BUTTON_UC "<A NAME='%s'></A><A HREF='#%s'><IMG height=18 width=18 onclick=\"return (matSetMatrixCheckBoxes(%s%s%s%s%s%s) == false);\" id='btn_%s' src='../images/%s'></A>"
+static void buttonsForAll()
+{
+printf(PM_BUTTON_UC, "plus_all", "plus_all", "true",  "", "", "", "", "",  "plus_all",    "add_sm.gif");
+printf(PM_BUTTON_UC,"minus_all","minus_all","false",  "", "", "", "", "", "minus_all", "remove_sm.gif");
+}
+static void buttonsForOne(char *name,char *class)
+{
+printf(PM_BUTTON_UC, name, name,  "true", ",'", class, "'", "", "", name,    "add_sm.gif");
+printf(PM_BUTTON_UC, name, name, "false", ",'", class, "'", "", "", name, "remove_sm.gif");
+}
+
+#define MATRIX_RIGHT_BUTTONS_AFTER 8
+#define MATRIX_BOTTOM_BUTTONS_AFTER 20
+static void matrixXheadingsRow1(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
+/* prints the top row of a matrix: 'All' buttons; X titles; buttons 'All' */
+{
+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;
+    if(dimensionY)
+        printf("<TH align=RIGHT><EM><B>%s</EM></B>:</TH>", dimensionX->title);
+    else
+        printf("<TH ALIGN=RIGHT valign=%s>&nbsp;&nbsp;<EM><B>%s</EM></B></TH>",top?"TOP":"BOTTOM", dimensionX->title);
+    for (ixX = 0; ixX < dimensionX->count; ixX++)
+        {
+        if(tdbsX[ixX] != NULL || dimensionX == NULL)
+            {
+            char *label = replaceChars(dimensionX->values[ixX]," (","<BR>(");//
+            printf("<TH WIDTH='60'>&nbsp;%s&nbsp;</TH>",labelWithVocabLink(parentTdb,tdbsX[ixX],dimensionX->tag,label));
+            freeMem(label);
+            }
+        }
+    // If dimension is big enough, then add Y buttons to righ as well
+    if(dimensionX->count>MATRIX_RIGHT_BUTTONS_AFTER)
+        {
+        if(dimensionY)
+            {
+            printf("<TH align=LEFT>:<EM><B>%s</EM></B></TH>", dimensionX->title);
+            printf("<TH ALIGN=RIGHT valign=%s>All&nbsp;",top?"TOP":"BOTTOM");
+            buttonsForAll();
+            puts("</TH>");
+            }
+        else
+            printf("<TH ALIGN=LEFT valign=%s><EM><B>%s</EM></B>&nbsp;&nbsp;</TH>",top?"TOP":"BOTTOM", dimensionX->title);
+        }
+    }
+else if(dimensionY)
+    {
+    printf("<TH ALIGN=RIGHT WIDTH=100 nowrap>");
+    printf("<EM><B>%s</EM></B>", dimensionY->title);
+    printf("</TH><TH ALIGN=CENTER WIDTH=60>");
+    buttonsForAll();
+    puts("</TH>");
+    }
+puts("</TR>\n");
+}
+
+static void matrixXheadingsRow2(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX)
+/* prints the 2nd row of a matrix: Y title; X buttons; title Y */
+{
+// If there are both X and Y dimensions, then there is a row of buttons in X
+if(dimensionX && dimensionY)
+    {
+    int ixX;
+    printf("<TR ALIGN=CENTER BGCOLOR=\"%s\"><TH ALIGN=CENTER colspan=2><EM><B>%s</EM></B></TH>",COLOR_BG_ALTDEFAULT, dimensionY->title);
+    for (ixX = 0; ixX < dimensionX->count; ixX++)    // Special row of +- +- +-
+        {
+        if(tdbsX[ixX] != NULL || dimensionX == NULL)
+            {
+            char objName[SMALLBUF];
+            puts("<TD>");
+            safef(objName, sizeof(objName), "plus_%s_all", dimensionX->names[ixX]);
+            buttonsForOne( objName, dimensionX->names[ixX] );
+            puts("</TD>");
+            }
+        }
+    // If dimension is big enough, then add Y buttons to righ as well
+    if(dimensionX->count>MATRIX_RIGHT_BUTTONS_AFTER)
+        printf("<TH ALIGN=CENTER colspan=2><EM><B>%s</EM></B></TH>", dimensionY->title);
+    puts("</TR>\n");
+    }
+}
+
+static void matrixXheadings(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
+/* UI for X headings in matrix */
+{
+if(top)
+    matrixXheadingsRow1(parentTdb,dimensionX,dimensionY,tdbsX,top);
+
+    matrixXheadingsRow2(parentTdb,dimensionX,dimensionY,tdbsX);
+
+if(!top)
+    matrixXheadingsRow1(parentTdb,dimensionX,dimensionY,tdbsX,top);
+}
+
+static void matrixYheadings(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,int ixY,struct trackDb *childTdb,boolean left)
+/* prints the top row of a matrix: 'All' buttons; X titles; buttons 'All' */
+{
+if(dimensionX && dimensionY && childTdb != NULL) // Both X and Y, then column of buttons
+    {
+    char objName[SMALLBUF];
+    printf("<TH ALIGN=%s nowrap colspan=2>",left?"RIGHT":"LEFT");
+    if(left)
+        printf("%s&nbsp;",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+    safef(objName, sizeof(objName), "plus_all_%s", dimensionY->names[ixY]);
+    buttonsForOne( objName, dimensionY->names[ixY] );
+    if(!left)
+        printf("&nbsp;%s",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+    puts("</TH>");
+    }
+else if (dimensionX)
+    {
+    printf("<TH ALIGN=%s>",left?"RIGHT":"LEFT");
+    buttonsForAll();
+    puts("</TH>");
+    }
+else if (left && dimensionY && childTdb != NULL)
+    printf("<TH ALIGN=RIGHT nowrap>%s</TH>\n",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+}
+
+
 static boolean hCompositeUiByMatrix(char *db, struct cart *cart, struct trackDb *parentTdb, char *formName)
 /* UI for composite tracks: matrix of checkboxes. */
 {
 //int ix;
@@ -4723,112 +4854,34 @@
     if(ixZ > -1)
         cellsZ[ixZ]++;
     }
 
-    // Regardless of whether there is a dimension X or Y, there will be 'all' buttons
-    //puts("<B>Select subtracks by characterization:</B><BR>");
-    printf("<B>Select subtracks by ");
-    if(dimensionX && !dimensionY)
+//puts("<B>Select subtracks by characterization:</B><BR>");
+printf("<B>Select subtracks by ");
+if(dimensionX && !dimensionY)
         safef(javascript, sizeof(javascript), "%s:</B><BR>",dimensionX->title);
-    else if(!dimensionX && dimensionY)
+else if(!dimensionX && dimensionY)
         safef(javascript, sizeof(javascript), "%s:</B><BR>",dimensionY->title);
-    else if(dimensionX && dimensionY && !dimensionZ)
+else if(dimensionX && dimensionY && !dimensionZ)
         safef(javascript, sizeof(javascript), "%s and %s:</B><BR>",dimensionX->title,dimensionY->title);
-    else //if(dimensionX && dimensionY && dimensionZ)
+else //if(dimensionX && dimensionY && dimensionZ)
         safef(javascript, sizeof(javascript), "%s, %s and %s:</B><BR>",dimensionX->title,dimensionY->title,dimensionZ->title);
-    puts(strLower(javascript));
-
-    printf("<TABLE class='greenBox' bgcolor='%s' borderColor='%s'}>\n",COLOR_BG_DEFAULT,COLOR_BG_DEFAULT);
+puts(strLower(javascript));
 
-    printf("<TR ALIGN=CENTER BGCOLOR='%s'>\n",COLOR_BG_ALTDEFAULT);
-    if(dimensionX && dimensionY)
-        {
-        printf("<TH ALIGN=LEFT WIDTH='100'>All&nbsp;&nbsp;");
-#define PM_BUTTON_UC "<A NAME='%s'></A><A HREF='#%s'><IMG height=18 width=18 onclick=\"return (matSetMatrixCheckBoxes(%s%s%s%s%s%s) == false);\" id='btn_%s' src='../images/%s'></A>"
-#define    BUTTON_PLUS_ALL()                   printf(PM_BUTTON_UC, "plus_all", "plus_all", "true",  "",     "",   "",      "", "", "plus_all",   "add_sm.gif")
-#define    BUTTON_MINUS_ALL()                  printf(PM_BUTTON_UC,"minus_all","minus_all","false",  "",     "",   "",      "", "","minus_all","remove_sm.gif")
-#define    BUTTON_PLUS_ONE( name,class)        printf(PM_BUTTON_UC,     (name),     (name), "true",",'",(class),  "'",      "", "",     (name),   "add_sm.gif")
-#define    BUTTON_MINUS_ONE(name,class)        printf(PM_BUTTON_UC,     (name),     (name),"false",",'",(class),  "'",      "", "",     (name),"remove_sm.gif")
-//#define    BUTTON_PLUS_TWO( name,class,class2) printf(PM_BUTTON_UC,     (name),     (name), "true",",'",(class),"','",(class2),"'",     (name),   "add_sm.gif")
-//#define    BUTTON_MINUS_TWO(name,class,class2) printf(PM_BUTTON_UC,     (name),     (name),"false",",'",(class),"','",(class2),"'",     (name),"remove_sm.gif")
-        BUTTON_PLUS_ALL();
-        BUTTON_MINUS_ALL();
-        puts("</TH>");
-        }
-    else if(dimensionX)
-        printf("<TH WIDTH=\"100\"><EM><B>%s</EM></B></TH>", dimensionX->title);
-    else if(dimensionY)
-        printf("<TH ALIGN=RIGHT WIDTH=\"100\"><EM><B>%s</EM></B></TH>", dimensionY->title);
-
-    // If there is an X dimension, then titles go across the top
-    if(dimensionX)
-        {
-        if(dimensionY)
-            printf("<TH align='right' WIDTH=\"100\"><EM><B>%s</EM></B>:</TH>", dimensionX->title);
-        for (ixX = 0; ixX < dimensionX->count; ixX++)
-            {
-            if(tdbsX[ixX] != NULL || dimensionX == NULL)
-                {
-                char *label = replaceChars(dimensionX->values[ixX]," (","<BR>(");//
-                printf("<TH WIDTH=\"100\">%s</TH>",labelWithVocabLink(parentTdb,tdbsX[ixX],dimensionX->tag,label));
-                freeMem(label);
-                }
-            }
-        }
-    else if(dimensionY)
-        {
-        printf("<TH ALIGN=CENTER WIDTH=\"100\">");
-        BUTTON_PLUS_ALL();
-        BUTTON_MINUS_ALL();
-        puts("</TH>");
-        }
-    puts("</TR>\n");
+printf("<TABLE class='greenBox' bgcolor='%s' borderColor='%s'}>\n",COLOR_BG_DEFAULT,COLOR_BG_DEFAULT);
 
-    // If there are both X and Y dimensions, then there is a row of buttons in X
-    if(dimensionX && dimensionY)
-        {
-        printf("<TR ALIGN=CENTER BGCOLOR=\"%s\"><TH ALIGN=RIGHT><EM><B>%s</EM></B></TH><TD>&nbsp;</TD>",COLOR_BG_ALTDEFAULT, dimensionY->title);
-        for (ixX = 0; ixX < dimensionX->count; ixX++)    // Special row of +- +- +-
-            {
-            if(tdbsX[ixX] != NULL || dimensionX == NULL)
-                {
-                puts("<TD>");
-                safef(objName, sizeof(objName), "plus_%s_all", dimensionX->names[ixX]);
-                BUTTON_PLUS_ONE( objName,dimensionX->names[ixX]);
-                BUTTON_MINUS_ONE(objName,dimensionX->names[ixX]);
-                puts("</TD>");
-                }
-            }
-        puts("</TR>\n");
-        }
+matrixXheadings(parentTdb,dimensionX,dimensionY,tdbsX,TRUE);
 
-    // Now the Y by X matrix
-    for (ixY = 0; ixY < sizeOfY; ixY++)
+// Now the Y by X matrix
+for (ixY = 0; ixY < sizeOfY; ixY++)
         {
         if(tdbsY[ixY] != NULL || dimensionY == NULL)
             {
             assert(!dimensionY || ixY < dimensionY->count);
             printf("<TR ALIGN=CENTER BGCOLOR=\"#FFF9D2\">");
-            if(dimensionY == NULL) // 'All' buttons go here if no Y dimension
-                {
-                printf("<TH ALIGN=CENTER WIDTH=\"100\">");
-                BUTTON_PLUS_ALL();
-                BUTTON_MINUS_ALL();
-                puts("</TH>");
-                }
-            else if(ixY < dimensionY->count)
-                printf("<TH ALIGN=RIGHT nowrap>%s</TH>\n",labelWithVocabLink(parentTdb,tdbsY[ixY],dimensionY->tag,dimensionY->values[ixY]));
-            else
-                break;
 
-            if(dimensionX && dimensionY) // Both X and Y, then column of buttons
-                {
-                puts("<TD>");
-                safef(objName, sizeof(objName), "plus_all_%s", dimensionY->names[ixY]);
-                BUTTON_PLUS_ONE( objName,dimensionY->names[ixY]);
-                BUTTON_MINUS_ONE(objName,dimensionY->names[ixY]);
-                puts("</TD>");
-                }
+        matrixYheadings(parentTdb, dimensionX,dimensionY,ixY,tdbsY[ixY],TRUE);
+
             for (ixX = 0; ixX < sizeOfX; ixX++)
                 {
                 if(tdbsX[ixX] != NULL || dimensionX == NULL)
                     {
@@ -4865,12 +4918,17 @@
                     else
                         puts("<TD>&nbsp;</TD>");
                     }
                 }
+        if(dimensionX && dimensionX->count>MATRIX_RIGHT_BUTTONS_AFTER)
+            matrixYheadings(parentTdb, dimensionX,dimensionY,ixY,tdbsY[ixY],FALSE);
             puts("</TR>\n");
             }
         }
-    if(dimensionZ)
+if(dimensionY && dimensionY->count>MATRIX_BOTTOM_BUTTONS_AFTER)
+    matrixXheadings(parentTdb,dimensionX,dimensionY,tdbsX,FALSE);
+
+if(dimensionZ)
         {
         printf("<TR align='center' valign='bottom' BGCOLOR='%s''>",COLOR_BG_ALTDEFAULT);
         printf("<TH class='greenRoof' STYLE='font-size: 2' colspan=50>&nbsp;</TH>");
         printf("<TR BGCOLOR='%s'><TH valign=top align=left colspan=2 rowspan=20><B><EM>%s</EM></B>:",
@@ -4897,15 +4955,16 @@
             }
         if((cntZ % sizeOfX) > 0)
             printf("<TH colspan=%d>&nbsp;</TH>",sizeOfX);
         }
-    puts("</TD></TR></TABLE>");
-    subgroupMembersFree(&dimensionX);
-    subgroupMembersFree(&dimensionY);
-    subgroupMembersFree(&dimensionZ);
-    puts("<BR>\n");
+puts("</TD></TR></TABLE>");
 
-    return TRUE;
+subgroupMembersFree(&dimensionX);
+subgroupMembersFree(&dimensionY);
+subgroupMembersFree(&dimensionZ);
+puts("<BR>\n");
+
+return TRUE;
 }
 
 static boolean hCompositeUiAllButtons(char *db, struct cart *cart, struct trackDb *parentTdb, char *formName)
 /* UI for composite tracks: all/none buttons only (as opposed to matrix or lots of buttons */