// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.collide.client.editor.renderer;
import com.google.collide.shared.document.Line;
import com.google.collide.shared.document.anchor.Anchor;
/**
* Implements a {@link LineRenderer} that wraps a given area in the document
* with an element with the given class name.
*/
public abstract class SingleChunkLineRenderer implements LineRenderer {
/**
* Creates a new renderer using line/column numbers (prone to collaboration
* issues).
*
* @param startLine the first line to render
* @param startColumn the first column to render
* @param endLine the last line to render (inclusive)
* @param endColumn the last column to render (inclusive)
* @param className the CSS class to apply
*/
public static SingleChunkLineRenderer create(final int startLine, final int startColumn,
final int endLine, final int endColumn, String className) {
return new SingleChunkLineRenderer(className) {
@Override
public int startLine() {
return startLine;
}
@Override
public int startColumn() {
return startColumn;
}
@Override
public int endLine() {
return endLine;
}
@Override
public int endColumn() {
return endColumn;
}
};
}
/**
* Creates a new renderer using anchors.
*
* @param startAnchor the rendering start point.
* @param endAnchor the last part to render (note that whatever line or
* character the anchor is at will also be rendered.
* @param className the CSS class name to apply
*/
public static SingleChunkLineRenderer create(final Anchor startAnchor, final Anchor endAnchor,
String className) {
return new SingleChunkLineRenderer(className) {
@Override
public int startLine() {
return startAnchor.getLineNumber();
}
@Override
public int startColumn() {
return startAnchor.getColumn();
}
@Override
public int endLine() {
return endAnchor.getLineNumber();
}
@Override
public int endColumn() {
return endAnchor.getColumn();
}
};
}
private final String className;
private int currentLineNumber;
private int currentLineLength;
private int linePosition;
private SingleChunkLineRenderer(String className) {
this.className = className;
}
public abstract int startLine();
public abstract int startColumn();
public abstract int endLine();
public abstract int endColumn();
@Override
public void renderNextChunk(Target target) {
if (currentLineNumber < startLine() || currentLineNumber > endLine()) {
// Out of the chunk to be rendered.
render(target, currentLineLength - linePosition, null);
} else if (currentLineNumber == startLine() && linePosition < startColumn()) {
// Still out of the chunk to be rendered.
render(target, startColumn() - linePosition, null);
} else if (currentLineNumber == endLine() && linePosition > endColumn()) {
// Right after the chunk was rendered.
render(target, currentLineLength - linePosition, null);
} else if (currentLineNumber == endLine()) {
// Chunk ends at the current line.
render(target, endColumn() + 1 - linePosition, className);
} else {
// The rest of the line belongs to the chunk.
render(target, currentLineLength - linePosition, className);
}
}
private void render(LineRenderer.Target target, int characterCount, String styleName) {
target.render(characterCount, styleName);
linePosition += characterCount;
}
@Override
public boolean resetToBeginningOfLine(Line line, int lineNumber) {
if (lineNumber < startLine() || lineNumber > endLine()) {
return false;
}
this.currentLineNumber = lineNumber;
this.currentLineLength = line.getText().length();
this.linePosition = 0;
return true;
}
@Override
public boolean shouldLastChunkFillToRight() {
return false;
}
}