Skip to content
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
26 changes: 18 additions & 8 deletions src/main/java/flimlib/flimj/ui/controller/ConfigCtrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@

import com.google.gson.JsonParser;
import com.google.gson.JsonElement;

import java.io.File;
import java.nio.file.Files;
import java.io.FileWriter;
import java.io.IOException;
import org.scijava.widget.FileWidget;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import flimlib.flimj.FitParams;
import flimlib.flimj.ui.controls.NumericSpinner;
import flimlib.flimj.ui.FitProcessor.FitType;

import net.imglib2.type.numeric.real.FloatType;

/**
Expand All @@ -44,7 +49,7 @@ public class ConfigCtrl extends AbstractCtrl {
@FXML
private NumericSpinner binSizeSpinner;

@FXML
@FXML
private Button configLoadButton;

@FXML
Expand All @@ -53,10 +58,15 @@ public class ConfigCtrl extends AbstractCtrl {
@Override
public void initialize() {

// initialize a file chooser
final var fcStage = new Stage();
final var fcUI = new FileChooser();

configSaveButton.setOnAction(event -> {
File cfgSavePath = getUIs().chooseFile("Choose config save path", new File("fit_config.txt"),
FileWidget.SAVE_STYLE);
if (cfgSavePath != null) {
fcUI.setTitle("Choose config save path");
fcUI.setInitialFileName("fit_config.txt");
File cfgSavePath = fcUI.showSaveDialog(fcStage);
if (cfgSavePath != null) {
try {
FileWriter writer = new FileWriter(cfgSavePath);
String paramsJSONString = fp.getParams().toJSON();
Expand All @@ -75,9 +85,9 @@ public void initialize() {
});

configLoadButton.setOnAction(event -> {
File cfgLoadPath = getUIs().chooseFile("Choose config file", null,
FileWidget.OPEN_STYLE);
if (cfgLoadPath != null) {
fcUI.setTitle("Choose config file");
File cfgLoadPath = fcUI.showOpenDialog(fcStage);
if (cfgLoadPath != null) {
String cfgPath = cfgLoadPath.getPath();
if (cfgPath.endsWith(".txt")) {
try {
Expand Down
144 changes: 130 additions & 14 deletions src/main/java/flimlib/flimj/ui/controller/PlotCtrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
Expand All @@ -23,6 +23,7 @@

import java.util.ArrayList;
import java.util.List;

import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
Expand All @@ -38,17 +39,24 @@
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;

import org.controlsfx.control.HiddenSidesPane;
import org.controlsfx.control.SegmentedButton;

import net.imglib2.type.numeric.real.FloatType;

import flimlib.flimj.FitParams;
import flimlib.flimj.FitResults;
import flimlib.flimj.ui.Utils;
import flimlib.flimj.ui.VariableScaleAxis;
import flimlib.flimj.ui.controls.NumericSpinner;
import net.imglib2.type.numeric.real.FloatType;

/**
* The controller of the "Plot" tab.
Expand All @@ -59,15 +67,21 @@ public class PlotCtrl extends AbstractCtrl {
private static final int FIT_IDX = 1;
private static final int RES_IDX = 2;
private static final int IRF_IDX = 3;

private static final int BEG_IDX = 0;
private static final int END_IDX = 1;

private static final int N_PLOTS = 4;

/** cursors */
@FXML
private Group lCsr, rCsr;
private Group lCsr, rCsr, lCsr_res, rCsr_res;

/** cursor circle elements*/
@FXML
private Circle lCsrCircle, rCsrCircle;

/** cursor line elements*/
@FXML
private Line lCsrBar, rCsrBar, lCsrBar_res, rCsrBar_res;

