/*
* Copyright (C) 2015 Patryk Strach
*
* This file is part of Virtual Slide Viewer.
*
* Virtual Slide Viewer is free software: you can redistribute it and/or modify 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.
*
* Virtual Slide Viewer 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 Virtual Slide Viewer.
* If not, see <http://www.gnu.org/licenses/>.
*/
package virtualslideviewer.ui;
import java.awt.*;
import java.text.DecimalFormat;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import virtualslideviewer.ui.imageviewing.ImagePresentationModel;
import virtualslideviewer.ui.imageviewing.view.ImageIndexControlPanel;
import virtualslideviewer.ui.imageviewing.view.ImagePreviewPanel;
import virtualslideviewer.ui.imageviewing.view.ImageRenderingPanel;
public class MainPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private final JComponent mImageIndexControlPanel;
private final JComponent mImageRenderingPanel;
private final JComponent mImageListPanel;
private final ImagePreviewPanel mImagePreviewPanel;
private JSlider mZoomSlider;
private JFormattedTextField mZoomTextField;
private boolean mZoomSliderSetProgrammatically = false;
private final ImagePresentationModel mImagePresentationModel;
public MainPanel(JComponent imageListPanel, ImagePresentationModel imagePresentationModel)
{
mImagePresentationModel = imagePresentationModel;
mImageIndexControlPanel = new ImageIndexControlPanel(mImagePresentationModel);
mImageRenderingPanel = new ImageRenderingPanel(mImagePresentationModel);
mImageListPanel = imageListPanel;
mImagePreviewPanel = new ImagePreviewPanel(mImagePresentationModel);
createZoomSlider();
createZoomTextField();
layoutComponents();
}
private void createZoomSlider()
{
mZoomSlider = new JSlider();
mZoomSlider.setMinimum(1);
mZoomSlider.setMaximum(4000);
mImagePresentationModel.addListener(new ImagePresentationModel.Listener()
{
@Override
public void onVisibleImageContentUpdate()
{
mZoomSliderSetProgrammatically = true;
mZoomSlider.setValue(percentToZoomLevel(mImagePresentationModel.getZoom()));
}
@Override
public void onImageChange() { onVisibleImageContentUpdate(); }
});
mZoomSlider.addChangeListener(x ->
{
if(mZoomSliderSetProgrammatically)
{
mZoomSliderSetProgrammatically = false;
return;
}
mImagePresentationModel.setZoom(zoomLevelToPercent(mZoomSlider.getValue()));
});
}
private void createZoomTextField()
{
mZoomTextField = new JFormattedTextField(new DecimalFormat("##0.00%"));
mZoomTextField.setFocusLostBehavior(JFormattedTextField.REVERT);
mZoomTextField.setHorizontalAlignment(SwingConstants.CENTER);
mZoomTextField.setColumns(6);
mZoomTextField.setMinimumSize(mZoomTextField.getPreferredSize());
mZoomTextField.addActionListener((x) -> mImagePresentationModel.setZoom(((Number)mZoomTextField.getValue()).doubleValue()));
mImagePresentationModel.addListener(new ImagePresentationModel.Listener()
{
@Override
public void onVisibleImageContentUpdate()
{
mZoomTextField.setValue(mImagePresentationModel.getZoom());
}
@Override
public void onImageChange() { onVisibleImageContentUpdate(); }
});
}
private double zoomLevelToPercent(int zoomLevel)
{
double minZoomPercent = mImagePresentationModel.getMinZoom();
double zoomIncrement = computeZoomIncrementToMakeExactlyNIncrements();
return minZoomPercent * Math.pow(zoomIncrement, zoomLevel - 1);
}
private int percentToZoomLevel(double percent)
{
double minZoomPercent = mImagePresentationModel.getMinZoom();
double zoomIncrement = computeZoomIncrementToMakeExactlyNIncrements();
return (int)Math.round((Math.log(percent / minZoomPercent) / Math.log(zoomIncrement)) + 1);
}
private double computeZoomIncrementToMakeExactlyNIncrements()
{
double minZoomPercent = mImagePresentationModel.getMinZoom();
double maxZoomPercent = mImagePresentationModel.getMaxZoom();
double incrementsCount = mZoomSlider.getMaximum();
return Math.pow(maxZoomPercent / minZoomPercent, 1.0 / (incrementsCount - 1));
}
private void layoutComponents()
{
super.setLayout(new BorderLayout(0, 0));
JSplitPane mainSplitPane = new JSplitPane();
mainSplitPane.setResizeWeight(1.0);
mainSplitPane.setOneTouchExpandable(true);
layoutLeftPart(mainSplitPane);
layoutRightPart(mainSplitPane);
super.add(mainSplitPane);
}
private void layoutLeftPart(JSplitPane mainSplitPane)
{
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints imageIndexControlPanelConstraints = new GridBagConstraints();
imageIndexControlPanelConstraints.gridx = 0;
imageIndexControlPanelConstraints.gridy = 0;
imageIndexControlPanelConstraints.weightx = 1.0;
imageIndexControlPanelConstraints.fill = GridBagConstraints.HORIZONTAL;
panel.add(mImageIndexControlPanel, imageIndexControlPanelConstraints);
GridBagConstraints imageRenderingPanelConstraints = new GridBagConstraints();
imageRenderingPanelConstraints.gridx = 0;
imageRenderingPanelConstraints.gridy = 1;
imageRenderingPanelConstraints.weightx = 1.0;
imageRenderingPanelConstraints.weighty = 1.0;
imageRenderingPanelConstraints.fill = GridBagConstraints.BOTH;
panel.add(mImageRenderingPanel, imageRenderingPanelConstraints);
mainSplitPane.setLeftComponent(panel);
}
private void layoutRightPart(JSplitPane mainSplitPane)
{
JSplitPane rightSplitPanel = new JSplitPane();
rightSplitPanel.setResizeWeight(0.4);
rightSplitPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
layoutTopRightPart(rightSplitPanel);
layoutBottomRightPart(rightSplitPanel);
mainSplitPane.setRightComponent(rightSplitPanel);
}
private void layoutTopRightPart(JSplitPane rightSplitPanel)
{
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints previewPanelConstraints = new GridBagConstraints();
previewPanelConstraints.gridx = 0;
previewPanelConstraints.gridy = 0;
previewPanelConstraints.weightx = 1.0;
previewPanelConstraints.weighty = 1.0;
previewPanelConstraints.fill = GridBagConstraints.BOTH;
mainPanel.add(mImagePreviewPanel, previewPanelConstraints);
JPanel zoomBoxPanel = new JPanel(new GridBagLayout());
zoomBoxPanel.setBorder(new TitledBorder("Zoom"));
{
GridBagConstraints zoomSlideConstraints = new GridBagConstraints();
zoomSlideConstraints.gridx = 0;
zoomSlideConstraints.gridy = 0;
zoomSlideConstraints.weightx = 1.0;
zoomSlideConstraints.fill = GridBagConstraints.HORIZONTAL;
zoomBoxPanel.add(mZoomSlider, zoomSlideConstraints);
GridBagConstraints zoomTextFieldConstaints = new GridBagConstraints();
zoomTextFieldConstaints.gridx = 1;
zoomTextFieldConstaints.gridy = 0;
zoomTextFieldConstaints.weightx = 0.0;
zoomBoxPanel.add(mZoomTextField, zoomTextFieldConstaints);
}
GridBagConstraints zoomBoxPanelConstraints = new GridBagConstraints();
zoomBoxPanelConstraints.gridx = 0;
zoomBoxPanelConstraints.gridy = 1;
zoomBoxPanelConstraints.weightx = 1.0;
zoomBoxPanelConstraints.weighty = 0.0;
zoomBoxPanelConstraints.fill = GridBagConstraints.HORIZONTAL;
mainPanel.add(zoomBoxPanel, zoomBoxPanelConstraints);
rightSplitPanel.setTopComponent(mainPanel);
}
private void layoutBottomRightPart(JSplitPane rightSplitPanel)
{
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
rightSplitPanel.setBottomComponent(tabbedPane);
tabbedPane.addTab("Images", null, mImageListPanel, null);
}
}