Craig Raw
5 years ago
8 changed files with 333 additions and 7 deletions
@ -1 +1 @@ |
|||||
Subproject commit dcd4218ba14ecea9113925b80af02fdc3287079a |
Subproject commit f6dcdb6d26c3b40ae1c0f7502b3e526aa8959564 |
@ -0,0 +1,150 @@ |
|||||
|
package com.sparrowwallet.sparrow.control; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.wallet.Keystore; |
||||
|
import javafx.animation.KeyFrame; |
||||
|
import javafx.animation.KeyValue; |
||||
|
import javafx.animation.Timeline; |
||||
|
import javafx.beans.property.SimpleObjectProperty; |
||||
|
import javafx.collections.ListChangeListener; |
||||
|
import javafx.collections.ObservableList; |
||||
|
import javafx.geometry.Insets; |
||||
|
import javafx.geometry.Orientation; |
||||
|
import javafx.geometry.Pos; |
||||
|
import javafx.scene.control.Label; |
||||
|
import javafx.scene.control.ProgressBar; |
||||
|
import javafx.scene.layout.StackPane; |
||||
|
import javafx.util.Duration; |
||||
|
import org.controlsfx.control.SegmentedBar; |
||||
|
|
||||
|
public class SignaturesProgressBar extends SegmentedBar<SignaturesProgressBar.SignatureProgressSegment> { |
||||
|
public SignaturesProgressBar() { |
||||
|
setOrientation(Orientation.HORIZONTAL); |
||||
|
setSegmentViewFactory(SignatureProgressSegmentView::new); |
||||
|
setInfoNodeFactory(segment -> segment.getKeystore() == null ? null : new SignatureProgressSegmentLabel(segment.getKeystore().getLabel())); |
||||
|
} |
||||
|
|
||||
|
public void initialize(ObservableList<Keystore> signedKeystores, int threshold) { |
||||
|
getStyleClass().add("signatures-progress-bar"); |
||||
|
getSegments().clear(); |
||||
|
|
||||
|
int numSegments = Math.max(threshold, signedKeystores.size()); |
||||
|
double segmentSize = 100d / numSegments; |
||||
|
for(int i = 0; i < numSegments; i++) { |
||||
|
if(i < signedKeystores.size()) { |
||||
|
getSegments().add(new SignatureProgressSegment(segmentSize, i, signedKeystores.get(i))); |
||||
|
} else { |
||||
|
getSegments().add(new SignatureProgressSegment(segmentSize, i, null)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
signedKeystores.addListener((ListChangeListener<Keystore>) c -> { |
||||
|
int numSegments1 = Math.max(threshold, c.getList().size()); |
||||
|
double newSegmentSize = 100d / numSegments1; |
||||
|
|
||||
|
for(int i = 0; i < numSegments1; i++) { |
||||
|
SignatureProgressSegment segment = null; |
||||
|
if(i < getSegments().size()) { |
||||
|
segment = getSegments().get(i); |
||||
|
} |
||||
|
|
||||
|
Keystore signedKeystore = null; |
||||
|
if(i < signedKeystores.size()) { |
||||
|
signedKeystore = signedKeystores.get(i); |
||||
|
} |
||||
|
|
||||
|
if(segment != null) { |
||||
|
//Animate new signature if changed
|
||||
|
segment.setKeystore(signedKeystore); |
||||
|
} else { |
||||
|
//Add extra (unnecessary) signature
|
||||
|
for(SignaturesProgressBar.SignatureProgressSegment existingSegment : getSegments()) { |
||||
|
existingSegment.setValue(newSegmentSize); |
||||
|
} |
||||
|
|
||||
|
SignaturesProgressBar.SignatureProgressSegment newSegment = new SignatureProgressSegment(newSegmentSize, i, null); |
||||
|
getSegments().add(newSegment); |
||||
|
newSegment.setKeystore(signedKeystore); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public static class SignatureProgressSegment extends SegmentedBar.Segment { |
||||
|
private final SimpleObjectProperty<Keystore> keystoreProperty; |
||||
|
private final int index; |
||||
|
|
||||
|
public SignatureProgressSegment(double value, int index, Keystore keystore) { |
||||
|
super(value); |
||||
|
this.index = index; |
||||
|
|
||||
|
this.keystoreProperty = new SimpleObjectProperty<>(this, "keystore", null); |
||||
|
keystoreProperty.addListener((observable, oldValue, newValue) -> { |
||||
|
setText(newValue == null ? "No keystore" : newValue.getLabel()); |
||||
|
}); |
||||
|
|
||||
|
setKeystore(keystore); |
||||
|
} |
||||
|
|
||||
|
public int getIndex() { |
||||
|
return index; |
||||
|
} |
||||
|
|
||||
|
public Keystore getKeystore() { |
||||
|
return keystoreProperty.get(); |
||||
|
} |
||||
|
|
||||
|
public SimpleObjectProperty<Keystore> keystoreProperty() { |
||||
|
return keystoreProperty; |
||||
|
} |
||||
|
|
||||
|
public void setKeystore(Keystore keystore) { |
||||
|
keystoreProperty.set(keystore); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static class SignatureProgressSegmentView extends StackPane { |
||||
|
private final ProgressBar progressBar; |
||||
|
private final Label label; |
||||
|
|
||||
|
public SignatureProgressSegmentView(SignatureProgressSegment segment) { |
||||
|
getStyleClass().add("signature-progress-segment"); |
||||
|
getStyleClass().add("segment" + segment.getIndex()); |
||||
|
|
||||
|
label = new Label(); |
||||
|
label.textProperty().bind(segment.textProperty()); |
||||
|
label.getStyleClass().add("signature-progress-segment-label"); |
||||
|
StackPane.setAlignment(label, Pos.CENTER); |
||||
|
|
||||
|
progressBar = new ProgressBar(segment.getKeystore() == null ? 0.0 : 1.0); |
||||
|
progressBar.setPrefWidth(Double.MAX_VALUE); |
||||
|
progressBar.setPrefHeight(30); |
||||
|
|
||||
|
setPrefHeight(50); |
||||
|
getChildren().addAll(progressBar, label); |
||||
|
|
||||
|
segment.keystoreProperty().addListener((observable, oldValue, newValue) -> { |
||||
|
if(oldValue == null && newValue != null) { |
||||
|
Timeline timeline = new Timeline( |
||||
|
new KeyFrame(Duration.ZERO, new KeyValue(progressBar.progressProperty(), 0)), |
||||
|
new KeyFrame(Duration.millis(800), new KeyValue(progressBar.progressProperty(), 1)) |
||||
|
); |
||||
|
timeline.setCycleCount(1); |
||||
|
timeline.play(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void layoutChildren() { |
||||
|
super.layoutChildren(); |
||||
|
label.setVisible(label.prefWidth(-1) < getWidth() - getPadding().getLeft() - getPadding().getRight() - 8); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static class SignatureProgressSegmentLabel extends Label { |
||||
|
public SignatureProgressSegmentLabel(String text) { |
||||
|
super(text); |
||||
|
setPadding(new Insets(10)); |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue