f0a0c72f15abf7903dcc3f3957dc6f1c0ce68952 tdreszer Fri Nov 19 11:26:06 2010 -0800 Support for drag virgins being on top diff --git src/hg/hgTracks/imageV2.c src/hg/hgTracks/imageV2.c index 1ad4d1e..c609c04 100644 --- src/hg/hgTracks/imageV2.c +++ src/hg/hgTracks/imageV2.c @@ -14,59 +14,154 @@ static char const rcsid[] = "$Id: imageV2.c,v 1.32 2010/05/24 19:53:42 hiram Exp $"; struct imgBox *theImgBox = NULL; // Make this global for now to avoid huge rewrite //struct image *theOneImg = NULL; // Make this global for now to avoid huge rewrite struct imgTrack *curImgTrack = NULL; // Make this global for now to avoid huge rewrite //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 ///////////////////////// // 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 ///////////////////////// +#define IMGORD_CUSTOM_ONTOP 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[256]; // The whole reason to do this is to reorder tracks/subtracks in the image! safef(var,sizeof(var),"%s_%s",track->tdb->track,IMG_ORDER_VAR); flatTrack->order = cartUsualInt(cart, var,IMG_ANYORDER); +#ifdef IMGORD_CUSTOM_ONTOP +if(flatTrack->order >= IMG_ORDERTOP) +#else///ifndef IMGORD_CUSTOM_ONTOP if(flatTrack->order >= IMG_ORDEREND) +#endif///ndef IMGORD_CUSTOM_ONTOP { cartRemove(cart,var); flatTrack->order = IMG_ANYORDER; } +#ifdef IMGORD_CUSTOM_ONTOP +static int topOrder = IMG_ORDERTOP; // keep track of the order added to top of image +#endif///def IMGORD_CUSTOM_ONTOP static int lastOrder = IMG_ORDEREND; // keep track of the order added and beyond end if( flatTrack->order == IMG_ANYORDER) + { +#ifdef IMGORD_CUSTOM_ONTOP + if (track->customTrack) + flatTrack->order = ++topOrder; // Custom tracks go to top + else +#endif///def IMGORD_CUSTOM_ONTOP 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); } +#ifdef IMGORD_CUSTOM_ONTOP +void flatTracksSort(struct flatTracks **flatTracks) +// This routine sorts the imgTracks then forces tight ordering, so new tracks wil go to the end +{ +// flatTracks list has 2 sets of "order": those already dragReordered (below IMG_ORDERTOP) +// and those not yet reordered (above). Within those not yet dragReordered are 2 sets: +// Those that begin numbering at IMG_ORDERTOP and those that begin at IMG_ORDEREND. +// This routine must determine if there are any already dragOrdered, and if so, position the +// newcomers in place. Newly appearing customTracks will appear at top, while newly appearing +// standard tracks appear at the end of the image. +int haveBeenOrderd = 0, imgOrdHighest=0; // Keep track of reordered count and position +int notYetOrdered = 0, toBeTopHighest=0; // Keep track of those to be reordered, and top ordered + +// First determine what if anything needs to be rearranged. +struct flatTracks *oneTrack = *flatTracks; +for(;oneTrack!=NULL;oneTrack = oneTrack->next) + { + if (oneTrack->order <= IMG_ORDERTOP) + { + haveBeenOrderd++; + if (imgOrdHighest < oneTrack->order ) + imgOrdHighest = oneTrack->order; + } + else + { + notYetOrdered++; + if (oneTrack->order <= IMG_ORDEREND) // && oneTrack->order >= IMG_ORDERTOP + { + if (toBeTopHighest < oneTrack->order ) + toBeTopHighest = oneTrack->order; + } + } + } + +// If some have previously been dragOrdered AND some new ones need to be given an explicit order +if (haveBeenOrderd > 0 && notYetOrdered > 0) + { + char var[256]; + int gapOnTopNeeded = 0; + if (toBeTopHighest > 0) + { + gapOnTopNeeded = toBeTopHighest - IMG_ORDERTOP; + imgOrdHighest += gapOnTopNeeded; // Will be after this loop + // Warning: Will need to throw away ALL previous orderings (even those not currently in image)! + safef(var,sizeof(var),"*_%s",IMG_ORDER_VAR); + cartRemoveLike(cart, var); + } + int gapFromOrderedToEnd = (IMG_ORDEREND - imgOrdHighest); // This difference should be removed from any with IMG_ORDEREND + for(oneTrack = *flatTracks;oneTrack!=NULL;oneTrack = oneTrack->next) + { + if (oneTrack->order <= IMG_FIXEDPOS) + ; // Untouchables + else if (oneTrack->order <= IMG_ORDERTOP && gapOnTopNeeded > 0) + { // Already order tracks will need to be pushed down. + oneTrack->order += gapOnTopNeeded; + safef(var,sizeof(var),"%s_%s",oneTrack->track->track,IMG_ORDER_VAR); + cartSetInt(cart, var, oneTrack->order); + } + else if (oneTrack->order >= IMG_ORDERTOP + && oneTrack->order < IMG_ORDEREND && gapOnTopNeeded > 0) + { // Unordered custom tracks will need to be added to top! + oneTrack->order -= IMG_ORDERTOP; // Force to top + safef(var,sizeof(var),"%s_%s",oneTrack->track->track,IMG_ORDER_VAR); + cartSetInt(cart, var, oneTrack->order); + } + else if (oneTrack->order >= IMG_ORDEREND && gapFromOrderedToEnd) + { // Normal unordered tracks can fill in the trailing numbers + oneTrack->order -= gapFromOrderedToEnd; + safef(var,sizeof(var),"%s_%s",oneTrack->track->track,IMG_ORDER_VAR); + cartSetInt(cart, var, oneTrack->order); + } + } + } + +if (flatTracks && *flatTracks) + slSort(flatTracks, flatTracksCmp); +} + +#else///ifndef IMGORD_CUSTOM_ONTOP + void flatTracksSort(struct flatTracks **flatTracks) // This routine sorts the imgTracks then forces tight ordering, so new tracks wil go to the end { // flatTracks list has 2 sets of "order": those already dragReordered (below IMG_ORDEREND) // and those not yet reordered (above). It has been decided that adding new tracks to an // existing order should always put the new tracks below existing and treat them as if they // were reordered there. Thus all new tracks should get an imgOrd below IMG_ORDEREND. // The result is turning on a successive set of new tracks will have them appear below all others. int imgOrdSet = 0; boolean notYetOrdered = FALSE; struct flatTracks *oneTrack = *flatTracks; for(;oneTrack!=NULL;oneTrack = oneTrack->next) { if (oneTrack->order <= IMG_ORDEREND && imgOrdSet < oneTrack->order ) @@ -80,30 +175,32 @@ for(oneTrack = *flatTracks;oneTrack!=NULL;oneTrack = oneTrack->next) { if (oneTrack->order >= imgOrdSet) { oneTrack->order -= imgOrdSet; char var[256]; safef(var,sizeof(var),"%s_%s",oneTrack->track->track,IMG_ORDER_VAR); cartSetInt(cart, var, oneTrack->order); } } } if (flatTracks && *flatTracks) slSort(flatTracks, flatTracksCmp); } +#endif///ndef IMGORD_CUSTOM_ONTOP + 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); } } // TODO: Move to trackDb.h and trackDbCustom.c enum kindOfParent { kopChildless = 0,