... | @@ -328,7 +328,7 @@ This subsection serves the purpose of elaborating the data which are stored insi |
... | @@ -328,7 +328,7 @@ This subsection serves the purpose of elaborating the data which are stored insi |
|
|
|
|
|
## Implementing the Line Wrap
|
|
## Implementing the Line Wrap
|
|
|
|
|
|
We stopped at the discussion of the method ```determineWrappedLines(...)``` which does calculate the lines of our editor. This method produces all lines, no matter if we have an activated wrap or not. Let us check the code
|
|
We stopped at the discussion of the method ```determineWrappedLines(...)``` which does calculate the lines of our editor. This method produces all lines, no matter if we have an activated wrap or not. The idea behind this method is to separate the document at every newline character ````\n```. Then measure the resulting text snippet. If the snippet exceeds the width of the visible area of the widget, we need to wrap this line, else we can just create a new EditorLine. Obviously, if wrap is not active, we can always create the line without wrapping it. Let us check the code
|
|
|
|
|
|
```java
|
|
```java
|
|
private void determineWrappedLines(int widgetWidth, GC gc, int height) {
|
|
private void determineWrappedLines(int widgetWidth, GC gc, int height) {
|
... | @@ -380,5 +380,66 @@ We stopped at the discussion of the method ```determineWrappedLines(...)``` whic |
... | @@ -380,5 +380,66 @@ We stopped at the discussion of the method ```determineWrappedLines(...)``` whic |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
The idea behind this method is to separate the document at every newline character ````\n```. Then measure the resulting text snippet. If the snippet exceeds the width of the visible area of the widget, we need to wrap this line, else we can just create a new EditorLine. Obviously, if wrap is not active, we can always create the line without wrapping it.
|
|
What is left is the method that does the actual wrapping, so far we would only get lines that are not wrapped. This is delegated to the method ```wrapLine(...)```. What this method does, is to iterate through all ```Character``` of the input string until a whitespace character is found. We do not wrap a line while a word is not finished, instead we only try to wrap on whitespace character. We do this, until we reached such a character so that the current text snippet exceeds the width of the widget. All we have to do now is to use the last position of a whitespace character and let our line end there. If no such a position exists we just create the line (since there is nothing we can do). The method itself is rather naiv and could probably be sped up if one would make use of a binary search instead of a naive loop.
|
|
|
|
This method, however gets only called, if the widget resizes or if a new input is received and therefore is not called many times.
|
|
|
|
|
|
|
|
```java
|
|
|
|
public static List<EditorLine> wrapLine(String prelimLine, int lineBeg, GC gc, int widgetWidth) {
|
|
|
|
List<EditorLine> lines = new ArrayList<>();
|
|
|
|
|
|
|
|
int lastpossOffset = ATHENEditorWidget.INVALID_OFFSET;
|
|
|
|
int offset = 0;
|
|
|
|
int handledBegOffset = 0;
|
|
|
|
for (Character c : prelimLine.toCharArray()) {
|
|
|
|
|
|
|
|
if (Character.isWhitespace(c)) {
|
|
|
|
// test
|
|
|
|
String substring = prelimLine.substring(handledBegOffset, offset);
|
|
|
|
Point extent = gc.stringExtent(substring);
|
|
|
|
if (extent.x > widgetWidth) {
|
|
|
|
|
|
|
|
// use the last possible one
|
|
|
|
if (lastpossOffset != ATHENEditorWidget.INVALID_OFFSET) {
|
|
|
|
|
|
|
|
String content = prelimLine.substring(handledBegOffset, lastpossOffset);
|
|
|
|
if (!content.isEmpty()) {
|
|
|
|
EditorLine editorLine = new EditorLine(content, new Point(handledBegOffset + lineBeg,
|
|
|
|
handledBegOffset + lineBeg + content.length()), extent.y, extent.x);
|
|
|
|
lines.add(editorLine);
|
|
|
|
}
|
|
|
|
handledBegOffset = lastpossOffset;
|
|
|
|
} else {
|
|
|
|
// either we are very small or the word is f*****
|
|
|
|
// long!!
|
|
|
|
if (!substring.isEmpty()) {
|
|
|
|
EditorLine editorLine = new EditorLine(substring,
|
|
|
|
new Point(handledBegOffset + lineBeg, lineBeg + substring.length()), extent.y,
|
|
|
|
extent.x);
|
|
|
|
lines.add(editorLine);
|
|
|
|
}
|
|
|
|
handledBegOffset = offset;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lastpossOffset = offset;
|
|
|
|
}
|
|
|
|
offset++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if we need a last line
|
|
|
|
if (handledBegOffset < prelimLine.length()) {
|
|
|
|
String content = prelimLine.substring(handledBegOffset, prelimLine.length());
|
|
|
|
Point extent = gc.textExtent(content);
|
|
|
|
if (!content.isEmpty()) {
|
|
|
|
EditorLine editorLine = new EditorLine(content,
|
|
|
|
new Point(handledBegOffset + lineBeg, lineBeg + prelimLine.length()), extent.y, extent.x);
|
|
|
|
lines.add(editorLine);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return lines;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
To be continued... |
|
To be continued... |
|
|
|
\ No newline at end of file |