Skip to content

Commit

Permalink
WIP: integrating writer.
Browse files Browse the repository at this point in the history
  • Loading branch information
obuchtala committed Aug 2, 2015
1 parent 931aa55 commit 4eda177
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 184 deletions.
177 changes: 93 additions & 84 deletions ui/scrollbar.js
Original file line number Diff line number Diff line change
@@ -1,98 +1,96 @@
"use strict";

var $$ = React.createElement;
var _ = require("substance/helpers");
var _ = require('../basics/helpers');
var Component = require('./component');
var $$ = Component.$$;

// A rich scrollbar implementation that supports highlights
// ----------------

var THUMB_MIN_HEIGHT = 7;

var Scrollbar = React.createClass({
displayName: "Scrollbar",
class Scrollbar extends Component {

getInitialState: function() {
constructor(parent, props) {
super(parent, props);

this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
}

getInitialState() {
return {
thumb: {top: 0, height: 20}, // just render at the top
highlights: [] // no highlights until state derived
};
},
}

componentDidMount: function() {
didMount() {
// HACK global window object!
$(window).mousemove(this.mouseMove);
$(window).mouseup(this.mouseUp);
},

mouseDown: function(e) {
this._mouseDown = true;
var scrollBarOffset = $(React.findDOMNode(this)).offset().top;
var y = e.pageY - scrollBarOffset;
var thumbEl = this.refs.thumb.getDOMNode();

if (e.target !== thumbEl) {
// Jump to mousedown position
this.offset = $(thumbEl).height()/2;
this.mouseMove(e);
} else {
this.offset = y - $(thumbEl).position().top;
}
return false;
},

// Handle Mouse Up
// -----------------
//
// Mouse lifted, no scroll anymore

mouseUp: function() {
this._mouseDown = false;
},
// TODO: why is this done?
$(window).on('mousemove', this.mouseMove);
$(window).on('mouseup', this.mouseUp);
this.$el.on('mousedown', this.onMouseDown);
}

// Handle Scroll
// -----------------
//
// Handle scroll event
// .visible-area handle
willUnmount() {
$(window).off('mousemove', this.mouseMove);
$(window).off('mouseup', this.mouseUp);
this.$el.off('mousedown', this.onMouseDown);
}

mouseMove: function(e) {
if (this._mouseDown) {
var scrollBarOffset = $(React.findDOMNode(this)).offset().top;
var y = e.pageY - scrollBarOffset;
get classNames() {
return 'scrollbar-component';
}

// find offset to visible-area.top
var scroll = (y-this.offset)*this.factor;
this.scrollTop = $(this.panelContentEl).scrollTop(scroll);
}
},
render() {
var highlightEls = this.state.highlights.map(function(h) {
return $$('div', {
classNames: 'highlight',
key: h.id,
style: {
top: h.top,
height: h.height
}
});
});
var thumbEl = $$('div', {
ref: "thumb",
classNames: "thumb",
style: {
top: this.state.thumb.top,
height: Math.max(this.state.thumb.height, THUMB_MIN_HEIGHT)
}
});
return $$("div", {classNames: " "+this.props.contextId, onMouseDown: },
thumbEl,
$$('div', {classNames: 'highlights'},
highlightEls
)
);
}

update: function(panelContentEl, panel) {
update(panelContentEl, panel) {
var self = this;

this.panelContentEl = panelContentEl;

var contentHeight = panel.getContentHeight();
var panelHeight = panel.getPanelHeight();
var scrollTop = panel.getScrollPosition();

// Needed for scrollbar interaction
this.factor = (contentHeight / panelHeight);

var highlights = [];
// Compute highlights
this.props.highlights().forEach(function(nodeId) {
var nodeEl = $(self.panelContentEl).find('*[data-id='+nodeId+']');
if (!nodeEl.length) return;

var top = nodeEl.position().top / self.factor;
var height = nodeEl.outerHeight(true) / self.factor;

// HACK: make all highlights at least 3 pxls high, and centered around the desired top pos
if (height < Scrollbar.overlayMinHeight) {
height = Scrollbar.overlayMinHeight;
top = top - 0.5 * Scrollbar.overlayMinHeight;
}

var data = {
id: nodeId,
top: top,
Expand All @@ -110,38 +108,49 @@ var Scrollbar = React.createClass({
thumb: thumbProps,
highlights: highlights
});
},
}

render: function() {
var highlightEls = this.state.highlights.map(function(h) {
onMouseDown(e) {
e.stopPropagation();
e.preventDefault();
this._mouseDown = true;
var scrollBarOffset = $(React.findDOMNode(this)).offset().top;
var y = e.pageY - scrollBarOffset;
var thumbEl = this.refs.thumb.getDOMNode();
if (e.target !== thumbEl) {
// Jump to mousedown position
this.offset = $(thumbEl).height()/2;
this.mouseMove(e);
} else {
this.offset = y - $(thumbEl).position().top;
}
}

return $$('div', {
className: 'highlight',
key: h.id,
style: {
top: h.top,
height: h.height
}
});
});
// Handle Mouse Up
// -----------------
//
// Mouse lifted, nothis.panelContentEl scroll anymore

var thumbEl = $$('div', {
ref: "thumb",
className: "thumb",
style: {
top: this.state.thumb.top,
height: Math.max(this.state.thumb.height, THUMB_MIN_HEIGHT)
}
});
onMouseUp() {
this._mouseDown = false;
}

return $$("div", {className: "scrollbar-component "+this.props.contextId, onMouseDown: this.mouseDown},
thumbEl,
$$('div', {className: 'highlights'},
highlightEls
)
);
// Handle Scroll
// -----------------
//
// Handle scroll event
// .visible-area handle

onMouseMove(e) {
if (this._mouseDown) {
var scrollBarOffset = this.$el.offset().top;
var y = e.pageY - scrollBarOffset;
// find offset to visible-area.top
var scroll = (y-this.offset)*this.factor;
this.scrollTop = $(this.panelContentEl).scrollTop(scroll);
}
}
});
}

Scrollbar.overlayMinHeight = 5

Expand Down
Loading

0 comments on commit 4eda177

Please sign in to comment.