Fossil SCM
This is a graph layout improvement experiment. In this version of Fossil, when there are multiple merge lines that go off the bottom of the page, they all use the same rail, rather than using separate rails for each parent node. This code is initially parked on a branch for evaluation.
Commit
65c218199c52b1089530c16f84dded87ce420f5ccaa124d9e66feca958df6fab
Parent
f905bd0d8d5b70f…
1 file changed
+24
+24
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -499,10 +499,11 @@ | ||
| 499 | 499 | const char *zTrunk; |
| 500 | 500 | u8 *aMap; /* Copy of p->aiRailMap */ |
| 501 | 501 | int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 502 | 502 | int nTimewarp = 0; |
| 503 | 503 | int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN; |
| 504 | + int offPageMergeRail = -1; | |
| 504 | 505 | |
| 505 | 506 | /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser |
| 506 | 507 | ** coming up from the bottom of the graph from off-screen check-in Y |
| 507 | 508 | ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0. |
| 508 | 509 | */ |
| @@ -806,10 +807,31 @@ | ||
| 806 | 807 | int iMrail = -1; |
| 807 | 808 | /* Merge from a node that is off-screen */ |
| 808 | 809 | if( iReuseIdx>=p->nRow+1 ){ |
| 809 | 810 | continue; /* Suppress multiple off-screen merges */ |
| 810 | 811 | } |
| 812 | + | |
| 813 | +#if 1 | |
| 814 | + /* Display option #1 for off-page merge lines: | |
| 815 | + ** | |
| 816 | + ** Use a single rail for all merge lines that go to the bottom of | |
| 817 | + ** the page. | |
| 818 | + */ | |
| 819 | + if( offPageMergeRail>=0 ){ | |
| 820 | + iMrail = offPageMergeRail; | |
| 821 | + }else{ | |
| 822 | + iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); | |
| 823 | + if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 824 | + mergeRiserFrom[iMrail] = parentRid; | |
| 825 | + offPageMergeRail = iMrail; | |
| 826 | + } | |
| 827 | +#else | |
| 828 | + /* Display option #2 for off-page merge lines: | |
| 829 | + ** | |
| 830 | + ** Use separate rails for each distinct parent node that is | |
| 831 | + ** off of the bottom of the page. | |
| 832 | + */ | |
| 811 | 833 | for(j=0; j<GR_MAX_RAIL; j++){ |
| 812 | 834 | if( mergeRiserFrom[j]==parentRid ){ |
| 813 | 835 | iMrail = j; |
| 814 | 836 | break; |
| 815 | 837 | } |
| @@ -817,10 +839,12 @@ | ||
| 817 | 839 | if( iMrail==-1 ){ |
| 818 | 840 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 819 | 841 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 820 | 842 | mergeRiserFrom[iMrail] = parentRid; |
| 821 | 843 | } |
| 844 | +#endif | |
| 845 | + | |
| 822 | 846 | iReuseIdx = p->nRow+1; |
| 823 | 847 | iReuseRail = iMrail; |
| 824 | 848 | mask = BIT(iMrail); |
| 825 | 849 | if( i>=pRow->nNonCherrypick ){ |
| 826 | 850 | pRow->mergeIn[iMrail] = 2; |
| 827 | 851 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -499,10 +499,11 @@ | |
| 499 | const char *zTrunk; |
| 500 | u8 *aMap; /* Copy of p->aiRailMap */ |
| 501 | int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 502 | int nTimewarp = 0; |
| 503 | int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN; |
| 504 | |
| 505 | /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser |
| 506 | ** coming up from the bottom of the graph from off-screen check-in Y |
| 507 | ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0. |
| 508 | */ |
| @@ -806,10 +807,31 @@ | |
| 806 | int iMrail = -1; |
| 807 | /* Merge from a node that is off-screen */ |
| 808 | if( iReuseIdx>=p->nRow+1 ){ |
| 809 | continue; /* Suppress multiple off-screen merges */ |
| 810 | } |
| 811 | for(j=0; j<GR_MAX_RAIL; j++){ |
| 812 | if( mergeRiserFrom[j]==parentRid ){ |
| 813 | iMrail = j; |
| 814 | break; |
| 815 | } |
| @@ -817,10 +839,12 @@ | |
| 817 | if( iMrail==-1 ){ |
| 818 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 819 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 820 | mergeRiserFrom[iMrail] = parentRid; |
| 821 | } |
| 822 | iReuseIdx = p->nRow+1; |
| 823 | iReuseRail = iMrail; |
| 824 | mask = BIT(iMrail); |
| 825 | if( i>=pRow->nNonCherrypick ){ |
| 826 | pRow->mergeIn[iMrail] = 2; |
| 827 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -499,10 +499,11 @@ | |
| 499 | const char *zTrunk; |
| 500 | u8 *aMap; /* Copy of p->aiRailMap */ |
| 501 | int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0; |
| 502 | int nTimewarp = 0; |
| 503 | int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN; |
| 504 | int offPageMergeRail = -1; |
| 505 | |
| 506 | /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser |
| 507 | ** coming up from the bottom of the graph from off-screen check-in Y |
| 508 | ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0. |
| 509 | */ |
| @@ -806,10 +807,31 @@ | |
| 807 | int iMrail = -1; |
| 808 | /* Merge from a node that is off-screen */ |
| 809 | if( iReuseIdx>=p->nRow+1 ){ |
| 810 | continue; /* Suppress multiple off-screen merges */ |
| 811 | } |
| 812 | |
| 813 | #if 1 |
| 814 | /* Display option #1 for off-page merge lines: |
| 815 | ** |
| 816 | ** Use a single rail for all merge lines that go to the bottom of |
| 817 | ** the page. |
| 818 | */ |
| 819 | if( offPageMergeRail>=0 ){ |
| 820 | iMrail = offPageMergeRail; |
| 821 | }else{ |
| 822 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 823 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 824 | mergeRiserFrom[iMrail] = parentRid; |
| 825 | offPageMergeRail = iMrail; |
| 826 | } |
| 827 | #else |
| 828 | /* Display option #2 for off-page merge lines: |
| 829 | ** |
| 830 | ** Use separate rails for each distinct parent node that is |
| 831 | ** off of the bottom of the page. |
| 832 | */ |
| 833 | for(j=0; j<GR_MAX_RAIL; j++){ |
| 834 | if( mergeRiserFrom[j]==parentRid ){ |
| 835 | iMrail = j; |
| 836 | break; |
| 837 | } |
| @@ -817,10 +839,12 @@ | |
| 839 | if( iMrail==-1 ){ |
| 840 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 841 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 842 | mergeRiserFrom[iMrail] = parentRid; |
| 843 | } |
| 844 | #endif |
| 845 | |
| 846 | iReuseIdx = p->nRow+1; |
| 847 | iReuseRail = iMrail; |
| 848 | mask = BIT(iMrail); |
| 849 | if( i>=pRow->nNonCherrypick ){ |
| 850 | pRow->mergeIn[iMrail] = 2; |
| 851 |