Add free text wrapping with constraints

This commit is contained in:
Joe Cheng 2011-02-10 20:11:28 +08:00 committed by Fabian Jakobs
commit c2cd67105d
5 changed files with 75 additions and 6 deletions

View file

@ -228,6 +228,11 @@ exports.launch = function(env) {
session.setWrapLimit(80);
renderer.setPrintMarginColumn(80);
break;
case "free":
session.setUseWrapMode(true);
session.setWrapLimitRange(null, null);
renderer.setPrintMarginColumn(80);
break;
}
});

View file

@ -97,6 +97,7 @@
<option value="off">Off</option>
<option value="40">40 Chars</option>
<option value="80">80 Chars</option>
<option value="free">Free</option>
</select>
</td>
<td align="right">

View file

@ -642,6 +642,10 @@ var EditSession = function(text, mode) {
// WRAPMODE
this.$wrapLimit = 80;
this.$useWrapMode = false;
this.$wrapLimitRange = {
min : null,
max : null
};
this.setUseWrapMode = function(useWrapMode) {
if (useWrapMode != this.$useWrapMode) {
@ -667,20 +671,64 @@ var EditSession = function(text, mode) {
};
this.setWrapLimit = function(wrapLimit) {
if (wrapLimit != this.$wrapLimit) {
this.$wrapLimit = wrapLimit;
this.setWrapLimitRange(wrapLimit, wrapLimit);
};
// Allow the wrap limit to move freely between min and max. Either
// parameter can be null to allow the wrap limit to be unconstrained
// in that direction. Or set both parameters to the same number to pin
// the limit to that value.
this.setWrapLimitRange = function(min, max) {
if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
this.$wrapLimitRange.min = min;
this.$wrapLimitRange.max = max;
this.$modified = true;
if (this.$useWrapMode) {
this.$updateWrapData(0, this.getLength() - 1);
}
// This will force a recalculation of the wrap limit
this._dispatchEvent("changeWrapMode");
}
};
// This should generally only be called by the renderer when a resize
// is detected.
this.adjustWrapLimit = function(desiredLimit) {
var wrapLimit = this.$constrainWrapLimit(desiredLimit);
if (wrapLimit != this.$wrapLimit && wrapLimit > 0) {
this.$wrapLimit = wrapLimit;
this.$modified = true;
if (this.$useWrapMode) {
this.$updateWrapData(0, this.getLength() - 1);
this._dispatchEvent("changeWrapLimit");
}
return true;
}
return false;
};
this.$constrainWrapLimit = function(wrapLimit) {
var min = this.$wrapLimitRange.min;
if (min)
wrapLimit = Math.max(min, wrapLimit);
var max = this.$wrapLimitRange.max;
if (max)
wrapLimit = Math.min(max, wrapLimit);
// What would a limit of 0 even mean?
return Math.max(1, wrapLimit);
};
this.getWrapLimit = function() {
return this.$wrapLimit;
};
this.getWrapLimitRange = function() {
// Avoid unexpected mutation by returning a copy
return {
min : this.$wrapLimitRange.min,
max : this.$wrapLimitRange.max
};
};
this.$updateWrapDataOnChange = function(e) {
if (!this.$useWrapMode) {
return;

View file

@ -126,6 +126,7 @@ var Editor =function(renderer, session) {
this.session.removeEventListener("change", this.$onDocumentChange);
this.session.removeEventListener("changeMode", this.$onDocumentModeChange);
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
this.session.removeEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
@ -149,6 +150,9 @@ var Editor =function(renderer, session) {
this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer);
session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
this.$onDocumentChangeWrapLimit = this.onDocumentChangeWrapLimit.bind(this);
session.addEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
this.$onDocumentChangeWrapMode = this.onDocumentChangeWrapMode.bind(this);
session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
@ -348,11 +352,15 @@ var Editor =function(renderer, session) {
this.renderer.setTokenizer(this.bgTokenizer);
};
this.onDocumentChangeWrapMode = function() {
this.onDocumentChangeWrapLimit = function() {
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
this.renderer.updateFull();
};
this.onDocumentChangeWrapMode = function() {
this.renderer.onResize(true);
};
this.getCopyText = function() {
if (!this.selection.isEmpty()) {
return this.session.getTextRange(this.getSelectionRange());

View file

@ -210,6 +210,13 @@ var VirtualRenderer = function(container, theme) {
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
this.scroller.style.left = gutterWidth + "px";
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
if (this.session.getUseWrapMode()) {
var limit = Math.floor(this.scroller.clientWidth / this.characterWidth);
if (this.session.adjustWrapLimit(limit) || force) {
changes = changes | this.CHANGE_FULL;
}
}
}
this.$size.scrollerWidth = this.scroller.clientWidth;