... | @@ -282,6 +282,7 @@ Now we are reaching one of the more interesting steps of writing a text widget - |
... | @@ -282,6 +282,7 @@ Now we are reaching one of the more interesting steps of writing a text widget - |
|
|
|
|
|
Wrapping lines is first interesting if the we receive a new input document. Recap the code of the ```setInput``` method:
|
|
Wrapping lines is first interesting if the we receive a new input document. Recap the code of the ```setInput``` method:
|
|
|
|
|
|
|
|
```java
|
|
public void setInput(CASEditorInput input) {
|
|
public void setInput(CASEditorInput input) {
|
|
this.currentInput = input;
|
|
this.currentInput = input;
|
|
|
|
|
... | @@ -297,4 +298,87 @@ Wrapping lines is first interesting if the we receive a new input document. Reca |
... | @@ -297,4 +298,87 @@ Wrapping lines is first interesting if the we receive a new input document. Reca |
|
startCursor();
|
|
startCursor();
|
|
|
|
|
|
}
|
|
}
|
|
|
|
```java
|
|
|
|
|
|
|
|
The focus of this section is the method ```updateScrollbar()``` which calculates the position and maximum values of our scrollbars. But more importantly the lines of the editor are created. Let us check this method:
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
|
|
|
private void updateScrollbar() {
|
|
|
|
|
|
|
|
GC gc = new GC(this);
|
|
|
|
// save the first visible character offset before wrapping
|
|
|
|
int firstVisibleCharacter = 0;
|
|
|
|
|
|
|
|
if (editorLines != null) {
|
|
|
|
firstVisibleCharacter = editorLines.get(topLineOffset).getOffset().x;
|
|
|
|
}
|
|
|
|
determineWrappedLines(determineWidgetWidth(), gc, getBounds().height);
|
|
|
|
|
|
|
|
/** omitted for brevity **/
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
This method is the first one with some complexity in it. However we are for now only interested in the method ```determineWrappedLines(...)``` which does calculate the lines of our editor.
|
|
|
|
|
|
|
|
### A small note towards the lines of the widget
|
|
|
|
|
|
|
|
This subsection serves the purpose of elaborating the data which are stored inside the editor. And the most important one is the concept of an ```EditorLine```. In the sense of the ```StyledText``` widget of SWT, a line does always start At a character and ends at a line break ```\n```. So whenever wrapping is enabled, there is no real way to tell into how many *lines* the actual lines was separated. This widget should not follow this approach, instead we define an ```EditorLine``` as every snippet of text that is displayed in the same row. (So that wrapping actually creates or changes the amount of lines!).
|
|
|
|
|
|
|
|
## 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
|
|
|
|
|
|
|
|
```java
|
|
|
|
private void determineWrappedLines(int widgetWidth, GC gc, int height) {
|
|
|
|
|
|
|
|
editorLines = new ArrayList<>();
|
|
|
|
|
|
|
|
// preliminary lines
|
|
|
|
int lineOffset = 0;
|
|
|
|
int lineNumber = 0;
|
|
|
|
while (true) {
|
|
|
|
//the next offset of a newline is found
|
|
|
|
int indexOf = getText().indexOf("\n", lineOffset);
|
|
|
|
String prelimLine;
|
|
|
|
if (indexOf == INVALID_OFFSET) {
|
|
|
|
// last line
|
|
|
|
prelimLine = getText().substring(lineOffset);
|
|
|
|
} else {
|
|
|
|
prelimLine = getText().substring(lineOffset, indexOf + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prelimLine.length() > 0) {
|
|
|
|
//the line is measured
|
|
|
|
Point textExtent = gc.textExtent(prelimLine);
|
|
|
|
// if the line is short enough or if no wrap is used
|
|
|
|
if (textExtent.x <= widgetWidth || !useWrap) {
|
|
|
|
EditorLine editorLine = new EditorLine(prelimLine,
|
|
|
|
new Point(lineOffset, lineOffset + prelimLine.length()), textExtent.y, textExtent.x);
|
|
|
|
editorLine.setLineNumber(lineNumber);
|
|
|
|
lineNumber++;
|
|
|
|
editorLines.add(editorLine);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// create more than 1 line with the according offsets
|
|
|
|
List<EditorLine> wrappedLines = wrapLine(prelimLine, lineOffset, gc, widgetWidth);
|
|
|
|
for (EditorLine l : wrappedLines) {
|
|
|
|
l.setLineNumber(lineNumber);
|
|
|
|
lineNumber++;
|
|
|
|
editorLines.add(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
lineOffset += prelimLine.length();
|
|
|
|
}
|
|
|
|
if (indexOf == INVALID_OFFSET) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
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.
|
|
To be continued... |
|
To be continued... |
|
|
|
\ No newline at end of file |