-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option to show a split view #152
Comments
Hi Jordan, How could I split a rich text area (whatever flavor) into two views, something that is typically done in a Word processor?
As of now, I could do the first by adding two rich text areas to a Split Pane, but how would I do the second? If I add two areas to a Split Pane, I could have them listen to each other for any updates. This is probably inefficient if the area contains a lot of text, styles, etc, but it provides a work around until a better solution is provided. —Reply to this email directly or view it on GitHub. |
Hi Jordan, I think the best you can do today is as you suggest - have the two text areas listen to each other. It is not necessarily inefficient, if you observe and re-do the individual changes. Here you can see how to apply a change generated by one text area to the other one. A cleaner (but unsupported as of now) solution would be to let the two areas share the same underlying |
@melkhaldi Thanks for the suggestion. Threads are above my level of programming as well. Maybe they won't be some day. :-) A Cyanogen phone! O.o @TomasMikula Thanks for the guidance. So, the quick and dirty solution is to do what I've described, but the better solution (and one that contributes to this project) would be to create a pull request that adds this support, correct? |
Yes, that is exactly correct ;) |
If someone else doesn't beat me to this, I'd like to do it. However, I'm still writing other core parts of my program. This feature isn't absolutely necessary to my program, but it would definitely be convenient to have. :-) |
So, to complete this, we'd need to:
|
Aye. I did this in a separate branch, and it wasn't difficult at all.
This is me thinking outloud: The area can be changed in two situations: 1) via user interaction and 2) via modifications made by code. I'm assuming your comment about "external modification" means the 2nd case as only one area could have the focus (and thus user inputs) at a time. // length == 30
String areaText = "Just some text for an example."
// both carets are positioned at 0
StyledTextArea area = // creation code;
StyledTextArea clone = area.createClone();
// area's caret repositioned to 30
area.positionCaret(area.getLength());
// deletes all text
clone.replaceText(0, clone.getLength(), "");
// clone's caret == 0
// area's caretPosition should be 0 but is 30
// length == 12
String someText = "someText";
// assumed result is that area displays: areaText + "someText"
area.insertText(area.getCaretPosition(), someText);
// actual result: area and clone both display "someText"
// and area's caret position == 12. It could be problematic for the |
By "external modification", I meant modification of the underlying What I thought of as a solution was that the area would listen to changes on the EditableStyledDocument and adjust the caret position/selection appropriately when necessary.
I think each area should have its own caret position and selection, don't you think? |
Ah........ ok, well I think I was reaching that conclusion with my recent commit in the PR ;-) |
After thinking about this more, I'm not sure why I went in the original direction I did... Let's GTD this:
Outcome: any modifications (via user or code) to the shared Where
Given a document with the following text:
When Area 2 deletes it's selection, the text should be updated accordingly:
Brainstorm: One way to update the caret and selection values is by calculating the index where a chance occurs and how much to offset an Area's caret and selection values. If an Area's caret or its selection's end is in front of this index, then both don't need to be changed. Otherwise, each needs to be offset by some amount. This offset amount (second) is the difference of the text's length before the change and after the change. // given these values
int indexOfChange = ...;
int changeInAreaLength = ...;
// and knowing the area's caret and selection values
int areaCaretPosition = ...;
int areaSelectionFrom = ...;
int areaSelectionTo = ...;
// then offset the area's caret and selection values if needed
if (changeInAreaLength != 0) {
if (indexOfChange < areaCaretPosition) {
area.setCaretPosition(areaCaretPosition + changeInAreaLength);
}
area.selectRange(
indexOfChange < areaSelectionFrom
? areaSelectionFrom + changeInAreaLength
: areaSelectionFrom,
indexOfChange < areaSelectionTo
? areaSelectionTo + changeInAreaLength
: areaSelectionTo
);
} |
That will work when the change is outside of selection/caret position. When, for example, the caret is at position 8, and a change occurs that deletes the range 6-10, the caret should be moved to position 6, but the above code would move it to position 4. |
Good point. What about changing the code to this then? // cloneUpdatesToDoc should emit its Event when this area is
// not the view making the change to the shared EditableStyledDocument
EventStream<PlainTextChange> cloneUpdatesToDoc = ...;
cloneUpdatesToDoc.subscribe( plainTextChange -> {
int changeLength = plainTextChange.getInserted().length() - plainTextChange.getRemoved().length();
if (changeLength != 0) {
int indexOfChange = plainTextChange.getPosition();
// in case of a replacement: "hello there" -> "hi."
int endOfChange = indexOfChange + Math.abs(changeLength);
// update caret
int caretPosition = getCaretPosition();
if (indexOfChange < caretPosition) {
// if caret is within the changed content, move it to indexOfChange
// otherwise offset it by changeLength
positionCaret(
caretPosition < endOfChange
? indexOfChange
: caretPosition + changeLength
);
}
// update selection
int selectionStart = getSelection().getStart();
int selectionEnd = getSelection().getEnd();
if (selectionStart != selectionEnd) {
// if start/end is within the changed content, move it to indexOfChange
// otherwise, offset it by changeLength
// Note: if both are moved to indexOfChange, selection is empty.
if (indexOfChange < selectionStart) {
selectionStart = selectionStart < endOfChange
? indexOfChange
: selectionStart + changeLength;
}
if (indexOfChange < selectionEnd) {
selectionEnd = selectionEnd < endOfChange
? indexOfChange
: selectionEnd + changeLength;
}
selectRange(selectionStart, selectionEnd);
}
}
}); |
Resolved via 87c2b30 |
Hello Tomas,
How could I split a rich text area (whatever flavor) into two views, something that is typically done in a Word processor?
There are two parts to this:
As of now, I could do the first by adding two rich text areas to a Split Pane, but how would I do the second? If I add two areas to a Split Pane, I could have them listen to each other for any updates. This is probably inefficient if the area contains a lot of text, styles, etc, but it provides a work around until a better solution is provided.
The text was updated successfully, but these errors were encountered: