Initial UI classes, with working partial rendering

The slider handle and stars render correctly. Not yet wired up to real
events.
This commit is contained in:
s1341 2013-11-24 20:14:21 +02:00
parent 95310dafd4
commit e6a426de4a
4 changed files with 198 additions and 44 deletions

View file

@ -1,3 +1,29 @@
/*
* slider handles (SliderHandle)
*/
#timeslider .slider-handle {
position: absolute;
}
#timeslider .star {
background-image: url(../../static/img/star.png);
cursor: pointer;
height: 16px;
top: 40px;
width: 15px;
}
#timeslider .handle {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
background-image: url(../../static/img/crushed_current_location.png);
cursor: pointer;
height: 61px;
left: 0;
top: 0;
width: 13px;
}
#editorcontainerbox { #editorcontainerbox {
overflow: auto; overflow: auto;
top: 40px; top: 40px;
@ -46,18 +72,7 @@
top: 1px; top: 1px;
width: 100%; width: 100%;
} }
#ui-slider-handle {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
background-image: url(../../static/img/crushed_current_location.png);
cursor: pointer;
height: 61px;
left: 0;
position: absolute;
top: 0;
width: 13px;
}
#ui-slider-bar { #ui-slider-bar {
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
@ -121,14 +136,6 @@
top: 20px; top: 20px;
width: 30px; width: 30px;
} }
#timeslider .star {
background-image: url(../../static/img/star.png);
cursor: pointer;
height: 16px;
position: absolute;
top: 40px;
width: 15px;
}
#timeslider #timer { #timeslider #timer {
color: #fff; color: #fff;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;

View file

