Add vertical scroll bar

This commit is contained in:
Fabian Jakobs 2010-04-20 16:48:08 +02:00
commit 9b562231a4
6 changed files with 95 additions and 18 deletions

View file

@ -15,6 +15,19 @@
overflow-y: hidden;
}
.editor .scrollbar {
position: absolute;
overflow-x: hidden;
overflow-y: scroll;
right: 0;
}
.editor .scrollbar div {
position: absolute;
width: 1px;
left: -10px;
}
.layer {
position: absolute;
overflow: hidden;

View file

@ -56,6 +56,7 @@
<script src="../src/layer/Gutter.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/layer/Text.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/layer/Marker.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ScrollBar.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/TextInput.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/KeyBinding.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/Editor.js" type="text/javascript" charset="utf-8"></script>

View file

@ -7,11 +7,17 @@ ace.Editor = function(renderer, doc) {
this.textInput = new ace.TextInput(container, this);
new ace.KeyBinding(container, this);
var self = this;
ace.addListener(container, "mousedown", function(e) {
self.focus();
return ace.stopEvent(e);
});
ace.addListener(container, "mousedown", ace.bind(this.onMouseDown, this));
ace.addListener(container, "dblclick", ace.bind(this.onMouseDoubleClick, this));
ace.addTripleClickListener(container, ace.bind(this.onMouseTripleClick, this));
ace.addMouseWheelListener(container, ace.bind(this.onMouseWheel, this));
var mouseTarget = renderer.getMouseEventTarget();
ace.addListener(mouseTarget, "mousedown", ace.bind(this.onMouseDown, this));
ace.addListener(mouseTarget, "dblclick", ace.bind(this.onMouseDoubleClick, this));
ace.addTripleClickListener(mouseTarget, ace.bind(this.onMouseTripleClick, this));
ace.addMouseWheelListener(mouseTarget, ace.bind(this.onMouseWheel, this));
this._selectionMarker = null;
this._highlightLineMarker = null;
@ -196,8 +202,6 @@ ace.Editor.prototype.onDocumentModeChange = function() {
ace.Editor.prototype.onMouseDown = function(e) {
this.focus();
var pageX = ace.getDocumentX(e);
var pageY = ace.getDocumentY(e);

40
src/ScrollBar.js Normal file
View file

@ -0,0 +1,40 @@
ace.provide("ace.ScrollBar");
ace.ScrollBar = function(parent) {
this.$initEvents();
this.element = document.createElement("div");
this.element.className = "scrollbar";
this.inner = document.createElement("div");
this.element.appendChild(this.inner);
parent.appendChild(this.element);
this.width = ace.scrollbarWidth();
this.element.style.width = this.width;
ace.addListener(this.element, "scroll", ace.bind(this.onScroll, this));
};
ace.mixin(ace.ScrollBar.prototype, ace.MEventEmitter);
ace.ScrollBar.prototype.onScroll = function() {
this.$dispatchEvent("scroll", {data: this.element.scrollTop});
};
ace.ScrollBar.prototype.getWidth = function() {
return this.width;
};
ace.ScrollBar.prototype.setHeight = function(height) {
this.element.style.height = (height - this.width) + "px";
};
ace.ScrollBar.prototype.setInnerHeight = function(height) {
this.inner.style.height = height + "px";
};
ace.ScrollBar.prototype.setScrollTop = function(scrollTop) {
this.element.scrollTop = scrollTop;
};

View file

@ -25,6 +25,9 @@ ace.VirtualRenderer = function(container) {
this.layers = [ this.markerLayer, textLayer, this.cursorLayer ];
this.scrollBar = new ace.ScrollBar(container);
this.scrollBar.addEventListener("scroll", ace.bind(this.onScroll, this));
this.scrollTop = 0;
this.cursorPos = {
@ -50,6 +53,10 @@ ace.VirtualRenderer.prototype.getContainerElement = function() {
return this.container;
};
ace.VirtualRenderer.prototype.getMouseEventTarget = function() {
return this.scroller;
};
ace.VirtualRenderer.prototype.getFirstVisibleRow = function() {
return this.layerConfig.firstRow || 0;
};
@ -63,24 +70,36 @@ ace.VirtualRenderer.prototype.onResize = function()
var height = ace.getInnerHeight(this.container);
this.gutter.style.height = height + "px";
this.scroller.style.height = height + "px";
this.scrollBar.setHeight(height);
var width = ace.getInnerWidth(this.container);
var gutterWidth = this.gutter.offsetWidth;
this.scroller.style.left = gutterWidth + "px";
this.scroller.style.width = Math.max(0, width - gutterWidth) + "px";
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
if (this.doc) {
this._updateScrollBar();
this.scrollToY(this.getScrollTop());
this.draw();
}
};
ace.VirtualRenderer.prototype.onScroll = function(e) {
this.scrollToY(e.data);
};
ace.VirtualRenderer.prototype._updateScrollBar = function() {
this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight);
this.scrollBar.setScrollTop(this.scrollTop);
};
ace.VirtualRenderer.prototype.updateLines = function(firstRow, lastRow) {
var layerConfig = this.layerConfig;
if (firstRow > layerConfig.lastRow + 1) { return; }
if (lastRow < layerConfig.firstRow) { return; }
// if the last row is unknow -> redraw everything
// if the last row is unknown -> redraw everything
if (lastRow === undefined) {
this.draw();
return;
@ -96,9 +115,7 @@ ace.VirtualRenderer.prototype.draw = function() {
var offset = this.scrollTop % this.lineHeight;
var minHeight = this.scroller.clientHeight + offset;
var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc
.getWidth()
* this.characterWidth));
var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc.getWidth() * this.characterWidth));
var lineCount = Math.ceil(minHeight / this.lineHeight);
var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight);
@ -121,12 +138,13 @@ ace.VirtualRenderer.prototype.draw = function() {
style.width = longestLine + "px";
layer.update(layerConfig);
}
;
};
this.gutterLayer.element.style.marginTop = (-offset) + "px";
this.gutterLayer.element.style.height = minHeight + "px";
this.gutterLayer.update(layerConfig);
this._updateScrollBar();
};
ace.VirtualRenderer.prototype.addMarker = function(range, clazz, type) {
@ -191,6 +209,7 @@ ace.VirtualRenderer.prototype.scrollToY = function(scrollTop) {
if (this.scrollTop !== scrollTop) {
this.scrollTop = scrollTop;
this._updateScrollBar();
this.draw();
}
};

View file

@ -97,20 +97,20 @@ ace.computedStyle = function(element, style) {
}
};
ace.scrollbarHeight = function() {
ace.scrollbarWidth = function(parent) {
var el = document.createElement("div");
var style = el.style;
style.position = "absolute";
style.left = "-10000px";
style.overflow = "scroll";
style.height = "100px";
style.width = "100px";
document.body.appendChild(el);
var height = el.offsetHeight - el.clientHeight;
(parent || document.body).appendChild(el);
var width = el.offsetWidth - el.clientWidth;
document.body.removeChild(el);
return height;
return width;
};
ace.stringReverse = function(string) {