mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-27 00:18:56 +02:00
have HEAD working
This commit is contained in:
parent
3b58cf2912
commit
f78e77e5c6
4 changed files with 116 additions and 29 deletions
|
@ -18,9 +18,12 @@ var GRAPHICS = {
|
|||
curveControlPointOffset: 50,
|
||||
defaultEasing: 'easeInOut',
|
||||
defaultAnimationTime: 300,
|
||||
|
||||
rectFill: '#FF3A3A',
|
||||
headRectFill: '#2831FF',
|
||||
rectStroke: '#FFF',
|
||||
rectStrokeWidth: '3',
|
||||
|
||||
multiBranchY: 20,
|
||||
upstreamHeadOpacity: 0.5,
|
||||
upstreamNoneOpacity: 0.2,
|
||||
|
|
|
@ -40,6 +40,9 @@ GitEngine.prototype.init = function() {
|
|||
|
||||
// commit once to get things going
|
||||
this.commit();
|
||||
|
||||
// now we are ready
|
||||
events.trigger('gitEngineReady', this);
|
||||
};
|
||||
|
||||
GitEngine.prototype.getDetachedHead = function() {
|
||||
|
|
116
src/tree.js
116
src/tree.js
|
@ -4,6 +4,12 @@ var VisBranch = Backbone.Model.extend({
|
|||
text: null,
|
||||
rect: null,
|
||||
arrow: null,
|
||||
isHead: false,
|
||||
flip: 1,
|
||||
|
||||
fill: GRAPHICS.rectFill,
|
||||
stroke: GRAPHICS.rectStroke,
|
||||
|
||||
offsetX: GRAPHICS.nodeRadius * 4.75,
|
||||
offsetY: 0,
|
||||
arrowHeight: 14,
|
||||
|
@ -11,8 +17,10 @@ var VisBranch = Backbone.Model.extend({
|
|||
arrowEdgeHeight: 6,
|
||||
arrowLength: 14,
|
||||
arrowOffsetFromCircleX: 10,
|
||||
|
||||
vPad: 5,
|
||||
hPad: 5,
|
||||
|
||||
animationSpeed: GRAPHICS.defaultAnimationTime,
|
||||
animationEasing: GRAPHICS.defaultEasing
|
||||
},
|
||||
|
@ -25,15 +33,27 @@ var VisBranch = Backbone.Model.extend({
|
|||
|
||||
initialize: function() {
|
||||
this.validateAtInit();
|
||||
if (this.get('branch').get('id') == 'HEAD') {
|
||||
// switch to a head ref
|
||||
this.set('isHead', true);
|
||||
this.set('flip', -1);
|
||||
|
||||
this.set('fill', GRAPHICS.headRectFill);
|
||||
}
|
||||
},
|
||||
|
||||
getCommitPosition: function() {
|
||||
var commit = this.get('branch').get('target');
|
||||
var commit = gitEngine.getCommitFromRef(this.get('branch'));
|
||||
var visNode = commit.get('visNode');
|
||||
return visNode.getScreenCoords();
|
||||
},
|
||||
|
||||
getBranchStackIndex: function() {
|
||||
if (this.get('isHead')) {
|
||||
// head is never stacked with other branches
|
||||
return 0;
|
||||
}
|
||||
|
||||
var myArray = this.getBranchStackArray();
|
||||
var index = -1;
|
||||
_.each(myArray, function(branch, i) {
|
||||
|
@ -45,11 +65,23 @@ var VisBranch = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
getBranchStackLength: function() {
|
||||
if (this.get('isHead')) {
|
||||
// head is always by itself
|
||||
return 1;
|
||||
}
|
||||
|
||||
return this.getBranchStackArray().length;
|
||||
},
|
||||
|
||||
getBranchStackArray: function() {
|
||||
return gitVisuals.branchStackMap[this.get('branch').get('target').get('id')];
|
||||
var arr = gitVisuals.branchStackMap[this.get('branch').get('target').get('id')];
|
||||
if (arr === undefined) {
|
||||
// this only occurs when we are generating graphics inside of
|
||||
// a new Branch instantiation, so we need to force the update
|
||||
gitVisuals.calcBranchStacks();
|
||||
return this.getBranchStackArray();
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
|
||||
getTextPosition: function() {
|
||||
|
@ -59,13 +91,14 @@ var VisBranch = Backbone.Model.extend({
|
|||
// so everything is independent
|
||||
var myPos = this.getBranchStackIndex();
|
||||
return {
|
||||
x: pos.x + this.get('offsetX'),
|
||||
x: pos.x + this.get('flip') * this.get('offsetX'),
|
||||
y: pos.y + myPos * GRAPHICS.multiBranchY + this.get('offsetY')
|
||||
};
|
||||
},
|
||||
|
||||
getRectPosition: function() {
|
||||
var pos = this.getTextPosition();
|
||||
var f = this.get('flip');
|
||||
// first get text width and height
|
||||
var textSize = this.getTextSize();
|
||||
return {
|
||||
|
@ -85,26 +118,27 @@ var VisBranch = Backbone.Model.extend({
|
|||
var toStringCoords = function(pos) {
|
||||
return String(Math.round(pos.x)) + ',' + String(Math.round(pos.y));
|
||||
};
|
||||
var f = this.get('flip');
|
||||
|
||||
var arrowTip = offset2d(this.getCommitPosition(),
|
||||
this.get('arrowOffsetFromCircleX'),
|
||||
f * this.get('arrowOffsetFromCircleX'),
|
||||
0
|
||||
);
|
||||
var arrowEdgeUp = offset2d(arrowTip, this.get('arrowLength'), -this.get('arrowHeight'));
|
||||
var arrowEdgeLow = offset2d(arrowTip, this.get('arrowLength'), this.get('arrowHeight'));
|
||||
var arrowEdgeUp = offset2d(arrowTip, f * this.get('arrowLength'), -this.get('arrowHeight'));
|
||||
var arrowEdgeLow = offset2d(arrowTip, f * this.get('arrowLength'), this.get('arrowHeight'));
|
||||
|
||||
var arrowInnerUp = offset2d(arrowEdgeUp,
|
||||
this.get('arrowInnerSkew'),
|
||||
f * this.get('arrowInnerSkew'),
|
||||
this.get('arrowEdgeHeight')
|
||||
);
|
||||
var arrowInnerLow = offset2d(arrowEdgeLow,
|
||||
this.get('arrowInnerSkew'),
|
||||
f * this.get('arrowInnerSkew'),
|
||||
-this.get('arrowEdgeHeight')
|
||||
);
|
||||
|
||||
var tailLength = 30;
|
||||
var arrowStartUp = offset2d(arrowInnerUp, tailLength, 0);
|
||||
var arrowStartLow = offset2d(arrowInnerLow, tailLength, 0);
|
||||
var arrowStartUp = offset2d(arrowInnerUp, f * tailLength, 0);
|
||||
var arrowStartLow = offset2d(arrowInnerLow, f * tailLength, 0);
|
||||
|
||||
var pathStr = '';
|
||||
pathStr += 'M' + toStringCoords(arrowStartUp) + ' ';
|
||||
|
@ -130,6 +164,13 @@ var VisBranch = Backbone.Model.extend({
|
|||
};
|
||||
|
||||
var textNode = this.get('text').node;
|
||||
if (this.get('isHead')) {
|
||||
// HEAD is a special case
|
||||
return {
|
||||
w: textNode.clientWidth,
|
||||
h: textNode.clientHeight
|
||||
};
|
||||
}
|
||||
|
||||
var maxWidth = 0;
|
||||
_.each(this.getBranchStackArray(), function(branch) {
|
||||
|
@ -192,7 +233,8 @@ var VisBranch = Backbone.Model.extend({
|
|||
var text = paper.text(textPos.x, textPos.y, String(name));
|
||||
text.attr({
|
||||
'font-size': 14,
|
||||
'font-family': 'Monaco, Courier, font-monospace'
|
||||
'font-family': 'Monaco, Courier, font-monospace',
|
||||
opacity: this.getTextOpacity()
|
||||
});
|
||||
this.set('text', text);
|
||||
|
||||
|
@ -200,18 +242,20 @@ var VisBranch = Backbone.Model.extend({
|
|||
var sizeOfRect = this.getRectSize();
|
||||
var rect = paper.rect(rectPos.x, rectPos.y, sizeOfRect.w, sizeOfRect.h, 8);
|
||||
rect.attr({
|
||||
fill: GRAPHICS.rectFill,
|
||||
stroke: GRAPHICS.rectStroke,
|
||||
'stroke-width': GRAPHICS.rectStrokeWidth
|
||||
fill: this.get('fill'),
|
||||
stroke: this.get('stroke'),
|
||||
'stroke-width': GRAPHICS.rectStrokeWidth,
|
||||
opacity: this.getNonTextOpacity()
|
||||
});
|
||||
this.set('rect', rect);
|
||||
|
||||
var arrowPath = this.getArrowPath();
|
||||
var arrow = paper.path(arrowPath);
|
||||
arrow.attr({
|
||||
fill: GRAPHICS.rectFill,
|
||||
stroke: GRAPHICS.rectStroke,
|
||||
'stroke-width': GRAPHICS.rectStrokeWidth
|
||||
fill: this.get('fill'),
|
||||
stroke: this.get('stroke'),
|
||||
'stroke-width': GRAPHICS.rectStrokeWidth,
|
||||
opacity: this.getNonTextOpacity()
|
||||
});
|
||||
this.set('arrow', arrow);
|
||||
|
||||
|
@ -225,16 +269,32 @@ var VisBranch = Backbone.Model.extend({
|
|||
});
|
||||
},
|
||||
|
||||
getNonTextOpacity: function() {
|
||||
if (this.get('isHead')) {
|
||||
return gitEngine.getDetachedHead() ? 1 : 0;
|
||||
}
|
||||
return this.getBranchStackIndex() == 0 ? 1 : 0.0;
|
||||
},
|
||||
|
||||
getTextOpacity: function() {
|
||||
if (this.get('isHead')) {
|
||||
return gitEngine.getDetachedHead() ? 1 : 0;
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
|
||||
animateUpdatedPos: function(speed, easing) {
|
||||
var s = speed !== undefined ? speed : this.get('animationSpeed');
|
||||
var e = easing || this.get('animationEasing');
|
||||
var masterOpacity = this.getBranchStackIndex() == 0 ? 1 : 0.0;
|
||||
var nonTextOpacity = this.getNonTextOpacity();
|
||||
var textOpacity = this.getTextOpacity();
|
||||
|
||||
this.updateName();
|
||||
var textPos = this.getTextPosition();
|
||||
this.get('text').stop().animate({
|
||||
x: textPos.x,
|
||||
y: textPos.y
|
||||
y: textPos.y,
|
||||
opacity: textOpacity
|
||||
}, s, e);
|
||||
|
||||
var rectPos = this.getRectPosition();
|
||||
|
@ -244,13 +304,13 @@ var VisBranch = Backbone.Model.extend({
|
|||
y: rectPos.y,
|
||||
width: rectSize.w,
|
||||
height: rectSize.h,
|
||||
opacity: masterOpacity,
|
||||
opacity: nonTextOpacity,
|
||||
}, s, e);
|
||||
|
||||
var arrowPath = this.getArrowPath();
|
||||
this.get('arrow').stop().animate({
|
||||
path: arrowPath,
|
||||
opacity: masterOpacity
|
||||
opacity: nonTextOpacity
|
||||
}, s, e);
|
||||
}
|
||||
});
|
||||
|
@ -259,6 +319,7 @@ var VisBranch = Backbone.Model.extend({
|
|||
var VisNode = Backbone.Model.extend({
|
||||
defaults: {
|
||||
depth: undefined,
|
||||
maxWidth: null,
|
||||
id: null,
|
||||
pos: null,
|
||||
radius: null,
|
||||
|
@ -295,6 +356,19 @@ var VisNode = Backbone.Model.extend({
|
|||
pos.y = this.get('depth') * depthIncrement;
|
||||
},
|
||||
|
||||
getMaxWidthScaled: function() {
|
||||
// returns our max width scaled based on if we are visible
|
||||
// from a branch or not
|
||||
var stat = gitVisuals.getCommitUpstreamStatus(this.get('commit'));
|
||||
var map = {
|
||||
branch: 1,
|
||||
head: 0.3,
|
||||
none: 0.1
|
||||
};
|
||||
if (map[stat] === undefined) { throw new Error('bad stat'); }
|
||||
return map[stat] * this.get('maxWidth');
|
||||
},
|
||||
|
||||
toFront: function() {
|
||||
this.get('circle').toFront();
|
||||
},
|
||||
|
|
|
@ -5,8 +5,8 @@ function GitVisuals(options) {
|
|||
|
||||
this.edgeCollection = new VisEdgeCollection();
|
||||
this.visBranchCollection = new VisBranchCollection();
|
||||
|
||||
this.commitMap = {};
|
||||
|
||||
this.rootCommit = null;
|
||||
this.branchStackMap = null;
|
||||
this.upstreamBranchSet = null;
|
||||
|
@ -30,8 +30,16 @@ function GitVisuals(options) {
|
|||
events.on('refreshTree', _.bind(
|
||||
this.refreshTree, this
|
||||
));
|
||||
events.on('gitEngineReady', this.whenGitEngineReady, this);
|
||||
}
|
||||
|
||||
GitVisuals.prototype.whenGitEngineReady = function(gitEngine) {
|
||||
// seed this with the HEAD pseudo-branch
|
||||
this.visBranchCollection.add(new VisBranch({
|
||||
branch: gitEngine.HEAD
|
||||
}));
|
||||
};
|
||||
|
||||
GitVisuals.prototype.getScreenBounds = function() {
|
||||
// for now we return the node radius subtracted from the walls
|
||||
return {
|
||||
|
@ -57,7 +65,7 @@ GitVisuals.prototype.toScreenCoords = function(pos) {
|
|||
};
|
||||
|
||||
/***************************************
|
||||
== Tree Calculation Parts ==
|
||||
== BEGIN Tree Calculation Parts ==
|
||||
_ __ __ _
|
||||
\\/ / \ \//_
|
||||
\ \ / __| __
|
||||
|
@ -101,11 +109,11 @@ GitVisuals.prototype.calcTreeCoords = function() {
|
|||
throw new Error('grr, no root commit!');
|
||||
}
|
||||
|
||||
this.calcUpstreamSets();
|
||||
this.calcBranchStacks();
|
||||
|
||||
this.calcDepth();
|
||||
this.calcWidth();
|
||||
|
||||
this.calcBranchStacks();
|
||||
this.calcUpstreamSets();
|
||||
};
|
||||
|
||||
GitVisuals.prototype.calcGraphicsCoords = function() {
|
||||
|
@ -116,7 +124,6 @@ GitVisuals.prototype.calcGraphicsCoords = function() {
|
|||
|
||||
GitVisuals.prototype.calcUpstreamSets = function() {
|
||||
this.upstreamBranchSet = gitEngine.getUpstreamBranchSet();
|
||||
|
||||
this.upstreamHeadSet = gitEngine.getUpstreamHeadSet();
|
||||
};
|
||||
|
||||
|
@ -193,7 +200,7 @@ GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) {
|
|||
var totalFlex = 0;
|
||||
var children = commit.get('children');
|
||||
_.each(children, function(child) {
|
||||
totalFlex += child.get('visNode').get('maxWidth');
|
||||
totalFlex += child.get('visNode').getMaxWidthScaled();
|
||||
}, this);
|
||||
|
||||
var prevBound = min;
|
||||
|
@ -201,7 +208,7 @@ GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) {
|
|||
// now go through and do everything
|
||||
// TODO: order so the max width children are in the middle!!
|
||||
_.each(children, function(child) {
|
||||
var flex = child.get('visNode').get('maxWidth');
|
||||
var flex = child.get('visNode').getMaxWidthScaled();
|
||||
var portion = (flex / totalFlex) * myLength;
|
||||
var childMin = prevBound;
|
||||
var childMax = childMin + portion;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue