add transaction hex tooltips

This commit is contained in:
Craig Raw 2021-04-15 15:18:00 +02:00
parent a8430c79eb
commit 2c98c8606c

View file

@ -3,20 +3,34 @@ package com.sparrowwallet.sparrow.control;
import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.protocol.*;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Point2D;
import javafx.scene.control.Label;
import javafx.stage.Popup;
import org.fxmisc.richtext.CodeArea; import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.event.MouseOverTextEvent;
import org.fxmisc.richtext.model.StyleSpan;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static org.fxmisc.richtext.model.TwoDimensional.Bias.Backward;
public class TransactionHexArea extends CodeArea { public class TransactionHexArea extends CodeArea {
private static final int TRUNCATE_AT = 30000; private static final int TRUNCATE_AT = 30000;
private static final int SEGMENTS_INTERVAL = 250; private static final int SEGMENTS_INTERVAL = 250;
private List<TransactionSegment> previousSegmentList = new ArrayList<>(); private List<TransactionSegment> previousSegmentList = new ArrayList<>();
public TransactionHexArea() {
super();
addPopupHandler();
}
public void setTransaction(Transaction transaction) { public void setTransaction(Transaction transaction) {
try { try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -44,6 +58,27 @@ public class TransactionHexArea extends CodeArea {
previousSegmentList = segments; previousSegmentList = segments;
} }
private void addPopupHandler() {
Popup popup = new Popup();
Label popupMsg = new Label();
popupMsg.getStyleClass().add("tooltip");
popup.getContent().add(popupMsg);
setMouseOverTextDelay(Duration.ofMillis(150));
addEventHandler(MouseOverTextEvent.MOUSE_OVER_TEXT_BEGIN, e -> {
Position position = getParagraph(0).getStyleSpans().offsetToPosition(e.getCharacterIndex() + 1, Backward);
StyleSpan<Collection<String>> styleSpan = getParagraph(0).getStyleSpans().getStyleSpan(position.getMajor());
Point2D pos = e.getScreenPosition();
popupMsg.setText(describeTransactionPart(styleSpan.getStyle()));
if(!popupMsg.getText().isEmpty()) {
popup.show(this, pos.getX(), pos.getY() + 10);
}
});
addEventHandler(MouseOverTextEvent.MOUSE_OVER_TEXT_END, e -> {
popup.hide();
});
}
private void applyHighlighting(int start, List<TransactionSegment> segments) { private void applyHighlighting(int start, List<TransactionSegment> segments) {
int end = Math.min(segments.size(), start + SEGMENTS_INTERVAL); int end = Math.min(segments.size(), start + SEGMENTS_INTERVAL);
for(int i = start; i < end; i++) { for(int i = start; i < end; i++) {
@ -143,6 +178,30 @@ public class TransactionHexArea extends CodeArea {
return "other"; return "other";
} }
private String describeTransactionPart(Collection<String> styles) {
String style = styles.isEmpty() ? "" : styles.iterator().next();
return switch(style) {
case "version" -> "Transaction version";
case "segwit-marker" -> "Segwit marker";
case "segwit-flag" -> "Segwit flag";
case "num-inputs" -> "Number of inputs";
case "input-hash" -> "Input transaction ID";
case "input-index" -> "Input transaction index";
case "input-sigscript-length" -> "ScriptSig length";
case "input-sigscript" -> "ScriptSig";
case "input-sequence" -> "Sequence";
case "num-outputs" -> "Number of outputs";
case "output-value" -> "Output value";
case "output-pubkeyscript-length" -> "ScriptPubKey length";
case "output-pubkeyscript" -> "ScriptPubKey";
case "witness-count" -> "Witness count";
case "witness-length" -> "Witness length";
case "witness-data" -> "Witness data";
case "locktime" -> "Locktime";
default -> "";
};
}
private static class TransactionSegment { private static class TransactionSegment {
public TransactionSegment(int start, int length, String style) { public TransactionSegment(int start, int length, String style) {
this.start = start; this.start = start;