/** cursor position spinners */
@FXML
Expand Down Expand Up @@ -96,6 +110,9 @@ public class PlotCtrl extends AbstractCtrl {
@FXML
private ImageView frostImageView;

@FXML
private ToggleButton linTB, logTB;

/** cursor positions */
private ObjectProperty<Double> lCsrPos, rCsrPos;

Expand Down Expand Up @@ -128,22 +145,41 @@ public class PlotCtrl extends AbstractCtrl {
@SuppressWarnings("unchecked")
public void initialize() {
// initialize properties with invalid values (corrected by refresh())
lCsrPos = new SimpleObjectProperty<>();
lCsrPos.set(-1.0);
rCsrPos = new SimpleObjectProperty<>();
rCsrPos.set(-1.0);
fitStart = new SimpleObjectProperty<>();
fitStart.set(-1);
fitEnd = new SimpleObjectProperty<>();
fitEnd.set(-1);
lCsrPos = new SimpleObjectProperty<>(-1.0);
rCsrPos = new SimpleObjectProperty<>(-1.0);
fitStart = new SimpleObjectProperty<>(-1);
fitEnd = new SimpleObjectProperty<>(-1);
lCsrSpinner.setMin(0.0);
rCsrSpinner.setMin(0.0);
lCsrSpinner.setMax(0.0);
rCsrSpinner.setMax(0.0);

// set cursor initial positions
lCsr.setTranslateX(0);
rCsr.setTranslateX(fitPlotAreaPane.getWidth());

// bind the X pos of the residual cursors so they move together
lCsr_res.translateXProperty().bind(lCsr.translateXProperty());
rCsr_res.translateXProperty().bind(rCsr.translateXProperty());

// fit the height of the bar with the plot height size
lCsrBar.endYProperty().bind(fitPlotAreaPane.heightProperty().subtract(1));
rCsrBar.endYProperty().bind(fitPlotAreaPane.heightProperty().subtract(1));
lCsrBar_res.endYProperty().bind(fitPlotAreaPane.heightProperty().subtract(1));
lCsrBar_res.endYProperty().bind(fitPlotAreaPane.heightProperty().subtract(1));

// link the two toggle buttons to the segmented button
fitYScaleSB.getButtons().addAll(linTB, logTB);
linTB.setSelected(true);

// initialize cursor listeners
initListeners(rCsr, rCsrPos, rCsrSpinner, fitEnd);
initListeners(lCsr, lCsrPos, lCsrSpinner, fitStart);

// initialize cursor mouse event handlers
initCursorEventHandlers(lCsr);
initCursorEventHandlers(rCsr);

fitPlotAreaPane.widthProperty().addListener((obs, oldVal, newVal) -> {
// == 0 at init
if (oldVal.floatValue() != 0) {
Expand Down Expand Up @@ -220,6 +256,17 @@ else if (oldVal != null)
});
}

/**
* Clamps a value between min and max.
* @param value The value to clamp.
* @param min The minimum allowed value.
* @param max The maximum allowed value.
* @return The clamped value.
*/
private double clamp(double value, double min, double max) {
return Math.max(min, Math.min(value, max));
}

@Override
protected void refresh(FitParams<FloatType> params, FitResults results) {
nIntervals = params.trans.length - 1;
Expand Down Expand Up @@ -248,6 +295,75 @@ protected void refresh(FitParams<FloatType> params, FitResults results) {

}

/**
* Sets up mouse event handlers for a cursor group.
*
* @param cursor The cursor group to initialize.
*/
private void initCursorEventHandlers(Group cursor) {
// find the circle within the cursor group
var csrCircle = (Circle) cursor.lookup("#" + cursor.getId() + "Circle");

// create onMouseEntered event handler
cursor.setOnMouseEntered(event -> {
double newCenterY = clamp(event.getY(),
csrCircle.getRadius() * 2.5,
fitPlotAreaPane.getHeight() - csrCircle.getRadius() * 2.5);
csrCircle.setCenterY(newCenterY);
csrCircle.setScaleX(2);
csrCircle.setScaleY(2);
});

// create onMouseExited event handler
cursor.setOnMouseExited(event -> {
csrCircle.setScaleX(1);
csrCircle.setScaleY(1);
});

// create onMouseDragged event handler
cursor.setOnMouseDragged(event -> {
double newTranslateX = cursor.getTranslateX() + event.getX();
double min = 0.0;
double max = fitPlotAreaPane.getWidth();
if (cursor == rCsr) {
min = lCsr.getTranslateX();
} else if (cursor == lCsr) {
max = rCsr.getTranslateX();
}
cursor.setTranslateX(clamp(newTranslateX, min, max));
});
}

/**
* Handle "mouse entered" events.
*
* @param event A mouse movement event.
*/
@FXML
private void handleMouseEntered(MouseEvent event) {
((Group) event.getSource()).getOnMouseEntered().handle(event);
}

/**
* Handle "mouse exited" events.
*
* @param event A mouse movement event.
*/
@FXML
private void handleMouseExited(MouseEvent event) {
((Group) event.getSource()).getOnMouseExited().handle(event);
}

/**
* Handle "mouse dragged" events.
*
* @param event A mouse movement event.
*/
@FXML
private void handleMouseDragged(MouseEvent event) {
((Group) event.getSource()).getOnMouseDragged().handle(event);
}

/**
* Adds change listeners to critical values so that they work together.
*
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/flimlib/flimj/ui/controller/SettingsCtrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@

import org.scijava.ui.DialogPrompt.MessageType;
import org.scijava.ui.DialogPrompt.OptionType;
import org.scijava.widget.FileWidget;

import flimlib.NoiseType;
import flimlib.flimj.FitParams;
Expand All @@ -50,6 +49,7 @@
import flimlib.flimj.ui.Utils;
import flimlib.flimj.ui.controls.NumericSpinner;
import flimlib.flimj.ui.controls.NumericTextField;

import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.application.Platform;
Expand All @@ -68,6 +68,8 @@
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.Duration;

Expand Down Expand Up @@ -122,11 +124,17 @@ public class SettingsCtrl extends AbstractCtrl {

@Override
public void initialize() {
// initialize buffers
paramLabels = new ArrayList<>();
paramValues = new ArrayList<>();
paramFixed = new ArrayList<>();
paramIndices = new ArrayList<>();
presentDatasets = new HashMap<>();

// initialize file chooser
final var fcStage = new Stage();
final var fcUI = new FileChooser();

// keep only the table header (remove the preview parameters)
paramPane.getChildren().removeIf(child -> GridPane.getRowIndex(child) > 0);

Expand Down Expand Up @@ -297,8 +305,8 @@ public NoiseType fromString(String string) {
// the name of selected dataset
String currentSelection = oldVal;
// choose from file
File irfFile = getUIs().chooseFile("Choose IRF transient file", null,
FileWidget.OPEN_STYLE);
fcUI.setTitle("Choose IRF transiet file");
File irfFile = fcUI.showOpenDialog(fcStage);
if (irfFile != null) {
// not cancelled
String irfPath = irfFile.getPath();
Expand Down
Loading