diff --git a/Gruntfile.js b/Gruntfile.js index 2f43b5eb..0a6c2e25 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -197,7 +197,7 @@ module.exports = function(grunt) { ['clean', 'browserify', 'uglify', 'hash', 'buildIndex', 'shell', 'jasmine_node', 'jshint', 'lintStrings', 'compliment'] ); grunt.registerTask('lint', ['jshint', 'compliment']); - grunt.registerTask('fastBuild', ['clean', 'browserify', 'hash', 'buildIndex']); + grunt.registerTask('fastBuild', ['clean', 'browserify', 'hash', 'buildIndex', 'jshint']); grunt.registerTask('watching', ['fastBuild', 'jasmine_node', 'jshint', 'lintStrings']); grunt.registerTask('default', ['build']); diff --git a/src/js/app/index.js b/src/js/app/index.js index 19c755cb..cf7a7548 100644 --- a/src/js/app/index.js +++ b/src/js/app/index.js @@ -4,6 +4,7 @@ var Backbone = require('backbone'); var constants = require('../util/constants'); var util = require('../util'); var intl = require('../intl'); +var GlobalState = require('../util/globalState'); /** * Globals @@ -195,7 +196,7 @@ var initDemo = function(sandbox) { } if (params.locale !== undefined && params.locale.length) { - constants.GLOBAL.locale = params.locale; + GlobalState.locale = params.locale; events.trigger('localeChanged'); } diff --git a/src/js/intl/index.js b/src/js/intl/index.js index 9262377b..49bec6ec 100644 --- a/src/js/intl/index.js +++ b/src/js/intl/index.js @@ -1,6 +1,7 @@ var _ = require('underscore'); var constants = require('../util/constants'); var util = require('../util'); +var GlobalState = require('../util/globalState'); var strings = require('../intl/strings').strings; @@ -9,8 +10,8 @@ var getDefaultLocale = exports.getDefaultLocale = function() { }; var getLocale = exports.getLocale = function() { - if (constants.GLOBAL.locale) { - return constants.GLOBAL.locale; + if (GlobalState.locale) { + return GlobalState.locale; } return getDefaultLocale(); }; diff --git a/src/js/intl/strings.js b/src/js/intl/strings.js index f0fd7549..1c8ceac0 100644 --- a/src/js/intl/strings.js +++ b/src/js/intl/strings.js @@ -377,6 +377,11 @@ exports.strings = { 'fr_FR': 'Git version PCOTTLE.1.0' }, /////////////////////////////////////////////////////////////////////////// + 'flip-tree-command': { + '__desc__': 'when the tree is being flipped', + 'en_US': 'Flipping tree...' + }, + /////////////////////////////////////////////////////////////////////////// 'refresh-tree-command': { '__desc__': 'when the tree is visually refreshed', 'en_US': 'Refreshing tree...', diff --git a/src/js/level/index.js b/src/js/level/index.js index c8891d73..d2509668 100644 --- a/src/js/level/index.js +++ b/src/js/level/index.js @@ -10,6 +10,7 @@ var log = require('../log'); var Errors = require('../util/errors'); var Sandbox = require('../sandbox/').Sandbox; var Constants = require('../util/constants'); +var GlobalState = require('../util/globalState'); var Visualization = require('../visuals/visualization').Visualization; var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall; @@ -365,7 +366,7 @@ var Level = Sandbox.extend({ var numCommands = this.gitCommandsIssued.length; var best = this.getNumSolutionCommands(); - Constants.GLOBAL.isAnimating = true; + GlobalState.isAnimating = true; var skipFinishDialog = this.testOption('noFinishDialog'); var finishAnimationChain = this.mainVis.gitVisuals.finishAnimation(); if (this.mainVis.originVis) { @@ -401,7 +402,7 @@ var Level = Sandbox.extend({ // nothing to do, we will just close }) .done(function() { - Constants.GLOBAL.isAnimating = false; + GlobalState.isAnimating = false; defer.resolve(); }); }, diff --git a/src/js/sandbox/commands.js b/src/js/sandbox/commands.js index c316dfe6..266a54f1 100644 --- a/src/js/sandbox/commands.js +++ b/src/js/sandbox/commands.js @@ -2,6 +2,7 @@ var _ = require('underscore'); var util = require('../util'); var constants = require('../util/constants'); +var GlobalState = require('../util/globalState'); var intl = require('../intl'); var Commands = require('../commands'); @@ -23,7 +24,7 @@ var instantCommands = [ }); }], [/^(locale|locale reset)$/, function(bits) { - constants.GLOBAL.locale = intl.getDefaultLocale(); + GlobalState.locale = intl.getDefaultLocale(); var Main = require('../app').getEvents().trigger('localeChanged'); throw new CommandResult({ @@ -47,7 +48,7 @@ var instantCommands = [ }); }], [/^locale (\w+)$/, function(bits) { - constants.GLOBAL.locale = bits[1]; + GlobalState.locale = bits[1]; var Main = require('../app').getEvents().trigger('localeChanged'); throw new CommandResult({ @@ -57,6 +58,15 @@ var instantCommands = [ ) }); }], + [/^flip$/, function() { + GlobalState.flipTreeY = !GlobalState.flipTreeY; + + var events = require('../app').getEvents(); + events.trigger('refreshTree'); + throw new CommandResult({ + msg: intl.str('flip-tree-command') + }); + }], [/^refresh$/, function() { var events = require('../app').getEvents(); diff --git a/src/js/util/constants.js b/src/js/util/constants.js index b3ba9c5a..ea581a88 100644 --- a/src/js/util/constants.js +++ b/src/js/util/constants.js @@ -5,11 +5,6 @@ var TIME = { betweenCommandsDelay: 400 }; -// useful for locks, etc -var GLOBAL = { - isAnimating: false -}; - var VIEWPORT = { minZoom: 0.55, maxZoom: 1.25, @@ -53,7 +48,6 @@ var GRAPHICS = { orphanNodeFill: 'hsb(0.5,0.8,0.7)' }; -exports.GLOBAL = GLOBAL; exports.TIME = TIME; exports.GRAPHICS = GRAPHICS; exports.VIEWPORT = VIEWPORT; diff --git a/src/js/util/globalState.js b/src/js/util/globalState.js new file mode 100644 index 00000000..ffc95cf6 --- /dev/null +++ b/src/js/util/globalState.js @@ -0,0 +1,11 @@ +/** + * Random grab bag of global state variables so we + * dont just straight up use window + */ + +var GlobalState = { + flipTreeY: false, + isAnimating: false +}; + +module.exports = GlobalState; diff --git a/src/js/visuals/animation/index.js b/src/js/visuals/animation/index.js index ce934eeb..f2071368 100644 --- a/src/js/visuals/animation/index.js +++ b/src/js/visuals/animation/index.js @@ -1,7 +1,7 @@ var _ = require('underscore'); var Q = require('q'); var Backbone = require('backbone'); -var GLOBAL = require('../../util/constants').GLOBAL; +var GlobalState = require('../../util/globalState'); var GRAPHICS = require('../../util/constants').GRAPHICS; var Animation = Backbone.Model.extend({ @@ -67,13 +67,13 @@ var AnimationQueue = Backbone.Model.extend({ this.set('index', 0); // set the global lock that we are animating - GLOBAL.isAnimating = true; + GlobalState.isAnimating = true; this.next(); }, finish: function() { // release lock here - GLOBAL.isAnimating = false; + GlobalState.isAnimating = false; this.get('callback')(); }, diff --git a/src/js/visuals/index.js b/src/js/visuals/index.js index 3d2ea47a..7eef956f 100644 --- a/src/js/visuals/index.js +++ b/src/js/visuals/index.js @@ -3,7 +3,7 @@ var Q = require('q'); var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; -var GLOBAL = require('../util/constants').GLOBAL; +var GlobalState = require('../util/globalState'); var Collections = require('../models/collections'); var CommitCollection = Collections.CommitCollection; @@ -124,10 +124,13 @@ GitVisuals.prototype.initHeadBranch = function() { }; GitVisuals.prototype.getScreenPadding = function() { + // if we are flipping the tree, the helper bar gets in the way + var topFactor = (GlobalState.flipTreeY) ? 3 : 1.5; + // for now we return the node radius subtracted from the walls return { widthPadding: GRAPHICS.nodeRadius * 1.5, - topHeightPadding: GRAPHICS.nodeRadius * 1.5, + topHeightPadding: GRAPHICS.nodeRadius * topFactor, // we pad the bottom a lot more so the branches wont go off screen bottomHeightPadding: GRAPHICS.nodeRadius * 5 }; @@ -180,10 +183,15 @@ GitVisuals.prototype.toScreenCoords = function(pos) { return paddingTop + frac * (total - paddingBelow - paddingTop); }; - return { - x: shrink(pos.x, this.paper.width, padding.widthPadding), - y: asymShrink(pos.y, this.paper.height, padding.topHeightPadding, padding.bottomHeightPadding) - }; + var x = shrink(pos.x, this.paper.width, padding.widthPadding); + var y = + asymShrink(pos.y, this.paper.height, padding.topHeightPadding, padding.bottomHeightPadding); + + if (GlobalState.flipTreeY) { + y = this.paper.height - y; + } + + return {x: x, y: y}; }; GitVisuals.prototype.animateAllAttrKeys = function(keys, attr, speed, easing) { @@ -782,14 +790,7 @@ GitVisuals.prototype.canvasResize = function(width, height) { GitVisuals.prototype.genResizeFunc = function() { this.resizeFunc = _.debounce( _.bind(function(width, height) { - - // refresh when we are ready if we are animating som ething - if (false && GLOBAL.isAnimating) { - var Main = require('../app'); - Main.getEventBaton().trigger('commandSubmitted', 'refresh'); - } else { - this.refreshTree(); - } + this.refreshTree(); }, this), 200, true diff --git a/src/js/visuals/visEdge.js b/src/js/visuals/visEdge.js index 99ea9cec..0cdbbab4 100644 --- a/src/js/visuals/visEdge.js +++ b/src/js/visuals/visEdge.js @@ -3,6 +3,7 @@ var Backbone = require('backbone'); var GRAPHICS = require('../util/constants').GRAPHICS; var VisBase = require('../visuals/visBase').VisBase; +var GlobalState = require('../util/globalState'); var VisEdge = VisBase.extend({ defaults: { @@ -51,6 +52,7 @@ var VisEdge = VisBase.extend({ // is M(move abs) C (curve to) (control point 1) (control point 2) (final point) // the control points have to be __below__ to get the curve starting off straight. + var flipFactor = (GlobalState.flipTreeY) ? -1 : 1; var coords = function(pos) { return String(Math.round(pos.x)) + ',' + String(Math.round(pos.y)); }; @@ -58,19 +60,19 @@ var VisEdge = VisBase.extend({ delta = delta || GRAPHICS.curveControlPointOffset; return { x: pos.x, - y: pos.y + delta * dir + y: pos.y + flipFactor * delta * dir }; }; var offset2d = function(pos, x, y) { return { x: pos.x + x, - y: pos.y + y + y: pos.y + flipFactor * y }; }; // first offset tail and head by radii tailPos = offset(tailPos, -1, this.get('tail').getRadius()); - headPos = offset(headPos, 1, this.get('head').getRadius()); + headPos = offset(headPos, 1, this.get('head').getRadius() * 1.15); var str = ''; // first move to bottom of tail diff --git a/todo.txt b/todo.txt index 78c11e2c..5b0c0316 100644 --- a/todo.txt +++ b/todo.txt @@ -8,7 +8,6 @@ Medium things: ~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ ] figure out what to do with instant commands (and parse waterfall and the like) [ ] disable git commands on hg levels (and vice versa) -[ ] flip trees upside down from command (look at refresh tree as a way to do this) Small things to implement: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -25,6 +24,7 @@ Ideas for cleaning Done things: (I only started this on Dec 17th 2012 to get a better sense of what was done) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[x] flip trees upside down from command (look at refresh tree as a way to do this) [x] make show solution easier [x] make helper bar clickable with goal vis floating [x] huge update to level you wrote. that you said is true for