src/hg/hgTracks/imageV2.c 1.17
1.17 2009/12/09 03:30:22 tdreszer
Checkin for FLAT_TRACKS for dragReorder. Also several other features worked out or cleaned up
Index: src/hg/hgTracks/imageV2.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgTracks/imageV2.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -b -B -U 4 -r1.16 -r1.17
--- src/hg/hgTracks/imageV2.c 5 Dec 2009 01:29:01 -0000 1.16
+++ src/hg/hgTracks/imageV2.c 9 Dec 2009 03:30:22 -0000 1.17
@@ -5,8 +5,9 @@
#include "hdb.h"
#include "hui.h"
#include "jsHelper.h"
#include "imageV2.h"
+#include "hgTracks.h"
static char const rcsid[] = "$Id$";
struct imgBox *theImgBox = NULL; // Make this global for now to avoid huge rewrite
@@ -15,9 +16,62 @@
//struct imgSlice *curSlice = NULL; // Make this global for now to avoid huge rewrite
//struct mapSet *curMap = NULL; // Make this global for now to avoid huge rewrite
//struct mapItem *curMapItem = NULL; // Make this global for now to avoid huge rewrite
-//#define IMAGEv2_UI
+#ifdef FLAT_TRACK_LIST
+/////////////////////////
+// FLAT TRACKS
+// A simplistic way of flattening the track list before building the image
+// NOTE: Strategy is NOT to use imgBox->imgTracks, since this should be independednt of imageV2
+/////////////////////////
+void flatTracksAdd(struct flatTracks **flatTracks,struct track *track,struct cart *cart)
+// Adds one track into the flatTracks list
+{
+struct flatTracks *flatTrack;
+AllocVar(flatTrack);
+flatTrack->track = track;
+char var[128]; // The whole reason to do this is to reorder tracks/subtracks in the image!
+safef(var,sizeof(var),"%s_%s",track->tdb->tableName,IMG_ORDER_VAR);
+flatTrack->order = cartUsualInt(cart, var,IMG_ANYORDER);
+if(flatTrack->order >= IMG_ORDEREND)
+ {
+ cartRemove(cart,var);
+ flatTrack->order = IMG_ANYORDER;
+ }
+static int lastOrder = IMG_ORDEREND; // keep track of the order added and beyond end
+if( flatTrack->order == IMG_ANYORDER)
+ flatTrack->order = ++lastOrder;
+
+slAddHead(flatTracks,flatTrack);
+}
+
+int flatTracksCmp(const void *va, const void *vb)
+// Compare to sort on flatTrack->order
+{
+const struct flatTracks *a = *((struct flatTracks **)va);
+const struct flatTracks *b = *((struct flatTracks **)vb);
+return (a->order - b->order);
+}
+
+void flatTracksSort(struct flatTracks **flatTracks)
+// This routine sorts the imgTracks then forces tight ordering, so new tracks wil go to the end
+{
+if(flatTracks && *flatTracks)
+ slSort(flatTracks, flatTracksCmp);
+}
+
+void flatTracksFree(struct flatTracks **flatTracks)
+// Frees all memory used to support flatTracks (underlying tracks are untouched)
+{
+if(flatTracks && *flatTracks)
+ {
+ struct flatTracks *flatTrack;
+ while((flatTrack = slPopHead(flatTracks)) != NULL)
+ freeMem(flatTrack);
+ }
+}
+#endif//def FLAT_TRACK_LIST
+
#ifdef IMAGEv2_UI
/////////////////////////
// IMAGEv2
// The new way to do images: PLEASE REFER TO imageV2.h FOR A DETAILED DESCRIPTION
@@ -318,24 +372,50 @@
/* Translate enum slice type to string */
{
switch(type)
{
- case isData: return "data";
- case isSide: return "side";
- case isCenter: return "center";
- case isButton: return "button";
+ case stData: return "data";
+ case stSide: return "side";
+ case stCenter: return "center";
+ case stButton: return "button";
default: return "unknown";
}
}
+struct imgSlice *sliceAddLink(struct imgSlice *slice,char *link,char *title)
+/* Adds a slice wide link. The link and map are mutually exclusive */
+{
+if(slice->map != NULL)
+ {
+ warn("sliceAddLink() but slice already has its own map. Being replaced.");
+ mapSetFree(&(slice->map));
+ }
+if(slice->link != NULL)
+ {
+ warn("sliceAddLink() but slice already has a link. Being replaced.");
+ freeMem(slice->link);
+ }
+slice->link = cloneString(link);
+if(slice->title != NULL) // OK to replace title
+ freeMem(slice->title);
+slice->title = cloneString(title);
+return slice;
+}
+
struct mapSet *sliceMapStart(struct imgSlice *slice,char *name,char *linkRoot)
/* Adds a slice specific map to a slice of an image. Map items can then be added to the returned pointer with mapSetItemAdd()*/
{
if(slice->parentImg == NULL)
{
warn("sliceAddMap() but slice has no image.");
return NULL;
}
+if(slice->link != NULL)
+ {
+ warn("sliceAddMap() but slice already has a link. Being replaced.");
+ freeMem(slice->link);
+ slice->link = NULL;
+ }
if(slice->map != NULL && slice->map != slice->parentImg->map)
{
warn("sliceAddMap() but slice already has its own map. Being replaced.");
mapSetFree(&(slice->map));
@@ -383,15 +463,16 @@
if (verbose)
warn("slice is NULL");
return FALSE;
}
-if (slice->parentImg == NULL)
+if (slice->parentImg == NULL && slice->type != stButton)
{
if (verbose)
warn("slice(%s) has no image",sliceTypeToString(slice->type));
return FALSE;
}
-if (slice->width == 0 || slice->width > slice->parentImg->width)
+if ( slice->width == 0
+|| (slice->parentImg && slice->width > slice->parentImg->width))
{
if (verbose)
warn("slice(%s) has an invalid width %d (image width %d)",
sliceTypeToString(slice->type),slice->width,slice->parentImg->width);
@@ -404,24 +485,30 @@
// sliceTypeToString(slice->type),slice->height,slice->parentImg->height);
//return FALSE;
return TRUE; // This may be valid (but is sloppy) when there is no data for the slice.
}
-if (slice->height > slice->parentImg->height)
+if (slice->parentImg && slice->height > slice->parentImg->height)
{
if (verbose)
warn("slice(%s) has an invalid height %d (image height %d)",
sliceTypeToString(slice->type),slice->height,slice->parentImg->height);
return FALSE;
}
-if (slice->offsetX >= slice->parentImg->width
-|| slice->offsetY >= slice->parentImg->height)
+if ( slice->parentImg
+&& (slice->offsetX >= slice->parentImg->width
+|| slice->offsetY >= slice->parentImg->height))
{
if (verbose)
warn("slice(%s) has an invalid X:%d or Y:%d offset (image width:%d height:%d)",
sliceTypeToString(slice->type),slice->offsetX,slice->offsetY,
slice->parentImg->width,slice->parentImg->height);
return FALSE;
}
+if (slice->link != NULL && slice->map != NULL)
+ {
+ warn("slice(%s) has both link and map of links",sliceTypeToString(slice->type));
+ return FALSE;
+ }
if (slice->map != NULL)
{
if(!mapSetIsComplete(slice->map,verbose))
{
@@ -452,8 +539,9 @@
struct mapSet *map = sliceGetMap(slice,TRUE);// Only one that belongs to slice, not image
if(map != NULL)
mapSetFree(&map);
freeMem(slice->title);
+ freeMem(slice->link);
freeMem(slice);
*pSlice = NULL;
}
}
@@ -490,9 +578,9 @@
imgTrack->chromEnd = chromEnd;
imgTrack->plusStrand = plusStrand;
imgTrack->showCenterLabel = showCenterLabel;
imgTrack->vis = vis;
-static int lastOrder = 900; // keep track of the order these images get added
+static int lastOrder = IMG_ORDEREND; // keep track of the order these images get added
if(order == IMG_FIXEDPOS)
{
imgTrack->reorderable = FALSE;
if(name != NULL && sameString(RULER_TRACK_NAME,name))
@@ -518,25 +606,25 @@
return imgTrack;
}
int imgTrackOrderCmp(const void *va, const void *vb)
-/* Compare to sort on label. */
+/* Compare to sort on imgTrack->order */
{
const struct imgTrack *a = *((struct imgTrack **)va);
const struct imgTrack *b = *((struct imgTrack **)vb);
return (a->order - b->order);
}
struct imgSlice *imgTrackSliceAdd(struct imgTrack *imgTrack,enum sliceType type, struct image *img,char *title,int width,int height,int offsetX,int offsetY)
-/* Adds slices to an image track. Expected are types: isData, isButton, isSide and isCenter */
+/* Adds slices to an image track. Expected are types: stData, stButton, stSide and stCenter */
{
struct imgSlice *slice = sliceCreate(type,img,title,width,height,offsetX,offsetY);
slAddHead(&(imgTrack->slices),slice);
return imgTrack->slices;
}
struct imgSlice *imgTrackSliceGetByType(struct imgTrack *imgTrack,enum sliceType type)
-/* Gets a specific slice already added to an image track. Expected are types: isData, isButton, isSide and isCenter */
+/* Gets a specific slice already added to an image track. Expected are types: stData, stButton, stSide and stCenter */
{
struct imgSlice *slice;
for(slice = imgTrack->slices;slice != NULL;slice=slice->next)
{
@@ -584,26 +672,39 @@
int count = 0;
for(slice = imgTrack->slices;slice != NULL;slice=slice->next)
{
+ if(slice->type == stButton) // Buttons don't have maps. Overlap will be ignored!
+ continue;
+ if(slice->parentImg != NULL)
+ {
if(imgFile == NULL)
imgFile = slice->parentImg->file;
else if(differentString(imgFile,slice->parentImg->file))
{
char * name = (imgTrack->name != NULL ? imgTrack->name : imgTrack->tdb != NULL ? imgTrack->tdb->tableName : imgFile);
warn("imgTrackAddMapItem(%s) called, but not all slice images are the same for this track.",name);
}
- if(topLeftX < (slice->offsetX + slice->width)
- && bottomRightX >= slice->offsetX
- && topLeftY < (slice->offsetY + slice->height)
- && bottomRightY >= slice->offsetY ) // some overlap
+ }
+ if(topLeftX < (slice->offsetX + slice->width-1)
+ && bottomRightX > (slice->offsetX + 1)
+ && topLeftY < (slice->offsetY + slice->height-1)
+ && bottomRightY > (slice->offsetY + 1)) // Overlap of a pixel or 2 is tolerated
{
struct mapSet *map = sliceGetMap(slice,FALSE);
if(map!=NULL)
{ // NOTE: using find or add gives precedence to first of same coordinate map items added
mapSetItemFindOrAdd(map,link,title,max(topLeftX,slice->offsetX),max(topLeftY,slice->offsetY),min(bottomRightX,slice->offsetX + slice->width),min(bottomRightY,slice->offsetY + slice->height), id);
count++;
}
+ else
+ { // FIXME: This is assuming that if there is no map then the entire slice should get the link!
+ char * name = (imgTrack->name != NULL ? imgTrack->name : imgTrack->tdb != NULL ? imgTrack->tdb->tableName : imgFile);
+ warn("imgTrackAddMapItem(%s,%s) mapItem(lx:%d,rx:%d) is overlapping slice:%s(lx:%d,rx:%d)",name,title,topLeftX,bottomRightX,
+ sliceTypeToString(slice->type),slice->offsetX,(slice->offsetX + slice->width - 1));
+ sliceAddLink(slice,link,title);
+ count++;
+ }
}
}
//if(count>=2)
// {
@@ -654,9 +755,9 @@
warn("imgTrack(%s) has no slices.",name);
return FALSE;
}
// Can have no more than one of each type of slice
-boolean found[isMaxSliceTypes] = { FALSE,FALSE,FALSE,FALSE};
+boolean found[stMaxSliceTypes] = { FALSE,FALSE,FALSE,FALSE};
struct imgSlice *slice = imgTrack->slices;
for(; slice != NULL; slice = slice->next )
{
if(found[slice->type])
@@ -675,9 +776,9 @@
return FALSE;
}
}
// This is not a requirement as the data portion could be empty (height==0) FIXME This still needs to be properly resolved
-//if(!found[isData])
+//if(!found[stData])
// {
// if (verbose)
// warn("imgTrack(%s) has no DATA slice.",name);
// return FALSE;
@@ -938,15 +1039,17 @@
/* This routine sorts the imgTracks then forces tight ordering, so new tracks wil go to the end */
{
#ifdef IMAGEv2_DRAG_REORDER
slSort(&(imgBox->imgTracks), imgTrackOrderCmp);
+#ifndef FLAT_TRACK_LIST
struct imgTrack *imgTrack = NULL;
int lastOrder = 0;
for (imgTrack = imgBox->imgTracks; imgTrack != NULL; imgTrack = imgTrack->next )
{
if(imgTrack->reorderable)
imgTrack->order = ++lastOrder;
}
+#endif//ndef FLAT_TRACK_LIST
#else//ifndef IMAGEv2_DRAG_REORDER
slReverse(&(imgBox->imgTracks));
#endif//ndef IMAGEv2_DRAG_REORDER
}
@@ -1042,10 +1145,10 @@
if (verbose)
warn("imgBox(%s.%s:%d-%d) has bad slice",imgBox->db,imgBox->chrom,imgBox->chromStart,imgBox->chromEnd);
return FALSE;
}
- // Every slice must point to an image owned by the imgBox
- if(slIxFromElement(imgBox->images,slice->parentImg) == -1)
+ // Every slice that has an image must point to an image owned by the imgBox
+ if(slice->parentImg && (slIxFromElement(imgBox->images,slice->parentImg) == -1))
{
if (verbose)
warn("imgBox(%s.%s:%d-%d) has slice(%s) for unknown image (%s)",
imgBox->db,imgBox->chrom,imgBox->chromStart,imgBox->chromEnd,
@@ -1080,22 +1183,22 @@
/////////////////////// imageV2 UI API
-void imageMapDraw(struct mapSet *map,char *name)
+static boolean imageMapDraw(struct mapSet *map,char *name)
/* writes an image map as HTML */
{
//warn("Drawing map_%s %s",name,(map == NULL?"map is NULL":map->items == NULL?"map->items is NULL":"Should draw!"));
if(map == NULL || map->items == NULL)
- return;
+ return FALSE;
slReverse(&(map->items)); // These must be reversed so that they are printed in the same order as created!
-hPrintf(" <MAP name='map_%s'>\n", name); // map_ prefix is implicit
+hPrintf(" <MAP name='map_%s'>", name); // map_ prefix is implicit
struct mapItem *item = map->items;
for(;item!=NULL;item=item->next)
{
- hPrintf(" <AREA SHAPE=RECT COORDS='%d,%d,%d,%d'",
+ hPrintf("\n <AREA SHAPE=RECT COORDS='%d,%d,%d,%d'",
item->topLeftX, item->topLeftY, item->bottomRightX, item->bottomRightY);
// TODO: remove static portion of the link and handle in js
if(map->linkRoot != NULL)
hPrintf(" HREF='%s%s'",map->linkRoot,(item->linkVar != NULL?item->linkVar:""));
@@ -1107,73 +1210,113 @@
if(item->title != NULL)
hPrintf(" TITLE='%s'", item->title );
if(item->id != NULL)
hPrintf(" id='%s'", item->id);
- hPrintf(">\n" );
+ hPrintf(">" );
}
-hPrintf(" </MAP>\n");
+hPrintf("</MAP>\n");
+return TRUE;
}
-void sliceAndMapDraw(struct imgBox *imgBox,struct imgSlice *slice,char *name,boolean scrollHandle)
+static void imageDraw(struct imgBox *imgBox,struct imgTrack *imgTrack,struct imgSlice *slice,char *name,int offsetX,int offsetY,boolean useMap)
+/* writes an image as HTML */
+{
+if(slice->parentImg && slice->parentImg->file != NULL)
+ {
+ hPrintf(" <IMG id='img_%s' src='%s' style='position:relative; left:-%dpx; top: -%dpx; border:0;'",
+ name,slice->parentImg->file,offsetX,offsetY);
+
+ if(useMap)
+ hPrintf(" usemap='#map_%s'",name);
+ if(slice->type==stSide)
+ hPrintf(" class='sideLab'");
+ else if(slice->type==stCenter)
+ hPrintf(" class='centerLab'");
+ else if(slice->type==stButton)
+ hPrintf(" class='button'");
+ #ifdef IMAGEv2_DRAG_SCROLL
+ else if(slice->type==stData && imgBox->showPortal)
+ hPrintf(" class='panImg' ondrag='{return false;}'");
+ #endif //def IMAGEv2_DRAG_SCROLL
+ if(slice->title != NULL)
+ hPrintf(" title='%s'",slice->title); // Adds slice wide title
+ else if(slice->parentImg->title != NULL)
+ hPrintf(" title='%s'",slice->parentImg->title);// Adds image wide title
+ hPrintf(">");
+ }
+else
+ {
+ hPrintf(" <p id='p_%s' style='height:%dpx;",name,slice->height);
+ if(slice->type==stButton)
+ {
+ char *trackName = (imgTrack->name != NULL ?
+ imgTrack->name :
+ imgTrack->tdb->parent ?
+ imgTrack->tdb->parent->tableName:
+ imgTrack->tdb->tableName );
+ hPrintf(" width:9px; display:none;' class='%s btn btnN btnGrey'></p>",trackName);
+ }
+ else
+ hPrintf("width:%dpx;'></p>",slice->width);
+ }
+}
+
+static void sliceAndMapDraw(struct imgBox *imgBox,struct imgTrack *imgTrack,enum sliceType sliceType,char *name,boolean scrollHandle)
/* writes a slice of an image and any assocated image map as HTML */
{
+if(imgBox==NULL || imgTrack==NULL)
+ return;
+struct imgSlice *slice = imgTrackSliceGetByType(imgTrack,sliceType);
if(slice==NULL || slice->height == 0)
return;
-// Adjustment for portal
+
+boolean useMap=FALSE;
int offsetX=slice->offsetX;
int width=slice->width;
-if(imgBox->showPortal && imgBox->basesPerPixel > 0
-&& (slice->type==isData || slice->type==isCenter))
+if(slice->parentImg)
+ {
+ // Adjustment for portal
+ if(imgBox->showPortal && imgBox->basesPerPixel > 0
+ && (sliceType==stData || sliceType==stCenter))
{
offsetX += (imgBox->portalStart - imgBox->chromStart) / imgBox->basesPerPixel;
width=imgBox->portalWidth;
}
-hPrintf(" <div style='width:%dpx; height:%dpx; overflow:hidden;'",width,slice->height);
-#ifdef IMAGEv2_DRAG_SCROLL
-if(imgBox->showPortal && slice->type==isData)
- {
- if(scrollHandle)
- hPrintf(" class='panDiv scroller'");
- else
- hPrintf(" class='panDiv'");
+ hPrintf(" <div style='width:%dpx; height:%dpx; overflow:hidden;'",width,slice->height);
+ #ifdef IMAGEv2_DRAG_SCROLL
+ if(imgBox->showPortal && sliceType==stData)
+ hPrintf(" class='panDiv%s'",(scrollHandle?" scroller":""));
+ #endif //def IMAGEv2_DRAG_SCROLL
+ hPrintf(">\n");
}
-#endif //def IMAGEv2_DRAG_SCROLL
-hPrintf(">\n");
-
struct mapSet *map = sliceGetMap(slice,FALSE); // Could be the image map or slice specific
if(map)
- imageMapDraw(map,name);
+ useMap = imageMapDraw(map,name);
+else if(slice->link != NULL)
+ {
+ hPrintf(" <A HREF='%s'",slice->link);
+ if(slice->title != NULL)
+ hPrintf(" TITLE='Click for %s'", slice->title );
+ hPrintf(">\n" );
+ }
-hPrintf(" <IMG id='img_%s' src='%s' style='position:relative; left:-%dpx; top: -%dpx; border:0;'",
- name,slice->parentImg->file,offsetX,slice->offsetY);
+imageDraw(imgBox,imgTrack,slice,name,offsetX,slice->offsetY,useMap);
+if(slice->link != NULL)
+ hPrintf("</A>\n");
-if(map && map->items)
- hPrintf(" usemap='#map_%s'",name);
-if(slice->type==isSide)
- hPrintf(" class='sideLab'");
-else if(slice->type==isCenter)
- hPrintf(" class='centerLab'");
-else if(slice->type==isButton)
- hPrintf(" class='button'");
-#ifdef IMAGEv2_DRAG_SCROLL
-else if(slice->type==isData && imgBox->showPortal)
- hPrintf(" class='panImg' ondrag='{return false;}'");
-#endif //def IMAGEv2_DRAG_SCROLL
-//hPrintf(" title='[%s] width:%d height: %d offsetX: %d offsetY: %d'",
-// sliceTypeToString(slice->type),slice->width,slice->height,slice->offsetX,slice->offsetY);
-if(slice->title != NULL)
- hPrintf(" title='%s'",slice->title); // Adds slice wide title
-else if(slice->parentImg->title != NULL)
- hPrintf(" title='%s'",slice->parentImg->title);// Adds image wide title
-hPrintf("></div>\n");
+if(slice->parentImg)
+ hPrintf("</div>");
}
void imageBoxDraw(struct imgBox *imgBox)
/* writes a entire imgBox including all tracksas HTML */
{
+if(imgBox->imgTracks == NULL) // Not an error to have an empty image
+ return;
if(!imgBoxIsComplete(imgBox,TRUE))
return;
char name[128];
+int bgOffset = NO_VALUE;
imgBoxTracksNormalizeOrder(imgBox);
hPrintf("<!---------------vvv IMAGEv2 vvv---------------->\n");
@@ -1185,8 +1328,17 @@
#ifdef IMAGEv2_DRAG_REORDER
hPrintf(".trDrag {opacity:0.4; padding:1px; background-color:red;}\n");// outline:red solid thin;}\n"); // opacity for FF, padding/bg for IE
hPrintf(".dragHandle {cursor: s-resize;}\n");
#endif//def IMAGEv2_DRAG_REORDER
+#ifdef FLAT_TRACK_LIST
+hPrintf(".btn {border-style:outset; background-color:#cccccc; border-color:#dddddd;}\n");
+hPrintf(".btnN {border-width:1px 1px 1px 1px; margin:1px 1px 0px 1px;}\n"); // connect none
+hPrintf(".btnU {border-width:0px 1px 1px 1px; margin:0px 1px 0px 1px;}\n"); // connect up
+hPrintf(".btnD {border-width:1px 1px 0px 1px; margin:1px 1px 0px 1px;}\n"); // connect down
+hPrintf(".btnL {border-width:0px 1px 0px 1px; margin:0px 1px 0px 1px;}\n"); // connect linear
+//hPrintf(".btnGrey {background-color:#cccccc; border-color:#dddddd;}\n");
+hPrintf(".btnBlue {background-color:#91B3E6; border-color:#91B3E6;}\n");
+#endif//def FLAT_TRACK_LIST
hPrintf("div.dragZoom {cursor: text;}\n");
hPrintf("</style>\n");
#ifdef IMAGEv2_DRAG_SCROLL
@@ -1202,15 +1354,15 @@
(int)((imgBox->portalStart - imgBox->chromStart) / imgBox->basesPerPixel),imgBox->basesPerPixel);
}
#endif//def IMAGEv2_DRAG_SCROLL
-hPrintf("<TABLE id='imgTbl' border=0 cellspacing=0 cellpadding=0 BGCOLOR='%s'","white");//"#AA0000"); // RED to help find bugs
+hPrintf("<TABLE id='imgTbl' border=0 cellspacing=0 cellpadding=0 BGCOLOR='%s'",COLOR_WHITE);//COLOR_RED); // RED to help find bugs
hPrintf(" width=%d",imgBox->showPortal?(imgBox->portalWidth+imgBox->sideLabelWidth):imgBox->width);
#ifdef IMAGEv2_DRAG_REORDER
hPrintf(" class='tableWithDragAndDrop'");
#endif//def IMAGEv2_DRAG_REORDER
-hPrintf(" style='border:1px solid blue;border-collapse:separate'");
-hPrintf(">\n");
+hPrintf(" style='border:1px solid blue;border-collapse:separate;");
+hPrintf("'>\n");
struct imgTrack *imgTrack = imgBox->imgTracks;
for(;imgTrack!=NULL;imgTrack=imgTrack->next)
{
@@ -1222,50 +1374,69 @@
{
// button
safef(name, sizeof(name), "btn_%s", trackName);
hPrintf(" <TD id='td_%s'%s>\n",name,(imgTrack->reorderable?" class='dragHandle'":""));
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isButton), name,FALSE);
- hPrintf(" </TD>");
+ sliceAndMapDraw(imgBox,imgTrack,stButton,name,FALSE);
+ hPrintf("</TD>\n");
// leftLabel
safef(name,sizeof(name),"side_%s",trackName);
hPrintf(" <TD id='td_%s'%s>\n",name,
(imgTrack->reorderable?" class='dragHandle' title='Drag to reorder'":""));
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isSide), name,FALSE);
- hPrintf(" </TD>");
+ sliceAndMapDraw(imgBox,imgTrack,stSide,name,FALSE);
+ hPrintf("</TD>\n");
}
// Main/Data image region
- hPrintf(" <TD id='td_data_%s' width=%d>\n", trackName, imgBox->width);
+ hPrintf(" <TD id='td_data_%s' width=%d class='tdData'", trackName, imgBox->width);
+ if(imgBox->bgImg)
+ {
+ if(imgBox->showSideLabel && imgBox->plusStrand)
+ {
+ if(bgOffset == NO_VALUE)
+ {
+ struct imgSlice *slice = imgTrackSliceGetByType(imgTrack,stData);
+ if(slice)
+ bgOffset = (slice->offsetX * -1); // This works because the ruler has a slice
+ }
+ hPrintf(" style='background-image:url(\"%s\");background-position:%dpx;'",imgBox->bgImg->file,bgOffset);
+ }
+ else
+ hPrintf(" style='background-image:url(\"%s\");'",imgBox->bgImg->file);
+ }
+ hPrintf(">\n");
hPrintf(" <input TYPE=HIDDEN name='%s_%s' value='%d'>\n",trackName,IMG_ORDER_VAR,imgTrack->order);
// centerLabel
if(imgTrack->showCenterLabel)
{
safef(name, sizeof(name), "center_%s", trackName);
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isCenter), name,FALSE);
+ sliceAndMapDraw(imgBox,imgTrack,stCenter,name,FALSE);
//hPrintf("<BR>\n");
}
// data image
safef(name, sizeof(name), "data_%s", trackName);
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isData), name,(imgTrack->order>0));
- hPrintf(" </TD>");
+ sliceAndMapDraw(imgBox,imgTrack,stData,name,(imgTrack->order>0));
+ hPrintf("</TD>\n");
if(imgBox->showSideLabel && !imgTrack->plusStrand)
{
// rightLabel
safef(name, sizeof(name), "side_%s", trackName);
hPrintf(" <TD id='td_%s'%s>\n", name,
(imgTrack->reorderable?" class='dragHandle' title='Drag to reorder'":""));
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isSide), name,FALSE);
- hPrintf(" </TD>\n");
+ sliceAndMapDraw(imgBox,imgTrack,stSide,name,FALSE);
+ hPrintf("</TD>\n");
// button
safef(name, sizeof(name), "btn_%s", trackName);
hPrintf(" <TD id='td_%s'%s>\n",name,(imgTrack->reorderable?" class='dragHandle'":""));
- sliceAndMapDraw(imgBox,imgTrackSliceGetByType(imgTrack,isButton), name,FALSE);
- hPrintf(" </TD>");
+ sliceAndMapDraw(imgBox,imgTrack,stButton, name,FALSE);
+ hPrintf("</TD>\n");
}
hPrintf("</TR>\n");
}
hPrintf("</TABLE>\n");
hPrintf("<!---------------^^^ IMAGEv2 ^^^---------------->\n");
}
+// Nice to do:
+// 1) For composites in dense (those without a title), replace map items with toggle! Sould we?
+
#endif//def IMAGEv2_UI