mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-27 10:56:16 -04:00
Working slider with mouse and events
Working slider class with mouse handling (click, drag) and events (change, slide). Lots of console logs still in the code. Got rid of some of the legacy code.
This commit is contained in:
parent
012cd184db
commit
57ed44ff75
3 changed files with 164 additions and 174 deletions
|
@ -5,22 +5,26 @@
|
|||
position: absolute;
|
||||
}
|
||||
|
||||
#timeslider .star {
|
||||
background-image: url(../../static/img/star.png);
|
||||
cursor: pointer;
|
||||
height: 16px;
|
||||
top: 40px;
|
||||
width: 15px;
|
||||
}
|
||||
#timeslider .handle {
|
||||
.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;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ui-slider-handle-star {
|
||||
background-image: url(../../static/img/star.png);
|
||||
height: 16px;
|
||||
top: 20px;
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.ui-slider-handle-handle {
|
||||
background-image: url(../../static/img/crushed_current_location.png);
|
||||
height: 61px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
top: -14px;
|
||||
width: 13px;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,53 +42,151 @@ $.Class("SliderHandleUI",
|
|||
* @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);
|
||||
init: function (slider, value, type) {
|
||||
console.log("New SliderHandle(%d, %s)", value, type);
|
||||
this.slider = slider;
|
||||
this.position = position;
|
||||
this.events = {};
|
||||
this.value = value;
|
||||
//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);
|
||||
this.element = $("<div class='ui-slider-handle'></div>");
|
||||
if (type === "")
|
||||
type = "handle";
|
||||
this.element.addClass("ui-slider-handle-" + type);
|
||||
this._mouseInit();
|
||||
},
|
||||
on: function (eventname, callback, context) {
|
||||
if (!(eventname in this.events))
|
||||
this.events[eventname] = [];
|
||||
this.events[eventname].push({handler:callback, context: context});
|
||||
_mouseInit: function () {
|
||||
this.element.on("mousedown.sliderhandle", null, this, function(event) {
|
||||
console.log("sliderhandleui - mousedown")
|
||||
})
|
||||
},
|
||||
_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
|
||||
{//statics
|
||||
},
|
||||
{//instance
|
||||
init: function(slider, revision) {
|
||||
this._super(slider, revision.revNum, 'star');
|
||||
this.revision = revision;
|
||||
},
|
||||
{//instance
|
||||
init: function(slider, revision) {
|
||||
this._super(slider, revision.revNum, 'star');
|
||||
this.revision = revision;
|
||||
},
|
||||
}
|
||||
_mouseInit: function () {
|
||||
this.element.on("mousedown.sliderhandle", null, this, function(event) {
|
||||
console.log("SliderSavedRevisionUI - mousedown")
|
||||
})
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
//TODO:
|
||||
// - window resizing is currently broken!
|
||||
// - keyboard events
|
||||
$.Class("SliderUI",
|
||||
{//statics
|
||||
defaults: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
}
|
||||
},
|
||||
{//instance
|
||||
init: function (element, options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.element = element;
|
||||
this.current_value = "value" in this.options ? this.options.value : 0;
|
||||
this.handles = [];
|
||||
this.attachHandle(new SliderHandleUI(this, this._current_value, 'handle'));
|
||||
this._mouseInit();
|
||||
|
||||
// handle window resize
|
||||
var _this = this;
|
||||
$(window).resize(function() {
|
||||
_this.render();
|
||||
});
|
||||
},
|
||||
_getStep: function () {
|
||||
return (this.element.width()) / (this.options.max * 1.0);
|
||||
},
|
||||
render: function () {
|
||||
for(var h in this.handles) {
|
||||
handle = this.handles[h];
|
||||
handle.element.css('left', (handle.value * this._getStep()) );
|
||||
}
|
||||
},
|
||||
// this internal version of _setValue should only be used to render
|
||||
// when the handle changes position as a result of UI events handled
|
||||
// by this slider.
|
||||
_setValue: function (value) {
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > this.options.max)
|
||||
value = this.options.max;
|
||||
this.handles[0].value = value;
|
||||
this.current_value = value;
|
||||
this.render();
|
||||
},
|
||||
// this 'public' version of _setValue also triggers a change event
|
||||
setValue: function(value) {
|
||||
this._setValue(value);
|
||||
this._trigger("change", value);
|
||||
},
|
||||
setMax: function (max) {
|
||||
this.options.max = max;
|
||||
this.render();
|
||||
},
|
||||
attachHandle: function (handle) {
|
||||
this.handles.push(handle);
|
||||
this.element.append(handle.element);
|
||||
this.current_value = this.handles[0].value;
|
||||
return handle;
|
||||
},
|
||||
_trigger: function (eventname, value) {
|
||||
//TODO: implement trigger
|
||||
console.log("triggering event: ", eventname);
|
||||
if (eventname in this.options) {
|
||||
this.options[eventname](value);
|
||||
}
|
||||
},
|
||||
_mouseInit: function () {
|
||||
// handle all mouse events for the slider and handles right here
|
||||
var _this = this;
|
||||
this.element.on("mousedown.slider", function (event) {
|
||||
if (event.target == _this.element[0] || $(event.target).hasClass("ui-slider-handle")) {
|
||||
// the click is on the slider bar itself.
|
||||
var start_value = Math.floor((event.clientX-_this.element.offset().left) / _this._getStep());
|
||||
console.log("sliderbar mousedown, value:", start_value);
|
||||
if (_this.current_value != start_value)
|
||||
_this._setValue(start_value);
|
||||
|
||||
$(document).on("mousemove.slider", function (event) {
|
||||
var current_value = Math.floor((event.clientX-_this.element.offset().left) / _this._getStep());
|
||||
console.log("sliderbar mousemove, value:", current_value);
|
||||
// don't change the value if it hasn't actually changed!
|
||||
if (_this.current_value != current_value) {
|
||||
_this._setValue(current_value);
|
||||
_this._trigger("slide", current_value);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("mouseup.slider", function (event) {
|
||||
// make sure to get rid of the handlers on document,
|
||||
// we don't need them after this 'slide' session is done.
|
||||
$(document).off("mouseup.slider mousemove.slider");
|
||||
var end_value = Math.floor((event.clientX-_this.element.offset().left) / _this._getStep());
|
||||
console.log("sliderbar mouseup, value:", end_value);
|
||||
// always change the value at mouseup
|
||||
_this._setValue(end_value);
|
||||
_this._trigger("change", end_value);
|
||||
|
||||
});
|
||||
} else {
|
||||
console.log("We shouldn't be here!")
|
||||
console.log(event.target);
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
$.Class("RevisionSlider",
|
||||
{//statics
|
||||
},
|
||||
{//instance
|
||||
|
@ -98,22 +196,20 @@ $.Class("SliderUI",
|
|||
// 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'));
|
||||
|
||||
var _this = this;
|
||||
this.slider = new SliderUI(this.elements['slider-bar'],
|
||||
options = {
|
||||
max: this.timeslider.head_revision,
|
||||
change: function () { _this.onChange.apply(_this, arguments); },
|
||||
slide: function () { _this.onSlide.apply(_this, arguments); },
|
||||
});
|
||||
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);
|
||||
});
|
||||
},
|
||||
onChange: function (value) {
|
||||
console.log("in change handler:", value);
|
||||
},
|
||||
onSlide: function (value) {
|
||||
console.log("in slide handler:", value);
|
||||
},
|
||||
loadElements: function (root_element) {
|
||||
this.elements['root'] = root_element;
|
||||
|
@ -131,28 +227,16 @@ $.Class("SliderUI",
|
|||
loadSavedRevisions: function () {
|
||||
for (var r in this.timeslider.savedRevisions) {
|
||||
var rev = this.timeslider.savedRevisions[r];
|
||||
this.attachHandle(new SliderSavedRevisionUI(this, rev));
|
||||
this.slider.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);
|
||||
this.slider.setValue(revNum);
|
||||
},
|
||||
|
||||
|
||||
|
@ -166,7 +250,7 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
(function()
|
||||
{ // wrap this code in its own namespace
|
||||
|
||||
tsui = new SliderUI(tsclient, $("#timeslider-top"));
|
||||
tsui = new RevisionSlider(tsclient, $("#timeslider-top"));
|
||||
|
||||
// if there was a revision specified in the 'location.hash', jump to it.
|
||||
if (window.location.hash.length > 1) {
|
||||
|
@ -202,34 +286,6 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
slidercallbacks[i](newval);
|
||||
}
|
||||
}
|
||||
|
||||
var updateSliderElements = function()
|
||||
{
|
||||
for (var i = 0; i < savedRevisions.length; i++)
|
||||
{
|
||||
var position = parseInt(savedRevisions[i].attr('pos'));
|
||||
//tsui._setElementPosition(savedRevisions[i], position);
|
||||
}
|
||||
//tsui._setElementPosition(tsui.elements['slider-handle'], sliderPos);
|
||||
|
||||
}
|
||||
|
||||
var addSavedRevision = function(position, info)
|
||||
{
|
||||
var newSavedRevision = $('<div></div>');
|
||||
newSavedRevision.addClass("star");
|
||||
|
||||
newSavedRevision.attr('pos', position);
|
||||
newSavedRevision.css('position', 'absolute');
|
||||
//tsui._setElementPosition(newSavedRevision, position);
|
||||
$("#timeslider-slider").append(newSavedRevision);
|
||||
newSavedRevision.mouseup(function(evt)
|
||||
{
|
||||
BroadcastSlider.setSliderPosition(position);
|
||||
});
|
||||
savedRevisions.push(newSavedRevision);
|
||||
};
|
||||
|
||||
var removeSavedRevision = function(position)
|
||||
{
|
||||
var element = $("div.star [pos=" + position + "]");
|
||||
|
@ -310,6 +366,7 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
padmodals.showModal("disconnected");
|
||||
}
|
||||
|
||||
//TODO: figure out what the hell this is for
|
||||
var fixPadHeight = _.throttle(function(){
|
||||
var height = $('#timeslider-top').height();
|
||||
$('#editorcontainerbox').css({marginTop: height});
|
||||
|
@ -385,7 +442,6 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
return sliderActive;
|
||||
},
|
||||
playpause: playpause,
|
||||
addSavedRevision: addSavedRevision,
|
||||
showReconnectUI: showReconnectUI,
|
||||
setAuthors: setAuthors
|
||||
}
|
||||
|
@ -474,55 +530,6 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
|
||||
});
|
||||
|
||||
/*$(window).resize(function()
|
||||
{
|
||||
tsui.render();
|
||||
updateSliderElements();
|
||||
});
|
||||
*/
|
||||
|
||||
/*$("#ui-slider-bar").mousedown(function(evt)
|
||||
{
|
||||
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").trigger(evt);
|
||||
});
|
||||
*/
|
||||
// Slider dragging
|
||||
$("#ui-slider-handle").mousedown(function(evt)
|
||||
{
|
||||
this.startLoc = evt.clientX;
|
||||
this.currentLoc = parseInt($(this).css('left'));
|
||||
var self = this;
|
||||
sliderActive = true;
|
||||
$(document).mousemove(function(evt2)
|
||||
{
|
||||
$(self).css('pointer', 'move')
|
||||
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
|
||||
if (newloc < 0) newloc = 0;
|
||||
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
|
||||
$("#revision_label").html(html10n.get("timeslider.version", { "version": Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))}));
|
||||
$(self).css('left', newloc);
|
||||
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
|
||||
});
|
||||
$(document).mouseup(function(evt2)
|
||||
{
|
||||
$(document).unbind('mousemove');
|
||||
$(document).unbind('mouseup');
|
||||
sliderActive = false;
|
||||
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
|
||||
if (newloc < 0) newloc = 0;
|
||||
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
|
||||
$(self).css('left', newloc);
|
||||
// if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2)))
|
||||
setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
|
||||
if(parseInt($(self).css('left')) < 2){
|
||||
$(self).css('left', '2px');
|
||||
}else{
|
||||
self.currentLoc = parseInt($(self).css('left'));
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// play/pause toggling
|
||||
$("#playpause_button").mousedown(function(evt)
|
||||
|
@ -607,26 +614,6 @@ function loadBroadcastSliderJS(tsclient, fireWhenAllScriptsAreLoaded)
|
|||
{
|
||||
$("#timeslider").show();
|
||||
|
||||
var startPos = clientVars.collab_client_vars.rev;
|
||||
/*if(window.location.hash.length > 1)
|
||||
{
|
||||
var hashRev = Number(window.location.hash.substr(1));
|
||||
if(!isNaN(hashRev))
|
||||
{
|
||||
// this is necessary because of the socket.io-event which loads the changesets
|
||||
setTimeout(function() { setSliderPosition(hashRev); }, 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
//setSliderLength(clientVars.collab_client_vars.rev);
|
||||
//setSliderPosition(clientVars.collab_client_vars.rev);
|
||||
/*
|
||||
_.eacheach(clientVars.savedRevisions, function(revision)
|
||||
{
|
||||
addSavedRevision(revision.revNum, revision);
|
||||
})
|
||||
*/
|
||||
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
<div id="timeslider-right"></div>
|
||||
<div id="timer"></div>
|
||||
<div id="timeslider-slider">
|
||||
<div id="ui-slider-handle"></div>
|
||||
<div id="ui-slider-bar"></div>
|
||||
</div>
|
||||
<div id="playpause_button">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue