Skip to content

Commit

Permalink
Use single model directory
Browse files Browse the repository at this point in the history
Store local models inside a subdirectory of the model directory called either 'local' or 'user' (or both).
This reduces the number of required preferences & also the vertical space required by the dialog (which can be important for small laptop monitors).
  • Loading branch information
petebankhead committed Nov 13, 2023
1 parent 135fccf commit 60d6074
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 56 deletions.
16 changes: 11 additions & 5 deletions src/main/java/qupath/ext/wsinfer/models/WSInferUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;
import java.util.ResourceBundle;

Expand Down Expand Up @@ -66,15 +67,20 @@ public static WSInferModelCollection getModelCollection() {
cachedModelCollection = downloadModelCollection();
}
}
String localModelDirectory = WSInferPrefs.localDirectoryProperty().get();
if (localModelDirectory != null) {
addLocalModels(cachedModelCollection, localModelDirectory);
String pathModels = WSInferPrefs.modelDirectoryProperty().get();
if (pathModels != null) {
File dirModels = new File(pathModels);
if (dirModels.isDirectory()) {
// Search for local models in 'local' or 'user' subdirectories
for (var name : Arrays.asList("local", "user")) {
addLocalModels(cachedModelCollection, new File(dirModels, name));
}
}
}
return cachedModelCollection;
}

private static void addLocalModels(WSInferModelCollection cachedModelCollection, String localModelDirectory) {
File modelDir = new File(localModelDirectory);
private static void addLocalModels(WSInferModelCollection cachedModelCollection, File modelDir) {
if (!modelDir.exists() || !modelDir.isDirectory()) {
return;
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/qupath/ext/wsinfer/ui/WSInferCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class WSInferCommand implements Runnable {
private final ResourceBundle resources = ResourceBundle.getBundle("qupath.ext.wsinfer.ui.strings");

private Stage stage;
private WSInferController controller;

public WSInferCommand(QuPathGUI qupath) {
this.qupath = qupath;
Expand All @@ -62,8 +63,10 @@ public void run() {
logger.error(e.getMessage(), e);
return;
}
} else
} else {
controller.refreshAvailableModels();
stage.show();
}
}

private Stage createStage() throws IOException {
Expand All @@ -77,6 +80,7 @@ private Stage createStage() throws IOException {
var loader = new FXMLLoader(url, resources);
loader.setClassLoader(this.getClass().getClassLoader());
VBox root = loader.load();
controller = loader.getController();

// There's probably a better approach... but wrapping in a border pane
// helped me get the resizing to behave
Expand Down
32 changes: 21 additions & 11 deletions src/main/java/qupath/ext/wsinfer/ui/WSInferController.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import javafx.scene.control.Spinner;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.StringConverter;
Expand All @@ -52,7 +53,6 @@
import org.controlsfx.control.action.ActionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import qupath.ext.wsinfer.ProgressListener;
import qupath.ext.wsinfer.WSInfer;
import qupath.ext.wsinfer.models.WSInferModel;
import qupath.ext.wsinfer.models.WSInferModelCollection;
Expand All @@ -64,6 +64,7 @@
import qupath.lib.common.ThreadTools;
import qupath.lib.gui.QuPathGUI;
import qupath.lib.gui.commands.Commands;
import qupath.lib.gui.tools.GuiTools;
import qupath.lib.gui.tools.WebViews;
import qupath.lib.images.ImageData;
import qupath.lib.objects.PathAnnotationObject;
Expand Down Expand Up @@ -129,8 +130,6 @@ public class WSInferController {
private Spinner<Integer> spinnerBatchSize;
@FXML
private TextField tfModelDirectory;
@FXML
private TextField localModelDirectory;

private WebView infoWebView = WebViews.create(true);
private PopOver infoPopover = new PopOver(infoWebView);
Expand All @@ -150,7 +149,7 @@ private void initialize() {
this.qupath = QuPathGUI.getInstance();
this.imageDataProperty.bind(qupath.imageDataProperty());

configureModelChoices();
refreshAvailableModels();

configureSelectionButtons();
configureDisplayToggleButtons();
Expand Down Expand Up @@ -186,7 +185,7 @@ private void configureMessageLabel() {
/**
* Populate the available models & configure the UI elements to select and download models.
*/
private void configureModelChoices() {
void refreshAvailableModels() {
WSInferModelCollection models = WSInferUtils.getModelCollection();
modelChoiceBox.getItems().setAll(models.getModels().values());
modelChoiceBox.setConverter(new ModelStringConverter(models));
Expand Down Expand Up @@ -273,8 +272,6 @@ private void configureActionToggleButton(Action action, ToggleButton button) {

private void configureModelDirectory() {
tfModelDirectory.textProperty().bindBidirectional(WSInferPrefs.modelDirectoryProperty());
localModelDirectory.textProperty().bindBidirectional(WSInferPrefs.localDirectoryProperty());
localModelDirectory.textProperty().addListener((v, o, n) -> configureModelChoices());
}

private void configureNumWorkers() {
Expand Down Expand Up @@ -375,12 +372,25 @@ public void downloadModel() {
});
}

public void promptForModelDirectory() {
promptToUpdateDirectory(WSInferPrefs.modelDirectoryProperty());
/**
* Open the model directory in the system file browser when double-clicked.
* @param event
*/
public void handleModelDirectoryLabelClick(MouseEvent event) {
if (event.getClickCount() != 2)
return;
var path = WSInferPrefs.modelDirectoryProperty().get();
if (path == null || path.isEmpty())
return;
var file = new File(path);
if (file.exists())
GuiTools.browseDirectory(file);
else
logger.debug("Can't browse directory for {}", file);
}

public void promptForLocalModelDirectory() {
promptToUpdateDirectory(WSInferPrefs.localDirectoryProperty());
public void promptForModelDirectory() {
promptToUpdateDirectory(WSInferPrefs.modelDirectoryProperty());
}

private void promptToUpdateDirectory(StringProperty dirPath) {
Expand Down
11 changes: 0 additions & 11 deletions src/main/java/qupath/ext/wsinfer/ui/WSInferPrefs.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ public class WSInferPrefs {
4
).asObject();

private static StringProperty localDirectoryProperty = PathPrefs.createPersistentPreference(
"wsinfer.localDirectory",
null);

/**
* String storing the preferred directory to cache models.
*/
Expand Down Expand Up @@ -81,13 +77,6 @@ public static Property<Integer> batchSizeProperty() {
return batchSizeProperty;
}

/**
* String storing the preferred directory for user-supplied model folders.
*/
public static StringProperty localDirectoryProperty() {
return localDirectoryProperty;
}

private static Path getUserDir() {
Path userPath = UserDirectoryManager.getInstance().getUserPath();
Path cachePath = Paths.get(System.getProperty("user.dir"), ".cache", "QuPath");
Expand Down
43 changes: 15 additions & 28 deletions src/main/resources/qupath/ext/wsinfer/ui/wsinfer_control.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@
</SegmentedButton>
</children>
</HBox>
<styleClass>
<String fx:value="standard-spacing" />
<String fx:value="standard-padding" />
</styleClass>
<styleClass>
<String fx:value="standard-padding" />
<String fx:value="standard-vertical-spacing" />
</styleClass>
</VBox>
</children>
</VBox>
Expand All @@ -100,7 +100,7 @@
</HBox>
<Label id="labelWarning" fx:id="labelMessage" styleClass="error-message" text="%ui.error.no-selection" VBox.vgrow="ALWAYS" />
<styleClass>
<String fx:value="standard-spacing" />
<String fx:value="standard-vertical-spacing" />
<String fx:value="standard-padding" />
</styleClass>
</VBox>
Expand All @@ -113,7 +113,7 @@
<!--**********************Results**********************-->
<VBox alignment="TOP_CENTER" styleClass="standard-spacing standard-padding">
<children>
<VBox alignment="CENTER" styleClass="standard-spacing">
<VBox alignment="CENTER" styleClass="standard-vertical-spacing">
<children>
<HBox alignment="CENTER" styleClass="standard-spacing">
<children>
Expand Down Expand Up @@ -150,7 +150,7 @@
</TitledPane>

<!-- Hardware Pane************************************************************-->
<TitledPane fx:id="pane3" animated="false" expanded="false" maxHeight="Infinity" text="%ui.options.pane" VBox.vgrow="NEVER">
<TitledPane fx:id="pane3" animated="false" maxHeight="Infinity" text="%ui.options.pane" VBox.vgrow="NEVER">
<VBox alignment="TOP_CENTER" spacing="7.5" styleClass="standard-padding">
<children>
<HBox alignment="CENTER" styleClass="standard-spacing">
Expand All @@ -163,7 +163,7 @@
</ChoiceBox>
</children>
</HBox>
<HBox alignment="CENTER" styleClass="standard-spacing">
<HBox alignment="CENTER">
<children>
<Label styleClass="regular" text="%ui.options.batchSize" />
<Spinner fx:id="spinnerBatchSize" prefWidth="75.0">
Expand All @@ -175,6 +175,10 @@
</valueFactory>
</Spinner>
</children>
<styleClass>
<String fx:value="standard-vertical-spacing" />
<String fx:value="standard-padding" />
</styleClass>
</HBox>
<HBox alignment="CENTER" styleClass="standard-spacing">
<children>
Expand All @@ -189,9 +193,9 @@
</HBox>
<Separator prefWidth="200.0" />
<VBox alignment="CENTER" styleClass="standard-spacing">
<VBox alignment="CENTER" styleClass="standard-spacing">
<VBox alignment="CENTER" styleClass="standard-vertical-spacing">
<children>
<Label styleClass="regular" text="%ui.options.directory" />
<Label onMouseClicked="#handleModelDirectoryLabelClick" styleClass="regular" text="%ui.options.directory" />
<HBox styleClass="standard-spacing">
<children>
<TextField fx:id="tfModelDirectory" HBox.hgrow="ALWAYS">
Expand All @@ -213,24 +217,7 @@
</VBox>
<VBox alignment="CENTER" styleClass="standard-spacing">
<children>
<Label styleClass="regular" text="%ui.options.localModelDirectory" />
<HBox styleClass="standard-spacing">
<children>
<TextField fx:id="localModelDirectory" HBox.hgrow="ALWAYS">
<tooltip>
<Tooltip text="%ui.options.localModelDirectory.tooltip" />
</tooltip>
</TextField>
<Button fx:id="userModelDirButton" mnemonicParsing="false" onAction="#promptForLocalModelDirectory">
<tooltip>
<Tooltip text="%ui.options.localModelDirectory.tooltip" />
</tooltip>
<graphic>
<Text styleClass="fa-icon" text="" />
</graphic>
</Button>
</children>
</HBox>
<HBox styleClass="standard-spacing" />
</children>
</VBox>
</VBox>
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/qupath/ext/wsinfer/ui/wsinferstyles.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
-fx-spacing: 7.5;
}

/* spacing - current use in VBox*/
.standard-vertical-spacing {
-fx-spacing: 5;
}

.standard-padding {
-fx-padding: 2;
}
Expand Down

0 comments on commit 60d6074

Please sign in to comment.