From e55fba333d154918a43242122a59897b4dfb7979 Mon Sep 17 00:00:00 2001
From: Peter Cottle
Date: Mon, 7 Jan 2013 01:30:19 -0800
Subject: [PATCH] kleybarod naviation
---
build/bundle.js | 345 +++++++++++++++++++++++++++++-
src/index.html | 2 +-
src/js/level/arbiter.js | 4 +
src/js/views/levelDropdownView.js | 154 ++++++++++++-
src/levels/index.js | 3 +-
src/style/main.css | 4 +
todo.txt | 8 +-
7 files changed, 511 insertions(+), 9 deletions(-)
diff --git a/build/bundle.js b/build/bundle.js
index 88ff7a3a..f2fb5096 100644
--- a/build/bundle.js
+++ b/build/bundle.js
@@ -15518,6 +15518,10 @@ LevelArbiter.prototype.validateLevel = function(level) {
}
};
+LevelArbiter.prototype.getSequenceToLevels = function() {
+ return levelSequences;
+};
+
LevelArbiter.prototype.getSequences = function() {
return _.keys(levelSequences);
};
@@ -15563,7 +15567,8 @@ exports.levelSequences = {
],
rebase: [
require('../../levels/rebase/1').level,
- require('../../levels/rebase/2').level
+ require('../../levels/rebase/2').level,
+ require('../../levels/rebase/3').level
]
};
@@ -15637,6 +15642,17 @@ require.define("/src/levels/rebase/2.js",function(require,module,exports,__dirna
};
+});
+
+require.define("/src/levels/rebase/3.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
+ id: 'rebase3',
+ name: 'Introduction #1',
+ goalTreeString: '{"branches":{"master":{"target":"C1","id":"master"},"win":{"target":"C2","id":"win"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"win","id":"HEAD"}}',
+ solutionCommand: 'git checkout -b win; git commit',
+ hint: 'Try checking out a branch named after Charlie Sheen'
+};
+
+
});
require.define("/src/js/views/levelDropdownView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
@@ -15670,15 +15686,24 @@ var LevelDropdownView = ContainedBase.extend({
true
));
this.navEvents.on('negative', this.negative, this);
+ this.navEvents.on('positive', this.positive, this);
+ this.navEvents.on('left', this.left, this);
+ this.navEvents.on('right', this.right, this);
+ this.navEvents.on('up', this.up, this);
+ this.navEvents.on('down', this.down, this);
+
this.keyboardListener = new KeyboardListener({
events: this.navEvents,
aliasMap: {
- esc: 'negative'
+ esc: 'negative',
+ enter: 'positive'
},
wait: true
});
this.sequences = Main.getLevelArbiter().getSequences();
+ this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels();
+
this.container = new ModalTerminal({
title: 'Select a Level'
});
@@ -15690,6 +15715,148 @@ var LevelDropdownView = ContainedBase.extend({
}
},
+ positive: function() {
+ if (!this.selectedID) {
+ return;
+ }
+ this.loadLevelID(this.selectedID);
+ },
+
+ left: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(-1);
+ },
+
+ leftOrRight: function(delta) {
+ this.deselectIconByID(this.selectedID);
+ this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence());
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ right: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(1);
+ },
+
+ up: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getPreviousSequence();
+ this.downOrUp();
+ },
+
+ down: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getNextSequence();
+ this.downOrUp();
+ },
+
+ downOrUp: function() {
+ this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence());
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ turnOnKeyboardSelection: function() {
+ if (!this.selectedID) {
+ this.selectFirst();
+ return true;
+ }
+ return false;
+ },
+
+ turnOffKeyboardSelection: function() {
+ if (!this.selectedID) { return; }
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = undefined;
+ this.selectedIndex = undefined;
+ this.selectedSequence = undefined;
+ },
+
+ wrapIndex: function(index, arr) {
+ index = (index >= arr.length) ? 0 : index;
+ index = (index < 0) ? arr.length - 1 : index;
+ return index;
+ },
+
+ boundIndex: function(index, arr) {
+ index = (index >= arr.length) ? arr.length - 1 : index;
+ index = (index < 0) ? 0 : index;
+ return index;
+ },
+
+ getNextSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current + 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getPreviousSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current - 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getSequenceIndex: function(name) {
+ var index;
+ _.each(this.sequences, function(_name, _index) {
+ if (_name == name) {
+ index = _index;
+ }
+ });
+ if (index === undefined) { throw new Error('didnt find'); }
+ return index;
+ },
+
+ getIndexForID: function(id) {
+ var index;
+ var levels = this.sequenceToLevels[this.selectedSequence];
+ _.each(levels, function(level, _index) {
+ if (level.id == id) {
+ index = _index;
+ }
+ });
+ return index;
+ },
+
+ selectFirst: function() {
+ var firstID = this.sequenceToLevels[this.sequences[0]][0].id;
+ this.selectIconByID(firstID);
+ this.selectedIndex = 0;
+ this.selectedSequence = this.sequences[0];
+ },
+
+ getCurrentSequence: function() {
+ return this.sequenceToLevels[this.selectedSequence];
+ },
+
+ getSelectedID: function() {
+ return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id;
+ },
+
+ selectIconByID: function(id) {
+ this.toggleIconSelect(id, true);
+ },
+
+ deselectIconByID: function(id) {
+ this.toggleIconSelect(id, false);
+ },
+
+ toggleIconSelect: function(id, value) {
+ this.selectedID = id;
+ var selector = '#levelIcon-' + id;
+ $(selector).toggleClass('selected', value);
+ },
+
negative: function() {
this.hide();
},
@@ -15706,6 +15873,7 @@ var LevelDropdownView = ContainedBase.extend({
}
this.showDeferred = undefined;
this.keyboardListener.mute();
+ this.turnOffKeyboardSelection();
LevelDropdownView.__super__.hide.apply(this);
},
@@ -18768,6 +18936,10 @@ LevelArbiter.prototype.validateLevel = function(level) {
}
};
+LevelArbiter.prototype.getSequenceToLevels = function() {
+ return levelSequences;
+};
+
LevelArbiter.prototype.getSequences = function() {
return _.keys(levelSequences);
};
@@ -21586,15 +21758,24 @@ var LevelDropdownView = ContainedBase.extend({
true
));
this.navEvents.on('negative', this.negative, this);
+ this.navEvents.on('positive', this.positive, this);
+ this.navEvents.on('left', this.left, this);
+ this.navEvents.on('right', this.right, this);
+ this.navEvents.on('up', this.up, this);
+ this.navEvents.on('down', this.down, this);
+
this.keyboardListener = new KeyboardListener({
events: this.navEvents,
aliasMap: {
- esc: 'negative'
+ esc: 'negative',
+ enter: 'positive'
},
wait: true
});
this.sequences = Main.getLevelArbiter().getSequences();
+ this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels();
+
this.container = new ModalTerminal({
title: 'Select a Level'
});
@@ -21606,6 +21787,148 @@ var LevelDropdownView = ContainedBase.extend({
}
},
+ positive: function() {
+ if (!this.selectedID) {
+ return;
+ }
+ this.loadLevelID(this.selectedID);
+ },
+
+ left: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(-1);
+ },
+
+ leftOrRight: function(delta) {
+ this.deselectIconByID(this.selectedID);
+ this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence());
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ right: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(1);
+ },
+
+ up: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getPreviousSequence();
+ this.downOrUp();
+ },
+
+ down: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getNextSequence();
+ this.downOrUp();
+ },
+
+ downOrUp: function() {
+ this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence());
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ turnOnKeyboardSelection: function() {
+ if (!this.selectedID) {
+ this.selectFirst();
+ return true;
+ }
+ return false;
+ },
+
+ turnOffKeyboardSelection: function() {
+ if (!this.selectedID) { return; }
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = undefined;
+ this.selectedIndex = undefined;
+ this.selectedSequence = undefined;
+ },
+
+ wrapIndex: function(index, arr) {
+ index = (index >= arr.length) ? 0 : index;
+ index = (index < 0) ? arr.length - 1 : index;
+ return index;
+ },
+
+ boundIndex: function(index, arr) {
+ index = (index >= arr.length) ? arr.length - 1 : index;
+ index = (index < 0) ? 0 : index;
+ return index;
+ },
+
+ getNextSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current + 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getPreviousSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current - 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getSequenceIndex: function(name) {
+ var index;
+ _.each(this.sequences, function(_name, _index) {
+ if (_name == name) {
+ index = _index;
+ }
+ });
+ if (index === undefined) { throw new Error('didnt find'); }
+ return index;
+ },
+
+ getIndexForID: function(id) {
+ var index;
+ var levels = this.sequenceToLevels[this.selectedSequence];
+ _.each(levels, function(level, _index) {
+ if (level.id == id) {
+ index = _index;
+ }
+ });
+ return index;
+ },
+
+ selectFirst: function() {
+ var firstID = this.sequenceToLevels[this.sequences[0]][0].id;
+ this.selectIconByID(firstID);
+ this.selectedIndex = 0;
+ this.selectedSequence = this.sequences[0];
+ },
+
+ getCurrentSequence: function() {
+ return this.sequenceToLevels[this.selectedSequence];
+ },
+
+ getSelectedID: function() {
+ return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id;
+ },
+
+ selectIconByID: function(id) {
+ this.toggleIconSelect(id, true);
+ },
+
+ deselectIconByID: function(id) {
+ this.toggleIconSelect(id, false);
+ },
+
+ toggleIconSelect: function(id, value) {
+ this.selectedID = id;
+ var selector = '#levelIcon-' + id;
+ $(selector).toggleClass('selected', value);
+ },
+
negative: function() {
this.hide();
},
@@ -21622,6 +21945,7 @@ var LevelDropdownView = ContainedBase.extend({
}
this.showDeferred = undefined;
this.keyboardListener.mute();
+ this.turnOffKeyboardSelection();
LevelDropdownView.__super__.hide.apply(this);
},
@@ -24515,7 +24839,8 @@ exports.levelSequences = {
],
rebase: [
require('../../levels/rebase/1').level,
- require('../../levels/rebase/2').level
+ require('../../levels/rebase/2').level,
+ require('../../levels/rebase/3').level
]
};
@@ -24596,4 +24921,16 @@ require.define("/src/levels/rebase/2.js",function(require,module,exports,__dirna
});
require("/src/levels/rebase/2.js");
+require.define("/src/levels/rebase/3.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
+ id: 'rebase3',
+ name: 'Introduction #1',
+ goalTreeString: '{"branches":{"master":{"target":"C1","id":"master"},"win":{"target":"C2","id":"win"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"win","id":"HEAD"}}',
+ solutionCommand: 'git checkout -b win; git commit',
+ hint: 'Try checking out a branch named after Charlie Sheen'
+};
+
+
+});
+require("/src/levels/rebase/3.js");
+
})();
diff --git a/src/index.html b/src/index.html
index 4249d31a..c91cd51d 100644
--- a/src/index.html
+++ b/src/index.html
@@ -191,7 +191,7 @@
<% for (var i = 0; i < ids.length; i++) { %>
-
+
diff --git a/src/js/level/arbiter.js b/src/js/level/arbiter.js
index 232a6f45..9aba919a 100644
--- a/src/js/level/arbiter.js
+++ b/src/js/level/arbiter.js
@@ -89,6 +89,10 @@ LevelArbiter.prototype.validateLevel = function(level) {
}
};
+LevelArbiter.prototype.getSequenceToLevels = function() {
+ return levelSequences;
+};
+
LevelArbiter.prototype.getSequences = function() {
return _.keys(levelSequences);
};
diff --git a/src/js/views/levelDropdownView.js b/src/js/views/levelDropdownView.js
index 59b3a9e3..050ba59e 100644
--- a/src/js/views/levelDropdownView.js
+++ b/src/js/views/levelDropdownView.js
@@ -29,15 +29,24 @@ var LevelDropdownView = ContainedBase.extend({
true
));
this.navEvents.on('negative', this.negative, this);
+ this.navEvents.on('positive', this.positive, this);
+ this.navEvents.on('left', this.left, this);
+ this.navEvents.on('right', this.right, this);
+ this.navEvents.on('up', this.up, this);
+ this.navEvents.on('down', this.down, this);
+
this.keyboardListener = new KeyboardListener({
events: this.navEvents,
aliasMap: {
- esc: 'negative'
+ esc: 'negative',
+ enter: 'positive'
},
wait: true
});
this.sequences = Main.getLevelArbiter().getSequences();
+ this.sequenceToLevels = Main.getLevelArbiter().getSequenceToLevels();
+
this.container = new ModalTerminal({
title: 'Select a Level'
});
@@ -49,6 +58,148 @@ var LevelDropdownView = ContainedBase.extend({
}
},
+ positive: function() {
+ if (!this.selectedID) {
+ return;
+ }
+ this.loadLevelID(this.selectedID);
+ },
+
+ left: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(-1);
+ },
+
+ leftOrRight: function(delta) {
+ this.deselectIconByID(this.selectedID);
+ this.selectedIndex = this.wrapIndex(this.selectedIndex + delta, this.getCurrentSequence());
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ right: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.leftOrRight(1);
+ },
+
+ up: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getPreviousSequence();
+ this.downOrUp();
+ },
+
+ down: function() {
+ if (this.turnOnKeyboardSelection()) {
+ return;
+ }
+ this.selectedSequence = this.getNextSequence();
+ this.downOrUp();
+ },
+
+ downOrUp: function() {
+ this.selectedIndex = this.boundIndex(this.selectedIndex, this.getCurrentSequence());
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = this.getSelectedID();
+ this.selectIconByID(this.selectedID);
+ },
+
+ turnOnKeyboardSelection: function() {
+ if (!this.selectedID) {
+ this.selectFirst();
+ return true;
+ }
+ return false;
+ },
+
+ turnOffKeyboardSelection: function() {
+ if (!this.selectedID) { return; }
+ this.deselectIconByID(this.selectedID);
+ this.selectedID = undefined;
+ this.selectedIndex = undefined;
+ this.selectedSequence = undefined;
+ },
+
+ wrapIndex: function(index, arr) {
+ index = (index >= arr.length) ? 0 : index;
+ index = (index < 0) ? arr.length - 1 : index;
+ return index;
+ },
+
+ boundIndex: function(index, arr) {
+ index = (index >= arr.length) ? arr.length - 1 : index;
+ index = (index < 0) ? 0 : index;
+ return index;
+ },
+
+ getNextSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current + 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getPreviousSequence: function() {
+ var current = this.getSequenceIndex(this.selectedSequence);
+ var desired = this.wrapIndex(current - 1, this.sequences);
+ return this.sequences[desired];
+ },
+
+ getSequenceIndex: function(name) {
+ var index;
+ _.each(this.sequences, function(_name, _index) {
+ if (_name == name) {
+ index = _index;
+ }
+ });
+ if (index === undefined) { throw new Error('didnt find'); }
+ return index;
+ },
+
+ getIndexForID: function(id) {
+ var index;
+ var levels = this.sequenceToLevels[this.selectedSequence];
+ _.each(levels, function(level, _index) {
+ if (level.id == id) {
+ index = _index;
+ }
+ });
+ return index;
+ },
+
+ selectFirst: function() {
+ var firstID = this.sequenceToLevels[this.sequences[0]][0].id;
+ this.selectIconByID(firstID);
+ this.selectedIndex = 0;
+ this.selectedSequence = this.sequences[0];
+ },
+
+ getCurrentSequence: function() {
+ return this.sequenceToLevels[this.selectedSequence];
+ },
+
+ getSelectedID: function() {
+ return this.sequenceToLevels[this.selectedSequence][this.selectedIndex].id;
+ },
+
+ selectIconByID: function(id) {
+ this.toggleIconSelect(id, true);
+ },
+
+ deselectIconByID: function(id) {
+ this.toggleIconSelect(id, false);
+ },
+
+ toggleIconSelect: function(id, value) {
+ this.selectedID = id;
+ var selector = '#levelIcon-' + id;
+ $(selector).toggleClass('selected', value);
+ },
+
negative: function() {
this.hide();
},
@@ -65,6 +216,7 @@ var LevelDropdownView = ContainedBase.extend({
}
this.showDeferred = undefined;
this.keyboardListener.mute();
+ this.turnOffKeyboardSelection();
LevelDropdownView.__super__.hide.apply(this);
},
diff --git a/src/levels/index.js b/src/levels/index.js
index 257a5dd0..025d123b 100644
--- a/src/levels/index.js
+++ b/src/levels/index.js
@@ -7,7 +7,8 @@ exports.levelSequences = {
],
rebase: [
require('../../levels/rebase/1').level,
- require('../../levels/rebase/2').level
+ require('../../levels/rebase/2').level,
+ require('../../levels/rebase/3').level
]
};
diff --git a/src/style/main.css b/src/style/main.css
index 25861965..23f08553 100644
--- a/src/style/main.css
+++ b/src/style/main.css
@@ -597,6 +597,10 @@ div.levelIcon:active {
background-image: -webkit-linear-gradient(top, #888686, #7A7A7A)
}
+div.levelIcon.selected {
+ box-shadow: 0 0 15px #25F6FF;
+}
+
div.levelIcon.solved {
background: -webkit-gradient(linear, left top, left bottom, from(#F3F86B), to(#35A30F));
border-top: 1px solid #f4ffa1;
diff --git a/todo.txt b/todo.txt
index 690571c7..2288412c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -13,7 +13,6 @@ Cases to handle / things to edit
Small things to implement:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-[x] optional multiview on start
Minor Bugs to fix:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -22,16 +21,21 @@ Big Bugs to fix:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ ] rebase bug... ugh
+Ideas for cleaning
+~~~~~~~~~~~~~
+- CSS... a ton. Switch to less
+
/*************************************
** Publish Things **
************************************/
- cross browser support... firefox only LULZ. should be just css right?
- fix terminal input field in general
-- maybe have keyboard navigation for level selection?
Done things:
(I only started this on Dec 17th 2012 to get a better sense of what was done)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[x] keyboard navigation for level selector
+[x] optional multiview on start
[x] local storage for solved map
[x] what if they just type "levels" ?
[x] hookup for when solving happens