package org.geogebra.desktop.geogebra3D.gui.dialogs.options; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextField; import org.geogebra.common.awt.GColor; import org.geogebra.common.euclidian.EuclidianView; import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoClippingCube3D; import org.geogebra.common.main.settings.EuclidianSettings; import org.geogebra.desktop.awt.GColorD; import org.geogebra.desktop.geogebra3D.gui.GuiResources3D; import org.geogebra.desktop.gui.GuiManagerD; import org.geogebra.desktop.gui.dialog.options.AxisPanel; import org.geogebra.desktop.gui.dialog.options.OptionsEuclidianD; import org.geogebra.desktop.gui.inputfield.MyTextFieldD; import org.geogebra.desktop.gui.util.LayoutUtil; import org.geogebra.desktop.main.AppD; /** * options for 3D view * * @author mathieu * */ public class OptionsEuclidian3DD extends OptionsEuclidianD { private AxisPanel3D zAxisPanel; private JCheckBox cbUseClipping, cbShowClipping; private JCheckBox cbYAxisVertical; private JRadioButton radioClippingSmall, radioClippingMedium, radioClippingLarge; private JPanel clippingOptionsPanel, boxSizePanel; private JCheckBox cbUseLight; /** * constructor * * @param app * application * @param view * 3D view */ public OptionsEuclidian3DD(AppD app, EuclidianView view) { super(app, view); enableStuff(false); updateGUI(); } @Override protected void initAxesOptionsPanel() { // y axis is vertical cbYAxisVertical = new JCheckBox(loc.getMenu("YAxisVertical")); super.initAxesOptionsPanel(); } @Override protected void fillAxesOptionsPanel() { axesOptionsPanel.add(LayoutUtil.flowPanel(cbShowAxes)); axesOptionsPanel.add(LayoutUtil.flowPanel(cbYAxisVertical)); axesOptionsPanel.add(LayoutUtil.flowPanel(lblAxisLabelStyle, cbAxisLabelSerif, cbAxisLabelBold, cbAxisLabelItalic)); } @Override protected void fillGridPanel(JPanel showGridPanel, JPanel gridPanel) { gridPanel.add(showGridPanel); gridPanel.add(typePanel); } @Override protected void setTypePanelLabel() { typePanel.setBorder(LayoutUtil.titleBorder( loc.getMenu("GridType") + " : " + loc.getMenu("Cartesian"))); } @Override protected void addComboGridType() { // TODO remove this when implemented } @Override protected JPanel buildBasicPanel() { // ------------------------------------- // clipping options panel clippingOptionsPanel = new JPanel(); clippingOptionsPanel.setLayout( new BoxLayout(clippingOptionsPanel, BoxLayout.Y_AXIS)); // clipping cbUseClipping = new JCheckBox(loc.getMenu("UseClipping")); clippingOptionsPanel.add(cbUseClipping); clippingOptionsPanel.add(Box.createRigidArea(new Dimension(10, 0))); cbShowClipping = new JCheckBox(loc.getMenu("ShowClipping")); clippingOptionsPanel.add(cbShowClipping); boxSizePanel = new JPanel(); boxSizePanel.setLayout(new BoxLayout(boxSizePanel, BoxLayout.Y_AXIS)); radioClippingSmall = new JRadioButton(loc.getMenu("small")); radioClippingMedium = new JRadioButton(loc.getMenu("medium")); radioClippingLarge = new JRadioButton(loc.getMenu("large")); boxSizePanel.add(radioClippingSmall); boxSizePanel.add(radioClippingMedium); boxSizePanel.add(radioClippingLarge); radioClippingSmall.addActionListener(this); radioClippingMedium.addActionListener(this); radioClippingLarge.addActionListener(this); ButtonGroup boxSizeGroup = new ButtonGroup(); boxSizeGroup.add(radioClippingSmall); boxSizeGroup.add(radioClippingMedium); boxSizeGroup.add(radioClippingLarge); // ------------------------------------- JPanel basicPanel = super.buildBasicPanel(); basicPanel.add(clippingOptionsPanel); basicPanel.add(boxSizePanel); return basicPanel; } @Override protected void fillMiscPanel() { // TODO remove this override miscPanel.add(LayoutUtil.flowPanel(backgroundColor, btBackgroundColor)); miscPanel.add(LayoutUtil.flowPanel(cbUseLight)); } @Override protected void initMiscPanel() { // use light cbUseLight = new JCheckBox(); cbUseLight.addActionListener(this); super.initMiscPanel(); } private void enableStuff(boolean flag) { // TODO remove when implemented // tfMinX.setEnabled(flag); // tfMaxX.setEnabled(flag); // tfMinY.setEnabled(flag); // tfMaxY.setEnabled(flag); // // btAxesColor.setEnabled(flag); // cbAxesStyle.setEnabled(flag); // cbShowMouseCoords.setEnabled(flag); // cbTooltips.setEnabled(flag); // // // ((AxisPanel3D) xAxisPanel).enableStuff(flag); // // ((AxisPanel3D) yAxisPanel).enableStuff(flag); // // zAxisPanel.enableStuff(flag); // // cbGridManualTick.setEnabled(flag); // ncbGridTickX.setEnabled(flag); // ncbGridTickY.setEnabled(flag); // cbGridTickAngle.setEnabled(flag); // cbGridStyle.setEnabled(flag); // cbGridType.setEnabled(flag); // cbBoldGrid.setEnabled(flag); // btGridColor.setEnabled(flag); } @Override protected void addDimPanel(JPanel basicPanel) { // TODO remove this and implement stuff for 3D } @Override public void updateGUI() { super.updateGUI(); // y axis is vertical cbYAxisVertical.removeActionListener(this); cbYAxisVertical .setSelected(((EuclidianView3D) view).getYAxisVertical()); cbYAxisVertical.addActionListener(this); // misc cbUseLight.removeActionListener(this); cbUseLight.setSelected(((EuclidianView3D) view).getUseLight()); cbUseLight.addActionListener(this); // clipping panel cbUseClipping.removeActionListener(this); cbUseClipping.setSelected(((EuclidianView3D) view).useClippingCube()); cbUseClipping.addActionListener(this); cbShowClipping.removeActionListener(this); cbShowClipping.setSelected(((EuclidianView3D) view).showClippingCube()); cbShowClipping.addActionListener(this); /* * radioClippingSmall.removeActionListener(this); * radioClippingMedium.removeActionListener(this); * radioClippingLarge.removeActionListener(this); */ int flag = ((EuclidianView3D) view).getClippingReduction(); radioClippingSmall .setSelected(flag == GeoClippingCube3D.REDUCTION_SMALL); radioClippingMedium .setSelected(flag == GeoClippingCube3D.REDUCTION_MEDIUM); radioClippingLarge .setSelected(flag == GeoClippingCube3D.REDUCTION_LARGE); /* * radioClippingSmall.addActionListener(this); * radioClippingMedium.addActionListener(this); * radioClippingLarge.addActionListener(this); */ // z axis panel zAxisPanel.updatePanel(); // projection // tfPersp.removeActionListener(this); tfPersp.setText("" + (int) ((EuclidianView3D) view) .getProjectionPerspectiveEyeDistance()); // tfPersp.addActionListener(this); tfGlassesEyeSep .setText("" + (int) ((EuclidianView3D) view).getEyeSep()); cbGlassesGray .setSelected(((EuclidianView3D) view).isGlassesGrayScaled()); cbGlassesShutDownGreen .setSelected(((EuclidianView3D) view).isGlassesShutDownGreen()); tfObliqueAngle.setText( "" + ((EuclidianView3D) view).getProjectionObliqueAngle()); tfObliqueFactor.setText( "" + ((EuclidianView3D) view).getProjectionObliqueFactor()); } @Override protected void initAxisPanels() { xAxisPanel = new AxisPanel3D(app, view, 0); yAxisPanel = new AxisPanel3D(app, view, 1); zAxisPanel = new AxisPanel3D(app, view, 2); } @Override protected void addTabs() { super.addTabs(); tabbedPane.addTab("", buildProjectionPanel()); } @Override protected void addAxisTabs() { super.addAxisTabs(); tabbedPane.addTab("", new JScrollPane(zAxisPanel)); } private JLabel[] projectionLabel; private JTextField tfPersp, tfGlassesEyeSep, tfObliqueAngle, tfObliqueFactor; private JLabel tfPerspLabel, tfGlassesLabel, tfObliqueAngleLabel, tfObliqueFactorLabel; private ProjectionButtons projectionButtons; private JCheckBox cbGlassesGray; private JLabel cbGlassesGrayLabel; private JCheckBox cbGlassesShutDownGreen; private JLabel cbGlassesShutDownGreenLabel; private class ProjectionButtons { private JButton[] buttons; private int buttonSelected; private EuclidianView3D view; private ProjectionButtons(OptionsEuclidian3DD options) { view = (EuclidianView3D) options.view; buttons = new JButton[4]; buttons[EuclidianView3D.PROJECTION_ORTHOGRAPHIC] = new JButton( app.getScaledIcon(GuiResources3D.PROJECTION_ORTOGRAPHIC)); buttons[EuclidianView3D.PROJECTION_PERSPECTIVE] = new JButton( app.getScaledIcon(GuiResources3D.PROJECTION_PERSPECTIVE)); buttons[EuclidianView3D.PROJECTION_GLASSES] = new JButton( app.getScaledIcon(GuiResources3D.PROJECTION_GLASSES)); buttons[EuclidianView3D.PROJECTION_OBLIQUE] = new JButton( app.getScaledIcon(GuiResources3D.PROJECTION_OBLIQUE)); for (int i = 0; i < 4; i++) { buttons[i].addActionListener(options); } buttonSelected = view.getProjection(); buttons[buttonSelected].setSelected(true); } JButton getButton(int i) { return buttons[i]; } void setSelected(int i) { buttons[buttonSelected].setSelected(false); buttonSelected = i; buttons[buttonSelected].setSelected(true); } public void updateIcons() { if (buttons == null) { return; } buttons[EuclidianView3D.PROJECTION_ORTHOGRAPHIC].setIcon( app.getScaledIcon(GuiResources3D.PROJECTION_ORTOGRAPHIC)); buttons[EuclidianView3D.PROJECTION_PERSPECTIVE].setIcon( app.getScaledIcon(GuiResources3D.PROJECTION_PERSPECTIVE)); buttons[EuclidianView3D.PROJECTION_GLASSES].setIcon( app.getScaledIcon(GuiResources3D.PROJECTION_GLASSES)); buttons[EuclidianView3D.PROJECTION_OBLIQUE].setIcon( app.getScaledIcon(GuiResources3D.PROJECTION_OBLIQUE)); } } private JPanel buildProjectionPanel() { // JLabel label; projectionLabel = new JLabel[4]; // "orthographic", "perspective", // "glasses" etc. for (int i = 0; i < 4; i++) { projectionLabel[i] = new JLabel(""); } projectionButtons = new ProjectionButtons(this); JPanel orthoPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); orthoPanel.add(projectionButtons .getButton(EuclidianView3D.PROJECTION_ORTHOGRAPHIC)); orthoPanel.add(projectionLabel[0]); JPanel perspPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); perspPanel.add(projectionButtons .getButton(EuclidianView3D.PROJECTION_PERSPECTIVE)); perspPanel.add(projectionLabel[1]); tfPerspLabel = new JLabel(""); perspPanel.add(tfPerspLabel); tfPersp = new MyTextFieldD(app, 5); tfPersp.addActionListener(this); tfPersp.addFocusListener(this); perspPanel.add(tfPersp); JPanel glassesPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); glassesPanel.add(projectionButtons .getButton(EuclidianView3D.PROJECTION_GLASSES)); glassesPanel.add(projectionLabel[2]); tfGlassesLabel = new JLabel(""); glassesPanel.add(tfGlassesLabel); tfGlassesEyeSep = new MyTextFieldD(app, 3); tfGlassesEyeSep.addActionListener(this); tfGlassesEyeSep.addFocusListener(this); glassesPanel.add(tfGlassesEyeSep); cbGlassesGray = new JCheckBox(); cbGlassesGray.addActionListener(this); cbGlassesGrayLabel = new JLabel(""); glassesPanel.add(cbGlassesGray); glassesPanel.add(cbGlassesGrayLabel); cbGlassesShutDownGreen = new JCheckBox(); cbGlassesShutDownGreen.addActionListener(this); cbGlassesShutDownGreenLabel = new JLabel(""); glassesPanel.add(cbGlassesShutDownGreen); glassesPanel.add(cbGlassesShutDownGreenLabel); JPanel cavPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); cavPanel.add(projectionButtons .getButton(EuclidianView3D.PROJECTION_OBLIQUE)); cavPanel.add(projectionLabel[EuclidianView3D.PROJECTION_OBLIQUE]); tfObliqueAngleLabel = new JLabel(""); cavPanel.add(tfObliqueAngleLabel); tfObliqueAngle = new MyTextFieldD(app, 4); tfObliqueAngle.addActionListener(this); tfObliqueAngle.addFocusListener(this); cavPanel.add(tfObliqueAngle); tfObliqueFactorLabel = new JLabel(""); cavPanel.add(tfObliqueFactorLabel); tfObliqueFactor = new MyTextFieldD(app, 4); tfObliqueFactor.addActionListener(this); tfObliqueFactor.addFocusListener(this); cavPanel.add(tfObliqueFactor); // ========================================== // create basic panel and add all sub panels JPanel northPanel = new JPanel(); northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS)); northPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 2, 5)); /* * northPanel.add(dimPanel); northPanel.add(Box.createRigidArea(new * Dimension(0,16))); northPanel.add(axesOptionsPanel); * northPanel.add(Box.createRigidArea(new Dimension(0,16))); * northPanel.add(bgPanel); */ northPanel.add(orthoPanel); northPanel.add(perspPanel); northPanel.add(glassesPanel); northPanel.add(cavPanel); // use a BorderLayout to keep sub panels together JPanel ret = new JPanel(new BorderLayout()); ret.add(northPanel, BorderLayout.NORTH); return ret; } @Override protected void setTabLabels() { tabbedPane.setTitleAt(0, loc.getMenu("Properties.Basic")); tabbedPane.setTitleAt(1, loc.getMenu("xAxis")); tabbedPane.setTitleAt(2, loc.getMenu("yAxis")); tabbedPane.setTitleAt(3, loc.getMenu("zAxis")); tabbedPane.setTitleAt(4, loc.getMenu("Grid")); tabbedPane.setTitleAt(5, loc.getMenu("Projection")); } @Override public void setLabels() { super.setLabels(); zAxisPanel.setLabels(); // y axis is vertical cbYAxisVertical.setText(loc.getMenu("YAxisVertical")); // misc cbUseLight.setText(loc.getMenu("UseLighting")); // clipping tab clippingOptionsPanel .setBorder(LayoutUtil.titleBorder(loc.getPlain("Clipping"))); cbUseClipping.setText(loc.getMenu("UseClipping")); cbShowClipping.setText(loc.getMenu("ShowClipping")); boxSizePanel.setBorder(LayoutUtil.titleBorder(loc.getMenu("BoxSize"))); radioClippingSmall.setText(loc.getMenu("BoxSize.small")); radioClippingMedium.setText(loc.getMenu("BoxSize.medium")); radioClippingLarge.setText(loc.getMenu("BoxSize.large")); // perspective tab projectionLabel[0].setText(loc.getMenu("Orthographic")); projectionLabel[1].setText(loc.getMenu("Perspective") + ":"); tfPerspLabel.setText(loc.getMenu("EyeDistance") + ":"); projectionLabel[2].setText(loc.getMenu("Glasses") + ":"); tfGlassesLabel.setText(loc.getMenu("EyesSeparation") + ":"); cbGlassesGrayLabel.setText(loc.getMenu("GrayScale")); cbGlassesShutDownGreenLabel.setText(loc.getMenu("ShutDownGreen")); projectionLabel[3].setText(loc.getMenu("Oblique") + ":"); tfObliqueAngleLabel.setText(loc.getMenu("Angle") + ":"); tfObliqueFactorLabel.setText(loc.getMenu("Dilate.Factor") + ":"); projectionButtons.updateIcons(); projectionButtons.setSelected(((EuclidianView3D) view).getProjection()); } @Override protected void doActionPerformed(Object source) { if (source == cbYAxisVertical) { ((EuclidianView3D) view) .setYAxisVertical(cbYAxisVertical.isSelected()); } else if (source == cbUseLight) { ((EuclidianView3D) view).getSettings() .setUseLight(cbUseLight.isSelected()); } else if (source == cbUseClipping) { ((EuclidianView3D) view) .setUseClippingCube(cbUseClipping.isSelected()); } else if (source == cbShowClipping) { ((EuclidianView3D) view) .setShowClippingCube(cbShowClipping.isSelected()); } else if (source == radioClippingSmall) { ((EuclidianView3D) view).getSettings() .setClippingReduction(GeoClippingCube3D.REDUCTION_SMALL); } else if (source == radioClippingMedium) { ((EuclidianView3D) view).getSettings() .setClippingReduction(GeoClippingCube3D.REDUCTION_MEDIUM); } else if (source == radioClippingLarge) { ((EuclidianView3D) view).getSettings() .setClippingReduction(GeoClippingCube3D.REDUCTION_LARGE); } else if (source == tfPersp) { try { int val = Integer.parseInt(tfPersp.getText()); int min = 1; if (val < min) { val = min; tfPersp.setText("" + val); } ((EuclidianView3D) view).getSettings() .setProjectionPerspectiveEyeDistance(val); } catch (NumberFormatException e) { tfPersp.setText("" + (int) ((EuclidianView3D) view) .getProjectionPerspectiveEyeDistance()); } } else if (source == tfGlassesEyeSep) { try { int val = Integer.parseInt(tfGlassesEyeSep.getText()); if (val < 0) { val = 0; tfGlassesEyeSep.setText("" + val); } ((EuclidianView3D) view).getSettings().setEyeSep(val); } catch (NumberFormatException e) { tfGlassesEyeSep.setText( "" + (int) ((EuclidianView3D) view).getEyeSep()); } } else if (source == tfObliqueAngle) { try { double val = Double.parseDouble(tfObliqueAngle.getText()); if (!Double.isNaN(val)) { ((EuclidianView3D) view).getSettings() .setProjectionObliqueAngle(val); } } catch (NumberFormatException e) { tfObliqueAngle.setText("" + ((EuclidianView3D) view).getProjectionObliqueAngle()); } } else if (source == tfObliqueFactor) { try { double val = Double.parseDouble(tfObliqueFactor.getText()); if (!Double.isNaN(val)) { if (val < 0) { val = 0; tfObliqueFactor.setText("" + val); } ((EuclidianView3D) view).setProjectionObliqueFactor(val); } } catch (NumberFormatException e) { tfObliqueFactor.setText("" + ((EuclidianView3D) view) .getProjectionObliqueFactor()); } } else if (source == projectionButtons .getButton(EuclidianView3D.PROJECTION_ORTHOGRAPHIC)) { ((EuclidianView3D) view).getSettings() .setProjection(EuclidianView3D.PROJECTION_ORTHOGRAPHIC); projectionButtons .setSelected(EuclidianView3D.PROJECTION_ORTHOGRAPHIC); } else if (source == projectionButtons .getButton(EuclidianView3D.PROJECTION_PERSPECTIVE)) { ((EuclidianView3D) view).getSettings() .setProjection(EuclidianView3D.PROJECTION_PERSPECTIVE); projectionButtons .setSelected(EuclidianView3D.PROJECTION_PERSPECTIVE); } else if (source == projectionButtons .getButton(EuclidianView3D.PROJECTION_GLASSES)) { ((EuclidianView3D) view).getSettings() .setProjection(EuclidianView3D.PROJECTION_GLASSES); projectionButtons.setSelected(EuclidianView3D.PROJECTION_GLASSES); } else if (source == projectionButtons .getButton(EuclidianView3D.PROJECTION_OBLIQUE)) { ((EuclidianView3D) view).getSettings() .setProjection(EuclidianView3D.PROJECTION_OBLIQUE); projectionButtons.setSelected(EuclidianView3D.PROJECTION_OBLIQUE); } else if (source == cbGlassesGray) { ((EuclidianView3D) view) .setGlassesGrayScaled(cbGlassesGray.isSelected()); } else if (source == cbGlassesShutDownGreen) { ((EuclidianView3D) view).setGlassesShutDownGreen( cbGlassesShutDownGreen.isSelected()); } else { super.doActionPerformed(source); } } @Override protected void updateFont(Font font) { super.updateFont(font); zAxisPanel.updateFont(); } private static class AxisPanel3D extends AxisPanel { private static final long serialVersionUID = 1L; final static protected int AXIS_Z = 2; public AxisPanel3D(AppD app, EuclidianView view, int axis) { super(app, view, axis); } @Override protected String getString() { if (getModel().getAxis() == AXIS_Z) { return "zAxis"; } return super.getString(); } @Override protected void addCrossPanel(JPanel crossPanel) { // TODO implement this } } @Override protected void actionBtBackgroundColor() { EuclidianSettings settings = view.getSettings(); GColor old = settings == null ? ((EuclidianView3D) view).getBackground() : settings.getBackground(); GColor color = GColorD.newColor( ((GuiManagerD) (app.getGuiManager())).showColorChooser(old)); if (settings == null) { view.setBackground(color); } else { settings.setBackground(color); } } }