Skip to content
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

Decouple style from segment object #590

Merged
merged 4 commits into from
Sep 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package org.fxmisc.richtext.demo.hyperlink;

public class Hyperlink<S> {
public class Hyperlink {

private final String originalDisplayedText;
private final String displayedText;
private final S style;
private final String link;

Hyperlink(String originalDisplayedText, String displayedText, S style, String link) {
Hyperlink(String originalDisplayedText, String displayedText, String link) {
this.originalDisplayedText = originalDisplayedText;
this.displayedText = displayedText;
this.style = style;
this.link = link;
}

Expand All @@ -22,7 +20,7 @@ public boolean isReal() {
return length() > 0;
}

public boolean shareSameAncestor(Hyperlink<S> other) {
public boolean shareSameAncestor(Hyperlink other) {
return link.equals(other.link) && originalDisplayedText.equals(other.originalDisplayedText);
}

Expand All @@ -44,32 +42,24 @@ public String getLink() {
return link;
}

public Hyperlink<S> subSequence(int start, int end) {
return new Hyperlink<>(originalDisplayedText, displayedText.substring(start, end), style, link);
public Hyperlink subSequence(int start, int end) {
return new Hyperlink(originalDisplayedText, displayedText.substring(start, end), link);
}

public Hyperlink<S> subSequence(int start) {
return new Hyperlink<>(originalDisplayedText, displayedText.substring(start), style, link);
public Hyperlink subSequence(int start) {
return new Hyperlink(originalDisplayedText, displayedText.substring(start), link);
}

public S getStyle() {
return style;
}

public Hyperlink<S> setStyle(S style) {
return new Hyperlink<>(originalDisplayedText, displayedText, style, link);
}

public Hyperlink<S> mapDisplayedText(String text) {
return new Hyperlink<>(originalDisplayedText, text, style, link);
public Hyperlink mapDisplayedText(String text) {
return new Hyperlink(originalDisplayedText, text, link);
}

@Override
public String toString() {
return isEmpty()
? String.format("EmptyHyperlink[original=%s style=%s link=%s]", originalDisplayedText, style, link)
: String.format("RealHyperlink[original=%s displayedText=%s, style=%s, link=%s]",
originalDisplayedText, displayedText, style, link);
? String.format("EmptyHyperlink[original=%s link=%s]", originalDisplayedText, link)
: String.format("RealHyperlink[original=%s displayedText=%s, link=%s]",
originalDisplayedText, displayedText, link);
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package org.fxmisc.richtext.demo.hyperlink;

import com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory;
import com.sun.javafx.application.HostServicesDelegate;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.fxmisc.flowless.VirtualizedScrollPane;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
package org.fxmisc.richtext.demo.hyperlink;

import org.fxmisc.richtext.model.SegmentOps;
import org.fxmisc.richtext.model.SegmentOpsBase;

import java.util.Optional;

public class HyperlinkOps<S> implements SegmentOps<Hyperlink<S>, S> {
public class HyperlinkOps<S> extends SegmentOpsBase<Hyperlink, S> {

public HyperlinkOps() {
super(new Hyperlink("", "", ""));
}

@Override
public int length(Hyperlink<S> hyperlink) {
public int length(Hyperlink hyperlink) {
return hyperlink.length();
}

@Override
public char charAt(Hyperlink<S> hyperlink, int index) {
public char realCharAt(Hyperlink hyperlink, int index) {
return hyperlink.charAt(index);
}

@Override
public String getText(Hyperlink<S> hyperlink) {
public String realGetText(Hyperlink hyperlink) {
return hyperlink.getDisplayedText();
}

@Override
public Hyperlink<S> subSequence(Hyperlink<S> hyperlink, int start, int end) {
public Hyperlink realSubSequence(Hyperlink hyperlink, int start, int end) {
return hyperlink.subSequence(start, end);
}

@Override
public Hyperlink<S> subSequence(Hyperlink<S> hyperlink, int start) {
public Hyperlink realSubSequence(Hyperlink hyperlink, int start) {
return hyperlink.subSequence(start);
}

@Override
public S getStyle(Hyperlink<S> hyperlink) {
return hyperlink.getStyle();
}

@Override
public Hyperlink<S> setStyle(Hyperlink<S> hyperlink, S style) {
return hyperlink.setStyle(style);
}

@Override
public Optional<Hyperlink<S>> join(Hyperlink<S> currentSeg, Hyperlink<S> nextSeg) {
public Optional<Hyperlink> joinSeg(Hyperlink currentSeg, Hyperlink nextSeg) {
if (currentSeg.isEmpty()) {
if (nextSeg.isEmpty()) {
return Optional.empty();
Expand All @@ -58,7 +52,7 @@ public Optional<Hyperlink<S>> join(Hyperlink<S> currentSeg, Hyperlink<S> nextSeg
}
}

private Optional<Hyperlink<S>> concatHyperlinks(Hyperlink<S> leftSeg, Hyperlink<S> rightSeg) {
private Optional<Hyperlink> concatHyperlinks(Hyperlink leftSeg, Hyperlink rightSeg) {
if (!leftSeg.shareSameAncestor(rightSeg)) {
return Optional.empty();
}
Expand Down Expand Up @@ -90,8 +84,4 @@ private Optional<Hyperlink<S>> concatHyperlinks(Hyperlink<S> leftSeg, Hyperlink<
}
}

@Override
public Hyperlink<S> createEmpty() {
return new Hyperlink<>("", "", null, "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,31 @@
import org.fxmisc.richtext.GenericStyledArea;
import org.fxmisc.richtext.TextExt;
import org.fxmisc.richtext.model.ReadOnlyStyledDocument;
import org.fxmisc.richtext.model.StyledText;
import org.fxmisc.richtext.model.SegmentOps;
import org.fxmisc.richtext.model.TextOps;
import org.reactfx.util.Either;

import java.util.Optional;
import java.util.function.Consumer;

public class TextHyperlinkArea extends GenericStyledArea<Void, Either<StyledText<TextStyle>, Hyperlink<TextStyle>>, TextStyle> {
public class TextHyperlinkArea extends GenericStyledArea<Void, Either<String, Hyperlink>, TextStyle> {

private static final TextOps<StyledText<TextStyle>, TextStyle> STYLED_TEXT_OPS = StyledText.textOps();
private static final TextOps<String, TextStyle> STYLED_TEXT_OPS = SegmentOps.styledTextOps();
private static final HyperlinkOps<TextStyle> HYPERLINK_OPS = new HyperlinkOps<>();
private static final TextOps<Either<StyledText<TextStyle>, Hyperlink<TextStyle>>, TextStyle> EITHER_OPS = STYLED_TEXT_OPS._or(HYPERLINK_OPS);

private static final TextOps<Either<String, Hyperlink>, TextStyle> EITHER_OPS = STYLED_TEXT_OPS._or(HYPERLINK_OPS, (s1, s2) -> Optional.empty());

public TextHyperlinkArea(Consumer<String> showLink) {
super(
null,
(t, p) -> {},
TextStyle.EMPTY,
EITHER_OPS,
e -> e.unify(
styledText ->
e -> e.getSegment().unify(
text ->
createStyledTextNode(t -> {
t.setText(styledText.getText());
t.setStyle(styledText.getStyle().toCss());
t.setText(text);
t.setStyle(e.getStyle().toCss());
}),
hyperlink ->
createStyledTextNode(t -> {
Expand All @@ -49,7 +51,7 @@ public void appendWithLink(String displayedText, String link) {

public void replaceWithLink(int start, int end, String displayedText, String link) {
replace(start, end, ReadOnlyStyledDocument.fromSegment(
Either.right(new Hyperlink<>(displayedText, displayedText, TextStyle.EMPTY, link)),
Either.right(new Hyperlink(displayedText, displayedText, link)),
null,
TextStyle.EMPTY,
EITHER_OPS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@

import javafx.scene.Node;

public class EmptyLinkedImage<S> implements LinkedImage<S> {
public class EmptyLinkedImage implements LinkedImage {

@Override
public LinkedImage<S> setStyle(S style) {
return this;
}

@Override
public S getStyle() {
return null;
public boolean isReal() {
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,39 @@
import java.io.DataOutputStream;
import java.io.IOException;

public interface LinkedImage<S> {
static <S> Codec<LinkedImage<S>> codec(Codec<S> styleCodec) {
return new Codec<LinkedImage<S>>() {

public interface LinkedImage {
static <S> Codec<LinkedImage> codec() {
return new Codec<LinkedImage>() {
@Override
public String getName() {
return "LinkedImage<" + styleCodec.getName() + ">";
return "LinkedImage";
}

@Override
public void encode(DataOutputStream os, LinkedImage<S> i) throws IOException {
// don't encode EmptyLinkedImage objects
if (i.getStyle() != null) {
// external path rep should use forward slashes only
String externalPath = i.getImagePath().replace("\\", "/");
public void encode(DataOutputStream os, LinkedImage linkedImage) throws IOException {
if (linkedImage.isReal()) {
os.writeBoolean(true);
String externalPath = linkedImage.getImagePath().replace("\\", "/");
Codec.STRING_CODEC.encode(os, externalPath);
styleCodec.encode(os, i.getStyle());
} else {
os.writeBoolean(false);
}
}

@Override
public RealLinkedImage<S> decode(DataInputStream is) throws IOException {
// Sanitize path - make sure that forward slashes only are used
String imagePath = Codec.STRING_CODEC.decode(is);
imagePath = imagePath.replace("\\", "/");
S style = styleCodec.decode(is);
return new RealLinkedImage<>(imagePath, style);
public LinkedImage decode(DataInputStream is) throws IOException {
if (is.readBoolean()) {
String imagePath = Codec.STRING_CODEC.decode(is);
imagePath = imagePath.replace("\\", "/");
return new RealLinkedImage(imagePath);
} else {
return new EmptyLinkedImage();
}
}

};
}

LinkedImage<S> setStyle(S style);

S getStyle();
boolean isReal();

/**
* @return The path of the image to render.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

import org.fxmisc.richtext.model.NodeSegmentOpsBase;

public class LinkedImageOps<S> extends NodeSegmentOpsBase<LinkedImage<S>, S> {

public LinkedImageOps() {
super(new EmptyLinkedImage<>());
}
public class LinkedImageOps<S> extends NodeSegmentOpsBase<LinkedImage, S> {

@Override
public S realGetStyle(LinkedImage<S> linkedImage) {
return linkedImage.getStyle();
public LinkedImageOps() {
super(new EmptyLinkedImage());
}

@Override
public LinkedImage<S> realSetStyle(LinkedImage<S> linkedImage, S style) {
return linkedImage.setStyle(style);
public int length(LinkedImage linkedImage) {
return linkedImage.isReal() ? 1 : 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@
* When rendered in the rich text editor, the image is loaded from the
* specified file.
*/
public class RealLinkedImage<S> implements LinkedImage<S> {
public class RealLinkedImage implements LinkedImage {

private final String imagePath;
private final S style;

/**
* Creates a new linked image object.
*
* @param imagePath The path to the image file.
* @param style The text style to apply to the corresponding segment.
*/
public RealLinkedImage(String imagePath, S style) {
public RealLinkedImage(String imagePath) {

// if the image is below the current working directory,
// then store as relative path name.
Expand All @@ -33,26 +31,18 @@ public RealLinkedImage(String imagePath, S style) {
}

this.imagePath = imagePath;
this.style = style;
}

@Override
public RealLinkedImage<S> setStyle(S style) {
return new RealLinkedImage<>(imagePath, style);
public boolean isReal() {
return true;
}


@Override
public String getImagePath() {
return imagePath;
}

@Override
public S getStyle() {
return style;
}


@Override
public String toString() {
return String.format("RealLinkedImage[path=%s]", imagePath);
Expand Down
Loading