@ -26,19 +26,163 @@ var _ = require('./underscore');
var padmodals = require('./pad_modals').padmodals; var padmodals = require('./pad_modals').padmodals;
require("./jquery.class"); require("./jquery.class");
function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded) /**
* A class for anything which can be hung off of the slider bar.
* I.e. this is for the handle, or saved-revisions (stars).
* TODO:
* - handle mousedowns/clicks
* - handle drags
*/
$.Class("SliderHandleUI",
{//statics
},
{//instance
/**
* Construct the SliderHandle.
* @param {SliderUI} slider The slider from which this handle will be hung.
* @param {Number} position The initial position for this handle.
*/
init: function (slider, position, type) {
console.log("New SliderHandle(%d, %s)", position, type);
this.slider = slider;
this.position = position;
this.events = {};
//create the element:
this.element = $("<div class='slider-handle'></div>");
this.element.addClass(type);
//handle events
this.element.mouseup(this._dispatchEvent);
this.element.mousedown(this._dispatchEvent);
},
on: function (eventname, callback, context) {
if (!(eventname in this.events))
this.events[eventname] = [];
this.events[eventname].push({handler:callback, context: context});
},
_dispatchEvent: function (evt) {
if (eventname in this.events)
for (var i in this.events[eventname])
{
e = this.events[eventname][i];
e.handler(evt, e.context);
}
},
render: function () {
this.element.css('left', this.position * this.slider.getTickSize());
},
setPosition: function (position) {
this.position = position;
this.render();
}
}
);
SliderHandleUI("SliderSavedRevisionUI",
{//statics
},
{//instance
init: function(slider, revision) {
this._super(slider, revision.revNum, 'star');
this.revision = revision;
},
}
);
$.Class("SliderUI",
{//statics
},
{//instance
init: function (timeslider, root_element) {
this.timeslider = timeslider;
console.log("New SliderUI, head_revision = %d", this.timeslider.head_revision);
// parse the various elements we need:
this.elements = {};
this.loadElements(root_element);
this.handles=[];
this.main_handle = this.attachHandle(new SliderHandleUI(this, this.timeslider.head_revision, 'handle'));
this.loadSavedRevisions();
this.render();
//events:
_this = this;
$(window).resize(function() {_this.render.call(_this)});
this.elements['slider-bar'].mousedown(function(evt) {
var revision = Math.floor((evt.clientX-$(this).offset().left) / _this.getTickSize());
_this.goToRevision(revision);
});
},
loadElements: function (root_element) {
this.elements['root'] = root_element;
//this.elements['slider-handle'] = root_element.first("#ui-slider-handle");
this.elements['slider-bar'] = root_element.find("#ui-slider-bar");
this.elements['slider'] = root_element.find("#timeslider-slider");
this.elements['button-left'] = root_element.find("#leftstep");
this.elements['button-right'] = root_element.find("#rightstep");
this.elements['button-play'] = root_element.find("#playpause_button");
this.elements['timestamp'] = root_element.find("#timer");
this.elements['revision-label'] = root_element.find("#revision_label");
this.elements['revision-date'] = root_element.find("#revision_date");
this.elements['authors'] = root_element.first("#authorsList");
},
loadSavedRevisions: function () {
for (var r in this.timeslider.savedRevisions) {
var rev = this.timeslider.savedRevisions[r];
this.attachHandle(new SliderSavedRevisionUI(this, rev));
};
},
render: function () {
for(var h in this.handles)
this.handles[h].render();
},
attachHandle: function (handle) {
this.handles.push(handle);
this.elements['slider'].append(handle.element);
return handle;
},
getTickSize: function () {
return (this.elements['slider-bar'].width()) / (this.timeslider.head_revision * 1.0);
},
goToRevision: function (revNum) {
//TODO: this should actually do an async jump to revision (with all the server fetching
//and changeset rendering that that implies), and perform the setPosition in a callback.
if (revNum <= 0 || revNum > this.timeslider.head_revision)
revNum = this.timeslider.latest_revision;
console.log("GO TO REVISION", revNum)
this.main_handle.setPosition(revNum);
},
}
);
function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
{ {
var BroadcastSlider; var BroadcastSlider;
(function() (function()
{ // wrap this code in its own namespace { // wrap this code in its own namespace
tsui = new SliderUI(tsclient, $("#timeslider-top"));
// if there was a revision specified in the 'location.hash', jump to it.
if (window.location.hash.length > 1) {
var rev = Number(window.location.hash.substr(1));
if(!isNaN(rev))
tsui.goToRevision(rev);
}
var sliderLength = 1000; var sliderLength = 1000;
var sliderPos = 0; var sliderPos = 0;
var sliderActive = false; var sliderActive = false;
var slidercallbacks = []; var slidercallbacks = [];
var savedRevisions = []; var savedRevisions = [];
var sliderPlaying = false; var sliderPlaying = false;
clientVars = _clientVars; clientVars = tsclient.clientVars;
function disableSelection(element) function disableSelection(element)
{ {
@ -64,9 +208,10 @@ function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
for (var i = 0; i < savedRevisions.length; i++) for (var i = 0; i < savedRevisions.length; i++)
{ {
var position = parseInt(savedRevisions[i].attr('pos')); var position = parseInt(savedRevisions[i].attr('pos'));
savedRevisions[i].css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1); //tsui._setElementPosition(savedRevisions[i], position);
} }
$("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)); //tsui._setElementPosition(tsui.elements['slider-handle'], sliderPos);
} }
var addSavedRevision = function(position, info) var addSavedRevision = function(position, info)
@ -76,7 +221,7 @@ function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
newSavedRevision.attr('pos', position); newSavedRevision.attr('pos', position);
newSavedRevision.css('position', 'absolute'); newSavedRevision.css('position', 'absolute');
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1); //tsui._setElementPosition(newSavedRevision, position);
$("#timeslider-slider").append(newSavedRevision); $("#timeslider-slider").append(newSavedRevision);
newSavedRevision.mouseup(function(evt) newSavedRevision.mouseup(function(evt)
{ {
@ -329,18 +474,20 @@ function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
}); });
$(window).resize(function() /*$(window).resize(function()
{ {
tsui.render();
updateSliderElements(); updateSliderElements();
}); });
*/
$("#ui-slider-bar").mousedown(function(evt) /*$("#ui-slider-bar").mousedown(function(evt)
{ {
setSliderPosition(Math.floor((evt.clientX - $("#ui-slider-bar").offset().left) * sliderLength / 742)); setSliderPosition(Math.floor((evt.clientX - $("#ui-slider-bar").offset().left) * sliderLength / 742));
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left)); $("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left));
$("#ui-slider-handle").trigger(evt); $("#ui-slider-handle").trigger(evt);
}); });
*/
// Slider dragging // Slider dragging
$("#ui-slider-handle").mousedown(function(evt) $("#ui-slider-handle").mousedown(function(evt)
{ {
@ -461,7 +608,7 @@ function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
$("#timeslider").show(); $("#timeslider").show();
var startPos = clientVars.collab_client_vars.rev; var startPos = clientVars.collab_client_vars.rev;
if(window.location.hash.length > 1) /*if(window.location.hash.length > 1)
{ {
var hashRev = Number(window.location.hash.substr(1)); var hashRev = Number(window.location.hash.substr(1));
if(!isNaN(hashRev)) if(!isNaN(hashRev))
@ -470,14 +617,15 @@ function loadBroadcastSliderJS(_clientVars, fireWhenAllScriptsAreLoaded)
setTimeout(function() { setSliderPosition(hashRev); }, 1); setTimeout(function() { setSliderPosition(hashRev); }, 1);
} }
} }
*/
setSliderLength(clientVars.collab_client_vars.rev); //setSliderLength(clientVars.collab_client_vars.rev);
setSliderPosition(clientVars.collab_client_vars.rev); //setSliderPosition(clientVars.collab_client_vars.rev);
/*
_.each(clientVars.savedRevisions, function(revision) _.eacheach(clientVars.savedRevisions, function(revision)
{ {
addSavedRevision(revision.revNum, revision); addSavedRevision(revision.revNum, revision);
}) })
*/
} }
}); });

View file

@ -174,6 +174,8 @@ AuthenticatedSocketClient("TimesliderClient",
handle_CLIENT_VARS: function(data, callback) { handle_CLIENT_VARS: function(data, callback) {
console.log("[timeslider_client] handle_CLIENT_VARS: ", data); console.log("[timeslider_client] handle_CLIENT_VARS: ", data);
this.clientVars = data; this.clientVars = data;
this.current_revision = this.head_revision = this.clientVars.collab_client_vars.rev;
this.savedRevisions = this.clientVars.savedRevisions;
}, },
handle_COLLABROOM: function(data, callback) { handle_COLLABROOM: function(data, callback) {
@ -222,7 +224,7 @@ function init(baseURL) {
var timesliderclient = new TimesliderClient(url, padId) var timesliderclient = new TimesliderClient(url, padId)
.on("CLIENT_VARS", function(data, context, callback) { .on("CLIENT_VARS", function(data, context, callback) {
//load all script that doesn't work without the clientVars //load all script that doesn't work without the clientVars
BroadcastSlider = require('./broadcast_slider').loadBroadcastSliderJS(this.clientVars,fireWhenAllScriptsAreLoaded); BroadcastSlider = require('./broadcast_slider').loadBroadcastSliderJS(this,fireWhenAllScriptsAreLoaded);
require('./broadcast_revisions').loadBroadcastRevisionsJS(this.clientVars); require('./broadcast_revisions').loadBroadcastRevisionsJS(this.clientVars);
changesetLoader = require('./broadcast').loadBroadcastJS(this, fireWhenAllScriptsAreLoaded, BroadcastSlider); changesetLoader = require('./broadcast').loadBroadcastJS(this, fireWhenAllScriptsAreLoaded, BroadcastSlider);

View file

@ -52,7 +52,7 @@
<div id="timeslider-top"> <div id="timeslider-top">
<% e.begin_block("timesliderTop"); %> <% e.begin_block("timesliderTop"); %>
<div id="timeslider-wrapper"> <div id="timeslider-wrapper">
<div id="timeslider" unselectable="on" style="display: none"> <div id="timeslider" unselectable="on"><!--style="display: none" -->
<div id="timeslider-left"></div> <div id="timeslider-left"></div>
<div id="timeslider-right"></div> <div id="timeslider-right"></div>
<div id="timer"></div> <div id="timer"></div>
@ -68,7 +68,6 @@
<div class="stepper" id="rightstep"></div> <div class="stepper" id="rightstep"></div>
</div> </div>
</div> </div>
<div id="overlay"> <div id="overlay">
<div id="overlay-inner"> <div id="overlay-inner">
<!-- --> <!-- -->
@ -90,7 +89,7 @@
<% e.end_block(); %> <% e.end_block(); %>
</div> </div>
<div> <div id="timeslider-metadata">
<h1> <h1>
<span id="revision_label"></span> <span id="revision_label"></span>
<span id="revision_date"></span> <span id="revision_date"></span>
@ -207,14 +206,13 @@
<!-- Bootstrap --> <!-- Bootstrap -->
<script type="text/javascript" > <script type="text/javascript" >
var clientVars = {}; var clientVars = {};
var BroadcastSlider; var BroadcastSlider;
(function () { (function () {
var pathComponents = location.pathname.split('/'); var pathComponents = location.pathname.split('/');
// Strip 'p', the padname and 'timeslider' from the pathname and set as baseURL // Strip 'p', the padname and 'timeslider' from the pathname and set as baseURL
var baseURL = pathComponents.slice(0,pathComponents.length-3).join('/') + '/'; var baseURL = pathComponents.slice(0,pathComponents.length-3).join('/') + '/';
require.setRootURI(baseURL + "javascripts/src"); require.setRootURI(baseURL + "javascripts/src");
require.setLibraryURI(baseURL + "javascripts/lib"); require.setLibraryURI(baseURL + "javascripts/lib");
require.setGlobalKeyPath("require"); require.setGlobalKeyPath("require");
@ -224,13 +222,12 @@
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) { if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet document.domain = document.domain; // for comet
} }
var plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins');
var timeslider = require('ep_etherpad-lite/static/js/timeslider') var timeslider = require('ep_etherpad-lite/static/js/timeslider')
var socket = timeslider.socket; var socket = timeslider.socket;
BroadcastSlider = timeslider.BroadcastSlider; BroadcastSlider = timeslider.BroadcastSlider;
plugins.baseURL = baseURL; plugins.baseURL = baseURL;
plugins.update(function () { plugins.update(function () {
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
hooks.plugins = plugins; hooks.plugins = plugins;