-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make previews always fit vertically in the preview area (#944)
No more previews clipping below the bottom, forcing users to scroll up and down to see information displayed below the image (eg contour count) Reimplement TitledPane and ImageView to get proper behavior
- Loading branch information
1 parent
11bdb8e
commit 69f5704
Showing
12 changed files
with
191 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
ui/src/main/java/edu/wpi/grip/ui/preview/ResizableImageView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package edu.wpi.grip.ui.preview; | ||
|
||
import javafx.beans.property.DoubleProperty; | ||
import javafx.beans.property.ObjectProperty; | ||
import javafx.beans.property.ReadOnlyDoubleProperty; | ||
import javafx.beans.property.SimpleDoubleProperty; | ||
import javafx.beans.property.SimpleObjectProperty; | ||
import javafx.geometry.Orientation; | ||
import javafx.scene.image.Image; | ||
import javafx.scene.layout.Background; | ||
import javafx.scene.layout.BackgroundImage; | ||
import javafx.scene.layout.BackgroundRepeat; | ||
import javafx.scene.layout.BackgroundSize; | ||
import javafx.scene.layout.Region; | ||
|
||
/** | ||
* A custom implementation of an image view that resizes to fit its parent container. | ||
*/ | ||
public class ResizableImageView extends Region { | ||
|
||
private final ObjectProperty<Image> image = new SimpleObjectProperty<>(this, "image"); | ||
private final DoubleProperty ratio = new SimpleDoubleProperty(this, "ratio", 1); | ||
private static final BackgroundSize size = | ||
new BackgroundSize(BackgroundSize.AUTO, BackgroundSize.AUTO, false, false, true, false); | ||
|
||
/** | ||
* Creates a new resizable image view. | ||
*/ | ||
public ResizableImageView() { | ||
super(); | ||
|
||
getStyleClass().add("resizable-image"); | ||
|
||
image.addListener((obs, old, img) -> { | ||
if (img == null) { | ||
setBackground(null); | ||
ratio.set(1); | ||
} else if (img != old) { | ||
// Only create a new background object when the image changes | ||
// Otherwise we would be creating a new background object for every frame of every preview | ||
Background background = createImageBackground(img); | ||
setBackground(background); | ||
ratio.set(img.getWidth() / img.getHeight()); | ||
setPrefHeight(img.getHeight()); | ||
setPrefWidth(USE_COMPUTED_SIZE); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Creates a background that displays only the given image. | ||
* | ||
* @param img the image to create the background for | ||
*/ | ||
private static Background createImageBackground(Image img) { | ||
BackgroundImage backgroundImage = new BackgroundImage( | ||
img, | ||
BackgroundRepeat.NO_REPEAT, | ||
BackgroundRepeat.NO_REPEAT, | ||
null, | ||
size | ||
); | ||
return new Background(backgroundImage); | ||
} | ||
|
||
public Image getImage() { | ||
return image.get(); | ||
} | ||
|
||
public ObjectProperty<Image> imageProperty() { | ||
return image; | ||
} | ||
|
||
public void setImage(Image image) { | ||
this.image.set(image); | ||
} | ||
|
||
public double getRatio() { | ||
return ratio.get(); | ||
} | ||
|
||
public ReadOnlyDoubleProperty ratioProperty() { | ||
return ratio; | ||
} | ||
|
||
@Override | ||
public Orientation getContentBias() { | ||
return Orientation.VERTICAL; | ||
} | ||
|
||
/** | ||
* Computes the width of the displayed image for the given target height, maintaining the image's | ||
* intrinsic aspect ratio. | ||
* | ||
* @param height the target height of the image | ||
* @return the width of the image | ||
*/ | ||
private double computeImageWidthForHeight(double height) { | ||
if (getImage() == null) { | ||
return 1; | ||
} | ||
return height * getRatio(); | ||
} | ||
|
||
@Override | ||
protected double computePrefWidth(double height) { | ||
return computeImageWidthForHeight(height); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package edu.wpi.grip.ui.preview; | ||
|
||
import javafx.beans.property.ObjectProperty; | ||
import javafx.beans.property.SimpleObjectProperty; | ||
import javafx.beans.property.StringProperty; | ||
import javafx.scene.Node; | ||
import javafx.scene.control.Label; | ||
import javafx.scene.layout.BorderPane; | ||
import javafx.scene.layout.HBox; | ||
import javafx.scene.layout.StackPane; | ||
|
||
/** | ||
* Custom implementation of a titled pane. The JavaFX implementation has a tendency to add a gap | ||
* on the sides of image content when resized. | ||
*/ | ||
public class TitledPane extends BorderPane { | ||
|
||
private final Label label = new Label(); | ||
private final HBox top = new HBox(label); | ||
private final StackPane center = new StackPane(); | ||
|
||
private final ObjectProperty<Node> content = new SimpleObjectProperty<>(); | ||
|
||
/** | ||
* Creates a new titled pane with no text and no content. | ||
*/ | ||
public TitledPane() { | ||
this.getStyleClass().add("titled-pane"); | ||
top.getStyleClass().add("title"); | ||
center.getStyleClass().add("content"); | ||
|
||
content.addListener((obs, old, content) -> { | ||
if (content == null) { | ||
center.getChildren().clear(); | ||
} else { | ||
center.getChildren().setAll(content); | ||
} | ||
}); | ||
|
||
setTop(top); | ||
setCenter(center); | ||
setMaxHeight(USE_PREF_SIZE); | ||
} | ||
|
||
public void setText(String text) { | ||
label.setText(text); | ||
} | ||
|
||
public String getText() { | ||
return label.getText(); | ||
} | ||
|
||
public StringProperty textProperty() { | ||
return label.textProperty(); | ||
} | ||
|
||
public Node getContent() { | ||
return content.get(); | ||
} | ||
|
||
public ObjectProperty<Node> contentProperty() { | ||
return content; | ||
} | ||
|
||
public void setContent(Node content) { | ||
this.content.set(content); | ||
} | ||
} |
Oops, something went wrong.