/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.ui.editor.image;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.weasis.core.api.gui.util.ActionState;
import org.weasis.core.api.gui.util.ActionW;
import org.weasis.core.api.gui.util.ComboItemListener;
import org.weasis.core.api.gui.util.DecFormater;
import org.weasis.core.api.gui.util.JMVUtils;
import org.weasis.core.api.gui.util.MathUtil;
import org.weasis.core.api.image.util.Unit;
import org.weasis.core.api.media.data.ImageElement;
import org.weasis.core.api.media.data.MediaSeries;
import org.weasis.core.api.util.LocalUtil;
import org.weasis.core.api.util.StringUtil;
import org.weasis.core.ui.Messages;
import org.weasis.core.ui.model.graphic.imp.line.LineGraphic;
public class CalibrationView extends JPanel {
private static final long serialVersionUID = -1098044466661041480L;
private static final Logger LOGGER = LoggerFactory.getLogger(CalibrationView.class);
private final ViewCanvas<?> view2d;
private final LineGraphic line;
private final JComboBox<Unit> jComboBoxUnit;
private final JPanel jPanelMode = new JPanel();
private final JFormattedTextField jTextFieldLineWidth = new JFormattedTextField();
private final JLabel jLabelKnownDist = new JLabel();
private final BorderLayout borderLayout1 = new BorderLayout();
private final GridBagLayout gridBagLayout2 = new GridBagLayout();
private final JLabel lblApplyTo = new JLabel(Messages.getString("CalibrationView.apply") + StringUtil.COLON); //$NON-NLS-1$
private final JPanel panel = new JPanel();
private final ButtonGroup ratioGroup = new ButtonGroup();
private final JRadioButton radioButtonSeries = new JRadioButton(Messages.getString("CalibrationView.series")); //$NON-NLS-1$
private final JRadioButton radioButtonImage = new JRadioButton(Messages.getString("CalibrationView.current")); //$NON-NLS-1$
public CalibrationView(LineGraphic line, ViewCanvas<?> view2d, boolean selectSeries) {
this.line = line;
this.view2d = view2d;
List<Unit> units = Unit.getUnitExceptPixel();
this.jComboBoxUnit = new JComboBox<>(units.toArray(new Unit[units.size()]));
try {
jbInit();
radioButtonSeries.setSelected(selectSeries);
if (!selectSeries) {
radioButtonImage.setSelected(true);
}
initialize();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
void jbInit() {
gridBagLayout2.rowWeights = new double[] { 1.0, 0.0 };
gridBagLayout2.columnWeights = new double[] { 0.0, 1.0, 0.0, 0.0 };
jPanelMode.setLayout(gridBagLayout2);
JMVUtils.setPreferredWidth(jTextFieldLineWidth, 170);
jTextFieldLineWidth.setLocale(LocalUtil.getLocaleFormat());
jTextFieldLineWidth.setFormatterFactory(DecFormater.setPreciseDoubleFormat(0.000005d, Double.MAX_VALUE));
jTextFieldLineWidth.setValue(1.0);
JMVUtils.addCheckAction(jTextFieldLineWidth);
jLabelKnownDist.setText(Messages.getString("CalibrationView.known") + StringUtil.COLON); //$NON-NLS-1$
this.setLayout(borderLayout1);
this.add(jPanelMode, BorderLayout.CENTER);
jPanelMode.add(jComboBoxUnit, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 3, 0, 0), 0, 0));
jPanelMode.add(jLabelKnownDist, new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 10, 0, 5), 0, 0));
jPanelMode.add(jTextFieldLineWidth, new GridBagConstraints(2, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 5), 0, 0));
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
flowLayout.setHgap(10);
flowLayout.setAlignment(FlowLayout.LEFT);
add(panel, BorderLayout.SOUTH);
panel.add(lblApplyTo);
ratioGroup.add(radioButtonSeries);
ratioGroup.add(radioButtonImage);
panel.add(radioButtonSeries);
panel.add(radioButtonImage);
}
public boolean isApplyingToSeries() {
return radioButtonSeries.isSelected();
}
private void initialize() {
ImageElement image = view2d.getImage();
if (image != null) {
Unit unit = image.getPixelSpacingUnit();
if (!Unit.PIXEL.equals(unit)) {
Point2D ptA = line.getStartPoint();
Point2D ptB = line.getEndPoint();
if (Objects.nonNull(ptA) && Objects.nonNull(ptB)) {
jTextFieldLineWidth.setValue(ptA.distance(ptB) * image.getPixelSize());
}
} else {
GridBagConstraints gbcTextPane = new GridBagConstraints();
gbcTextPane.gridwidth = 4;
gbcTextPane.insets = new Insets(0, 0, 5, 5);
gbcTextPane.fill = GridBagConstraints.HORIZONTAL;
gbcTextPane.gridx = 0;
gbcTextPane.gridy = 0;
gbcTextPane.weightx = 1.0;
gbcTextPane.weighty = 1.0;
JScrollPane scroll = new JScrollPane(createArea(Messages.getString("CalibrationView.warn"), //$NON-NLS-1$
true, 0));
scroll.setPreferredSize(new Dimension(300, 75));
jPanelMode.add(scroll, gbcTextPane);
unit = Unit.MILLIMETER;
}
jComboBoxUnit.setSelectedItem(unit);
}
}
private static JTextArea createArea(String text, boolean lineWrap, int columns) {
JTextArea area = new JTextArea(text);
area.setBorder(new CompoundBorder(BorderFactory.createRaisedBevelBorder(), new EmptyBorder(3, 5, 3, 5)));
area.setLineWrap(lineWrap);
area.setWrapStyleWord(true);
area.setEditable(false);
area.setColumns(columns);
return area;
}
public void removeCalibration() {
applyCalibration(1.0, Unit.PIXEL);
}
private void applyCalibration(double ratio, Unit unit) {
ImageElement image = view2d.getImage();
if (image != null) {
if (radioButtonSeries.isSelected()) {
MediaSeries<?> seriesList = view2d.getSeries();
if (Objects.nonNull(seriesList)) {
Iterable<?> list = seriesList.getMedias(null, null);
synchronized (seriesList) {
for (Object media : list) {
if (media instanceof ImageElement && media != image) {
ImageElement img = (ImageElement) media;
img.setPixelSpacingUnit(unit);
img.setPixelSize(ratio);
}
}
}
}
}
image.setPixelSize(ratio);
image.setPixelSpacingUnit(unit);
if (view2d.getEventManager().getSelectedViewPane() == view2d) {
ActionState spUnitAction = view2d.getEventManager().getAction(ActionW.SPATIAL_UNIT);
if (spUnitAction instanceof ComboItemListener) {
((ComboItemListener) spUnitAction).setSelectedItem(unit);
}
}
view2d.getGraphicManager().updateLabels(Boolean.TRUE, view2d);
}
}
public void applyNewCalibration() {
ImageElement image = view2d.getImage();
if (image != null) {
Number inputCalibVal = JMVUtils.getFormattedValue(jTextFieldLineWidth);
if (inputCalibVal != null) {
double imgRatio = image.getPixelSize();
Unit unit = (Unit) jComboBoxUnit.getSelectedItem();
Unit imgUnit = image.getPixelSpacingUnit();
if (!Unit.PIXEL.equals(unit)) {
image.setPixelSpacingUnit(unit);
Double lineLength = 0.0;
Point2D ptA = line.getStartPoint();
Point2D ptB = line.getEndPoint();
if (Objects.nonNull(ptA) && Objects.nonNull(ptB)) {
lineLength = ptA.distance(ptB);
}
if (Objects.isNull(lineLength) || lineLength < 1d) {
lineLength = 1.0;
}
double newRatio = inputCalibVal.doubleValue() / lineLength;
if ((Objects.nonNull(imgRatio) && MathUtil.isDifferent(newRatio, imgRatio))
|| !Objects.equals(unit, imgUnit)) {
applyCalibration(newRatio, unit);
}
}
}
}
}
}