Fossil

Check-in [675f8c7d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the ability to draw graph rail lines in node color.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | improved-skin-edit
Files: files | file ages | folders
SHA1:675f8c7d29b09eab1f5dd2f0688270fd38733bf6
User & Date: drh 2015-03-30 16:57:31
Context
2015-03-30
17:43
Convert background colors into foreground colors before using them for drawing graph lines. Closed-Leaf check-in: 70e882b5 user: drh tags: improved-skin-edit
16:57
Add the ability to draw graph rail lines in node color. check-in: 675f8c7d user: drh tags: improved-skin-edit
15:26
Add the ability to specify circle-nodes and omit arrowheads on the timeline using the "details.txt" skin file. check-in: d4c2e8db user: drh tags: improved-skin-edit
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to skins/aht/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/black_and_white/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/blitz/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/blitz_no_logo/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/default/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/eagle/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       1
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           1

Changes to skins/enhanced1/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/khaki/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/original/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/plain_gray/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/rounded1/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to skins/xekri/details.txt.

1
2
3
4
timeline-arrowheads:    1
timeline-circle-nodes:  0
timeline-colored-lines: 0
white-foreground:       0
|
|
|
|
1
2
3
4
timeline-arrowheads:        1
timeline-circle-nodes:      0
timeline-color-graph-lines: 0
white-foreground:           0

Changes to src/skins.c.

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
**
** The following array holds the value for all known skin details.
*/
static struct SkinDetail {
  const char *zName;      /* Name of the detail */
  char *zValue;           /* Value of the detail */
} aSkinDetail[] = {
  { "timeline-arrowheads",    "1"  },
  { "timeline-circle-nodes",  "0"  },
  { "timeline-multicolor",    "0"  },
  { "white-foreground",       "0"  }
};

/*
** Invoke this routine to set the alternative skin.  Return NULL if the
** alternative was successfully installed.  Return a string listing all
** available skins if zName does not match an available skin.  Memory
** for the returned string comes from fossil_malloc() and should be freed







|
|
|
|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
**
** The following array holds the value for all known skin details.
*/
static struct SkinDetail {
  const char *zName;      /* Name of the detail */
  char *zValue;           /* Value of the detail */
} aSkinDetail[] = {
  { "timeline-arrowheads",        "1"  },
  { "timeline-circle-nodes",      "0"  },
  { "timeline-color-graph-lines", "0"  },
  { "white-foreground",           "0"  },
};

/*
** Invoke this routine to set the alternative skin.  Return NULL if the
** alternative was successfully installed.  Return a string listing all
** available skins if zName does not match an available skin.  Memory
** for the returned string comes from fossil_malloc() and should be freed

Changes to src/timeline.c.

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
...
695
696
697
698
699
700
701
702



703

704
705
706
707
708
709
710
...
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
...
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
    GraphRow *pRow;
    int i;
    char cSep;
    int mergeOffset;     /* Pixel offset from rail to merge riser */
    int iRailPitch;      /* Pixels between consecutive rails */
    int showArrowheads;  /* True to draw arrowheads.  False to omit. */
    int circleNodes;     /* True for circle nodes.  False for square nodes */
    int multicolorLines; /* Use colors for graph lines */

    iRailPitch = pGraph->iRailPitch;
    showArrowheads = skin_detail_boolean("timeline-arrowheads");
    circleNodes = skin_detail_boolean("timeline-circle-nodes");
    multicolorLines = skin_detail_boolean("timeline-multicolor");
    (void)multicolorLines; /* Not currently used */

    /* Number of pixels that the thin merge lines are offset from the
    ** the center of the think rail lines.  If zero, then the vertical
    ** merge lines overlap with the thicker rail lines.
    */
    mergeOffset = iRailPitch>=14 ? 4 : iRailPitch>=13 ? 3 : 0;
    if( PB("nomo") ) mergeOffset = 0;
................................................................................
        if( i==pRow->iRail ) continue;
        if( pRow->aiRiser[i]>0 ){
          cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
          cSep = ',';
        }
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("],mi:");



      /* mi */

      cSep = '[';
      for(i=0; i<GR_MAX_RAIL; i++){
        if( pRow->mergeIn[i] ){
          int mi = i*iRailPitch;
          if( pRow->mergeIn[i]==1 ) mi -= mergeOffset-1;
          if( pRow->mergeIn[i]==3 ) mi += mergeOffset;
          if( pRow->mergeDown & (1<<i) ) mi = -mi;
................................................................................
    @     do{
    @       left += obj.offsetLeft;
    @     }while( obj = obj.offsetParent );
    @   }
    @   return left;
    @ }
    if( showArrowheads ){
      @ function drawUpArrow(x,y0,y1){
      @   drawBox(lineClr,x,y0+4,x+1,y1);
      @   var n = document.createElement("div"),
      @       l = x-2,
      @       t = y0;
      @   n.style.position = "absolute";
      @   n.style.left = l+"px";
      @   n.style.top = t+"px";
      @   n.style.width = 0;
      @   n.style.height = 0;
      @   n.style.transform = "scale(.999)";
      @   n.style.borderWidth = 0;
      @   n.style.borderStyle = "solid";
      @   n.style.borderColor = "transparent";
      @   n.style.borderRightWidth = "3px";
      @   n.style.borderBottomColor = lineClr;
      @   n.style.borderLeftWidth = "3px";
      @   if( y0+10>=y1 ){
      @     n.style.borderBottomWidth = "5px";
      @   } else {
      @     n.style.borderBottomWidth = "7px";
      @   }
      @   cDiv.appendChild(n);
      @ }
    }else{
      @ function drawUpArrow(x,y0,y1){
      @   drawBox(lineClr,x,y0+1,x+1,y1);
      @ }
    }
    @ function drawThinArrow(y,xFrom,xTo){
    @   var n = document.createElement("div"),
    @       t = y-2;
    @   n.style.position = "absolute";
    @   n.style.top = t+"px";
................................................................................
    if( circleNodes ){
      @   n.style.borderRadius = "6px";
    }
    @ }
    @ function drawNode(p, left, btm){
    @   drawNodeBox(boxColor,p.x-5,p.y-5,p.x+6,p.y+6);
    @   drawNodeBox(p.bg||bgClr,p.x-4,p.y-4,p.x+5,p.y+5);
    @   if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
    @   if( p.f&1 ) drawNodeBox(boxColor,p.x-1,p.y-1,p.x+2,p.y+2);
    if( !omitDescenders ){
      @   if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
      @   if( p.d ) drawUpArrow(p.x, p.y+6, btm);
    }
    @   if( p.mo>0 ){
    @     var x1 = p.mo + left - 1;
    @     var y1 = p.y-3;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.mu-1];
    @     var y0 = u.y+5;
................................................................................
    @   var n = p.au.length;
    @   for(var i=0; i<n; i+=2){
    @     var x1 = p.au[i]*railPitch + left;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.au[i+1]-1];
    @     if(u.id<p.id){
    @       drawBox(lineClr,x0,p.y,x1+1,p.y+1);
    @       drawUpArrow(x1, u.y+6, p.y);
    @     }else{
    @       drawBox("#600000",x0,p.y,x1,p.y+1);
    @       drawBox("#600000",x1-1,p.y,x1,u.y+1);
    @       drawBox("#600000",x1,u.y,u.x-10,u.y+1);
    @       var n = document.createElement("div"),
    @           t = u.y-2,
    @           l = u.x-11;







|




|
<







 







|
>
>
>

>







 







|
|













|









|
|







 







|


|
|







 







|







612
613
614
615
616
617
618
619
620
621
622
623
624

625
626
627
628
629
630
631
...
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
...
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
...
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
...
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    GraphRow *pRow;
    int i;
    char cSep;
    int mergeOffset;     /* Pixel offset from rail to merge riser */
    int iRailPitch;      /* Pixels between consecutive rails */
    int showArrowheads;  /* True to draw arrowheads.  False to omit. */
    int circleNodes;     /* True for circle nodes.  False for square nodes */
    int colorGraph;      /* Use colors for graph lines */

    iRailPitch = pGraph->iRailPitch;
    showArrowheads = skin_detail_boolean("timeline-arrowheads");
    circleNodes = skin_detail_boolean("timeline-circle-nodes");
    colorGraph = skin_detail_boolean("timeline-color-graph-lines");


    /* Number of pixels that the thin merge lines are offset from the
    ** the center of the think rail lines.  If zero, then the vertical
    ** merge lines overlap with the thicker rail lines.
    */
    mergeOffset = iRailPitch>=14 ? 4 : iRailPitch>=13 ? 3 : 0;
    if( PB("nomo") ) mergeOffset = 0;
................................................................................
        if( i==pRow->iRail ) continue;
        if( pRow->aiRiser[i]>0 ){
          cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
          cSep = ',';
        }
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("],");
      if( colorGraph && pRow->zBgClr[0]=='#' ){
        cgi_printf("fg:\"%s\",", pRow->zBgClr);
      }
      /* mi */
      cgi_printf("mi:");
      cSep = '[';
      for(i=0; i<GR_MAX_RAIL; i++){
        if( pRow->mergeIn[i] ){
          int mi = i*iRailPitch;
          if( pRow->mergeIn[i]==1 ) mi -= mergeOffset-1;
          if( pRow->mergeIn[i]==3 ) mi += mergeOffset;
          if( pRow->mergeDown & (1<<i) ) mi = -mi;
................................................................................
    @     do{
    @       left += obj.offsetLeft;
    @     }while( obj = obj.offsetParent );
    @   }
    @   return left;
    @ }
    if( showArrowheads ){
      @ function drawUpArrow(x,y0,y1,clr){
      @   drawBox(clr,x,y0+4,x+1,y1);
      @   var n = document.createElement("div"),
      @       l = x-2,
      @       t = y0;
      @   n.style.position = "absolute";
      @   n.style.left = l+"px";
      @   n.style.top = t+"px";
      @   n.style.width = 0;
      @   n.style.height = 0;
      @   n.style.transform = "scale(.999)";
      @   n.style.borderWidth = 0;
      @   n.style.borderStyle = "solid";
      @   n.style.borderColor = "transparent";
      @   n.style.borderRightWidth = "3px";
      @   n.style.borderBottomColor = clr;
      @   n.style.borderLeftWidth = "3px";
      @   if( y0+10>=y1 ){
      @     n.style.borderBottomWidth = "5px";
      @   } else {
      @     n.style.borderBottomWidth = "7px";
      @   }
      @   cDiv.appendChild(n);
      @ }
    }else{
      @ function drawUpArrow(x,y0,y1,clr){
      @   drawBox(clr,x,y0+1,x+1,y1);
      @ }
    }
    @ function drawThinArrow(y,xFrom,xTo){
    @   var n = document.createElement("div"),
    @       t = y-2;
    @   n.style.position = "absolute";
    @   n.style.top = t+"px";
................................................................................
    if( circleNodes ){
      @   n.style.borderRadius = "6px";
    }
    @ }
    @ function drawNode(p, left, btm){
    @   drawNodeBox(boxColor,p.x-5,p.y-5,p.x+6,p.y+6);
    @   drawNodeBox(p.bg||bgClr,p.x-4,p.y-4,p.x+5,p.y+5);
    @   if( p.u>0 ) drawUpArrow(p.x,rowinfo[p.u-1].y+6,p.y-6,p.fg||lineClr);
    @   if( p.f&1 ) drawNodeBox(boxColor,p.x-1,p.y-1,p.x+2,p.y+2);
    if( !omitDescenders ){
      @   if( p.u==0 ) drawUpArrow(p.x,0,p.y-6,p.fg||lineClr);
      @   if( p.d ) drawUpArrow(p.x,p.y+6,btm,p.fg||lineClr);
    }
    @   if( p.mo>0 ){
    @     var x1 = p.mo + left - 1;
    @     var y1 = p.y-3;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.mu-1];
    @     var y0 = u.y+5;
................................................................................
    @   var n = p.au.length;
    @   for(var i=0; i<n; i+=2){
    @     var x1 = p.au[i]*railPitch + left;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.au[i+1]-1];
    @     if(u.id<p.id){
    @       drawBox(lineClr,x0,p.y,x1+1,p.y+1);
    @       drawUpArrow(x1,u.y+6,p.y,p.fg||lineClr);
    @     }else{
    @       drawBox("#600000",x0,p.y,x1,p.y+1);
    @       drawBox("#600000",x1-1,p.y,x1,u.y+1);
    @       drawBox("#600000",x1,u.y,u.x-10,u.y+1);
    @       var n = document.createElement("div"),
    @           t = u.y-2,
    @           l = u.x-11;