package plugins.kernel.canvas; import icy.gui.component.IcyTextField; import icy.gui.component.IcyTextField.TextChangeListener; import icy.gui.component.NumberTextField; import icy.gui.component.button.ColorChooserButton; import icy.gui.component.button.ColorChooserButton.ColorChangeListener; import icy.gui.component.button.IcyToggleButton; import icy.resource.ResourceUtil; import icy.resource.icon.IcyIcon; import icy.vtk.VtkImageVolume; import icy.vtk.VtkImageVolume.VtkVolumeBlendType; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.util.EventListener; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JCheckBox; public class VtkSettingPanel extends JPanel implements ActionListener, TextChangeListener, ColorChangeListener { /** * */ private static final long serialVersionUID = 6433369095311474470L; protected static final Image ICON_GPU = ResourceUtil.getAlphaIconAsImage("gpu.png"); protected static final Image ICON_SHADING = ResourceUtil.getColorIconAsImage("shading.png"); public static final String PROPERTY_BG_COLOR = "renderBGColor"; public static final String PROPERTY_MAPPER = "volumeMapper"; public static final String PROPERTY_BLENDING = "volumeBlending"; public static final String PROPERTY_SAMPLE = "volumeSample"; public static final String PROPERTY_INTERPOLATION = "volumeInterpolation"; public static final String PROPERTY_SHADING = "shading"; public static final String PROPERTY_AMBIENT = "volumeAmbient"; public static final String PROPERTY_DIFFUSE = "volumeDiffuse"; public static final String PROPERTY_SPECULAR = "volumeSpecular"; /** * GUI */ private ColorChooserButton bgColorButton; private JCheckBox gpuMapperCheckBox; private JComboBox volumeBlendingComboBox; private JComboBox volumeSampleComboBox; private JComboBox volumeInterpolationComboBox; private IcyToggleButton shadingButton; private NumberTextField volumeAmbientField; private NumberTextField volumeSpecularField; private NumberTextField volumeDiffuseField; /** * Create the panel. */ public VtkSettingPanel() { super(); initialize(); updateState(); bgColorButton.addColorChangeListener(this); gpuMapperCheckBox.addActionListener(this); volumeBlendingComboBox.addActionListener(this); volumeInterpolationComboBox.addActionListener(this); volumeSampleComboBox.addActionListener(this); shadingButton.addActionListener(this); volumeAmbientField.addTextChangeListener(this); volumeDiffuseField.addTextChangeListener(this); volumeSpecularField.addTextChangeListener(this); } protected void initialize() { setBorder(new EmptyBorder(2, 0, 2, 0)); GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[] {0, 0, 0, 0, 0}; gridBagLayout.rowHeights = new int[] {0, 0, 0, 0, 0, 0}; gridBagLayout.columnWeights = new double[] {0.0, 1.0, 1.0, 1.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE}; setLayout(gridBagLayout); final JLabel lblBackground = new JLabel("Background color "); lblBackground.setToolTipText("Change background color"); GridBagConstraints gbc_lblBackground = new GridBagConstraints(); gbc_lblBackground.anchor = GridBagConstraints.WEST; gbc_lblBackground.insets = new Insets(0, 0, 5, 5); gbc_lblBackground.gridx = 0; gbc_lblBackground.gridy = 0; add(lblBackground, gbc_lblBackground); bgColorButton = new ColorChooserButton(); bgColorButton.setToolTipText("Change background color"); GridBagConstraints gbc_bgColorButton = new GridBagConstraints(); gbc_bgColorButton.anchor = GridBagConstraints.WEST; gbc_bgColorButton.insets = new Insets(0, 0, 5, 5); gbc_bgColorButton.gridx = 1; gbc_bgColorButton.gridy = 0; add(bgColorButton, gbc_bgColorButton); gpuMapperCheckBox = new JCheckBox("New check box"); gpuMapperCheckBox.setFocusable(false); gpuMapperCheckBox.setIconTextGap(8); gpuMapperCheckBox.setText("GPU rendering"); gpuMapperCheckBox.setToolTipText("Enable GPU volume rendering"); GridBagConstraints gbc_gpuMapperCheckBox = new GridBagConstraints(); gbc_gpuMapperCheckBox.anchor = GridBagConstraints.EAST; gbc_gpuMapperCheckBox.gridwidth = 2; gbc_gpuMapperCheckBox.insets = new Insets(0, 0, 5, 0); gbc_gpuMapperCheckBox.gridx = 2; gbc_gpuMapperCheckBox.gridy = 0; add(gpuMapperCheckBox, gbc_gpuMapperCheckBox); final JLabel lblInterpolation = new JLabel("Interpolation "); lblInterpolation.setToolTipText("Select volume rendering interpolation method"); GridBagConstraints gbc_lblInterpolation = new GridBagConstraints(); gbc_lblInterpolation.anchor = GridBagConstraints.WEST; gbc_lblInterpolation.insets = new Insets(0, 0, 5, 5); gbc_lblInterpolation.gridx = 0; gbc_lblInterpolation.gridy = 1; add(lblInterpolation, gbc_lblInterpolation); volumeInterpolationComboBox = new JComboBox(); volumeInterpolationComboBox.setToolTipText("Select volume rendering interpolation method"); volumeInterpolationComboBox.setMaximumRowCount(7); volumeInterpolationComboBox.setModel(new DefaultComboBoxModel(new String[] {"Nearest (Fast)", "Linear", "Cubic (Slow)"})); volumeInterpolationComboBox.setSelectedIndex(1); GridBagConstraints gbc_volumeInterpolationComboBox = new GridBagConstraints(); gbc_volumeInterpolationComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeInterpolationComboBox.gridwidth = 3; gbc_volumeInterpolationComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeInterpolationComboBox.gridx = 1; gbc_volumeInterpolationComboBox.gridy = 1; add(volumeInterpolationComboBox, gbc_volumeInterpolationComboBox); JLabel lblBlending = new JLabel("Blending"); lblBlending.setToolTipText("Select volume rendering blending method"); GridBagConstraints gbc_lblBlending = new GridBagConstraints(); gbc_lblBlending.anchor = GridBagConstraints.WEST; gbc_lblBlending.insets = new Insets(0, 0, 5, 5); gbc_lblBlending.gridx = 0; gbc_lblBlending.gridy = 2; add(lblBlending, gbc_lblBlending); volumeBlendingComboBox = new JComboBox(); volumeBlendingComboBox.setToolTipText("Select volume rendering blending method"); volumeBlendingComboBox.setModel(new DefaultComboBoxModel(VtkVolumeBlendType.values())); GridBagConstraints gbc_volumeBlendingComboBox = new GridBagConstraints(); gbc_volumeBlendingComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeBlendingComboBox.gridwidth = 3; gbc_volumeBlendingComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeBlendingComboBox.gridx = 1; gbc_volumeBlendingComboBox.gridy = 2; add(volumeBlendingComboBox, gbc_volumeBlendingComboBox); final JLabel lblSample = new JLabel("Sample"); lblSample.setToolTipText("Set volume sample resolution (raycaster mapper only)"); GridBagConstraints gbc_lblSample = new GridBagConstraints(); gbc_lblSample.anchor = GridBagConstraints.WEST; gbc_lblSample.insets = new Insets(0, 0, 5, 5); gbc_lblSample.gridx = 0; gbc_lblSample.gridy = 3; add(lblSample, gbc_lblSample); volumeSampleComboBox = new JComboBox(); volumeSampleComboBox .setToolTipText("Use low value for fine (but slow) rendering and high value for fast (but coarse) rendering"); volumeSampleComboBox.setMaximumRowCount(11); volumeSampleComboBox.setModel(new DefaultComboBoxModel(new String[] {"Auto", "1 (Slow)", "2", "3", "4", "5", "6", "7", "8", "9", "10 (Fast)"})); volumeSampleComboBox.setSelectedIndex(0); GridBagConstraints gbc_volumeSampleComboBox = new GridBagConstraints(); gbc_volumeSampleComboBox.fill = GridBagConstraints.HORIZONTAL; gbc_volumeSampleComboBox.gridwidth = 3; gbc_volumeSampleComboBox.insets = new Insets(0, 0, 5, 0); gbc_volumeSampleComboBox.gridx = 1; gbc_volumeSampleComboBox.gridy = 3; add(volumeSampleComboBox, gbc_volumeSampleComboBox); shadingButton = new IcyToggleButton(new IcyIcon(ICON_SHADING, false)); shadingButton.setIconTextGap(8); shadingButton.setText("Shading"); shadingButton.setFocusable(false); shadingButton.setToolTipText("Enable volume shading"); GridBagConstraints gbc_shadingBtn = new GridBagConstraints(); gbc_shadingBtn.anchor = GridBagConstraints.WEST; gbc_shadingBtn.insets = new Insets(0, 0, 0, 5); gbc_shadingBtn.gridx = 0; gbc_shadingBtn.gridy = 4; add(shadingButton, gbc_shadingBtn); volumeAmbientField = new NumberTextField(); volumeAmbientField.setToolTipText("Ambient lighting coefficient"); GridBagConstraints gbc_volumeAmbientField = new GridBagConstraints(); gbc_volumeAmbientField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeAmbientField.insets = new Insets(0, 0, 0, 5); gbc_volumeAmbientField.gridx = 1; gbc_volumeAmbientField.gridy = 4; add(volumeAmbientField, gbc_volumeAmbientField); volumeAmbientField.setColumns(3); volumeDiffuseField = new NumberTextField(); volumeDiffuseField.setToolTipText("Diffuse lighting coefficient"); GridBagConstraints gbc_volumeDiffuseField = new GridBagConstraints(); gbc_volumeDiffuseField.insets = new Insets(0, 0, 0, 5); gbc_volumeDiffuseField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeDiffuseField.gridx = 2; gbc_volumeDiffuseField.gridy = 4; add(volumeDiffuseField, gbc_volumeDiffuseField); volumeDiffuseField.setColumns(3); volumeSpecularField = new NumberTextField(); volumeSpecularField.setToolTipText("Specular lighting coefficient"); GridBagConstraints gbc_volumeSpecularField = new GridBagConstraints(); gbc_volumeSpecularField.fill = GridBagConstraints.HORIZONTAL; gbc_volumeSpecularField.gridx = 3; gbc_volumeSpecularField.gridy = 4; add(volumeSpecularField, gbc_volumeSpecularField); volumeSpecularField.setColumns(3); } protected void updateState() { // if (isBoundingBoxVisible()) // { // boundingBoxGridCheckBox.setEnabled(true); // boundingBoxRulerCheckBox.setEnabled(true); // } // else // { // boundingBoxGridCheckBox.setEnabled(false); // boundingBoxRulerCheckBox.setEnabled(false); // } // switch (getVolumeMapperType()) // { // case RAYCAST_CPU_FIXEDPOINT: // case RAYCAST_GPU_OPENGL: // volumeSampleComboBox.setEnabled(true); // volumeBlendingComboBox.setEnabled(true); // break; // case TEXTURE2D_OPENGL: // case TEXTURE3D_OPENGL: // volumeSampleComboBox.setEnabled(false); // volumeBlendingComboBox.setEnabled(false); // break; // } } public Color getBackgroundColor() { return bgColorButton.getColor(); } public void setBackgroundColor(Color value) { bgColorButton.setColor(value); } public boolean getGPURendering() { return gpuMapperCheckBox.isSelected(); } public void setGPURendering(boolean value) { gpuMapperCheckBox.setSelected(value); } public int getVolumeInterpolation() { return volumeInterpolationComboBox.getSelectedIndex(); } public void setVolumeInterpolation(int value) { volumeInterpolationComboBox.setSelectedIndex(value); } public VtkVolumeBlendType getVolumeBlendingMode() { if (volumeBlendingComboBox.getSelectedIndex() == -1) return null; return (VtkVolumeBlendType) volumeBlendingComboBox.getSelectedItem(); } public void setVolumeBlendingMode(VtkVolumeBlendType value) { volumeBlendingComboBox.setSelectedItem(value); } public int getVolumeSample() { return volumeSampleComboBox.getSelectedIndex(); } public void setVolumeSample(int value) { volumeSampleComboBox.setSelectedIndex(value); } public double getVolumeAmbient() { return volumeAmbientField.getNumericValue(); } public void setVolumeAmbient(double value) { volumeAmbientField.setNumericValue(value); } public double getVolumeDiffuse() { return volumeDiffuseField.getNumericValue(); } public void setVolumeDiffuse(double value) { volumeDiffuseField.setNumericValue(value); } public double getVolumeSpecular() { return volumeSpecularField.getNumericValue(); } public void setVolumeSpecular(double value) { volumeSpecularField.setNumericValue(value); } /** * @see VtkImageVolume#getShade() */ public boolean getVolumeShading() { return shadingButton.isSelected(); } /** * @see VtkImageVolume#setShade(boolean) */ public void setVolumeShading(boolean value) { if (shadingButton.isSelected() != value) shadingButton.doClick(); } /** * Add a SettingChange listener */ public void addSettingChangeListener(SettingChangeListener listener) { listenerList.add(SettingChangeListener.class, listener); } /** * Remove a SettingChange listener */ public void removeSettingChangeListener(SettingChangeListener listener) { listenerList.remove(SettingChangeListener.class, listener); } public void fireSettingChange(Object source, String propertyName, Object oldValue, Object newValue) { if ((oldValue != null) && (newValue != null) && oldValue.equals(newValue)) return; final PropertyChangeEvent event = new PropertyChangeEvent(source, propertyName, oldValue, newValue); final SettingChangeListener[] listeners = getListeners(SettingChangeListener.class); for (int i = 0; i < listeners.length; i++) listeners[i].settingChange(event); } @Override public void colorChanged(ColorChooserButton source) { if (source == bgColorButton) fireSettingChange(source, PROPERTY_BG_COLOR, null, source.getColor()); } @Override public void actionPerformed(ActionEvent e) { final Object source = e.getSource(); if (source == gpuMapperCheckBox) fireSettingChange(source, PROPERTY_MAPPER, Boolean.valueOf(!gpuMapperCheckBox.isSelected()), Boolean.valueOf(gpuMapperCheckBox.isSelected())); else if (source == volumeBlendingComboBox) fireSettingChange(source, PROPERTY_BLENDING, null, volumeBlendingComboBox.getSelectedItem()); else if (source == volumeSampleComboBox) fireSettingChange(source, PROPERTY_SAMPLE, Integer.valueOf(-1), Integer.valueOf(volumeSampleComboBox.getSelectedIndex())); else if (source == volumeInterpolationComboBox) fireSettingChange(source, PROPERTY_INTERPOLATION, Integer.valueOf(-1), Integer.valueOf(volumeInterpolationComboBox.getSelectedIndex())); else if (source == shadingButton) fireSettingChange(source, PROPERTY_SHADING, Integer.valueOf(-1), Boolean.valueOf(shadingButton.isSelected())); updateState(); } @Override public void textChanged(IcyTextField source, boolean validate) { if (!validate) return; if (source == volumeAmbientField) fireSettingChange(source, PROPERTY_AMBIENT, Double.valueOf(-1d), Double.valueOf(volumeAmbientField.getNumericValue())); else if (source == volumeDiffuseField) fireSettingChange(source, PROPERTY_DIFFUSE, Double.valueOf(-1d), Double.valueOf(volumeDiffuseField.getNumericValue())); else if (source == volumeSpecularField) fireSettingChange(source, PROPERTY_SPECULAR, Double.valueOf(-1d), Double.valueOf(volumeSpecularField.getNumericValue())); updateState(); } public static interface SettingChangeListener extends EventListener { public void settingChange(PropertyChangeEvent evt); } }