package org.geogebra.web.geogebra3D.web.gui.dialog.options; import org.geogebra.common.awt.GColor; import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon; import org.geogebra.common.euclidian.event.KeyEvent; import org.geogebra.common.euclidian.event.KeyHandler; import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoClippingCube3D; import org.geogebra.common.gui.dialog.options.model.EuclidianOptionsModel; import org.geogebra.web.geogebra3D.web.gui.images.StyleBar3DResources; import org.geogebra.web.html5.event.FocusListenerW; import org.geogebra.web.html5.gui.inputfield.AutoCompleteTextFieldW; import org.geogebra.web.html5.gui.util.LayoutUtilW; import org.geogebra.web.html5.main.AppW; import org.geogebra.web.html5.util.tabpanel.MultiRowsTabBar; import org.geogebra.web.web.gui.dialog.options.OptionsEuclidianW; import org.geogebra.web.web.gui.util.MyToggleButtonW; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RadioButton; import com.google.gwt.user.client.ui.ToggleButton; import com.google.gwt.user.client.ui.Widget; /** * Properties for 3D view (web) * * @author mathieu * */ @SuppressWarnings("javadoc") public class OptionsEuclidian3DW extends OptionsEuclidianW { private AxisTab zAxisTab; private ProjectionTab projectionTab; /** * basic tab for 3D * * @author mathieu * */ protected class BasicTab3D extends BasicTab { private CheckBox cbYAxisVertical; private CheckBox cbUseClipping, cbShowClipping; private FlowPanel clippingOptionsPanel, boxSizePanel; private Label clippingOptionsTitle, boxSizeTitle; private RadioButton radioClippingSmall, radioClippingMedium, radioClippingLarge; private CheckBox cbUseLight; /** * constructor */ public BasicTab3D() { super(); addClippingOptionsPanel(); } @Override protected void indentDimPanel() { // TODO remove this and implement stuff for 3D } @Override protected void addToDimPanel(Widget w) { // TODO remove this and implement stuff for 3D } @Override protected void fillMiscPanel() { miscPanel.add(LayoutUtilW.panelRow(backgroundColorLabel, btBackgroundColor)); miscPanel.add(LayoutUtilW.panelRow(cbUseLight)); } @Override protected void addMiscPanel() { cbUseLight = new CheckBox(); super.addMiscPanel(); cbUseLight.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().getSettings() .setUseLight( cbUseLight.getValue()); view.repaintView(); } }); } @Override protected void applyBackgroundColor(GColor color) { model.applyBackgroundColor(3, color); } @Override protected void addAxesOptionsPanel() { cbYAxisVertical = new CheckBox(); cbYAxisVertical.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().setYAxisVertical(cbYAxisVertical .getValue()); view.repaintView(); } }); super.addAxesOptionsPanel(); } @Override protected void fillAxesOptionsPanel() { axesOptionsPanel.add(LayoutUtilW.panelRow(cbShowAxes)); axesOptionsPanel.add(LayoutUtilW.panelRow(cbYAxisVertical)); axesOptionsPanel.add(LayoutUtilW.panelRow(lblAxisLabelStyle, cbAxisLabelSerif, cbAxisLabelBold, cbAxisLabelItalic)); } private void addClippingOptionsPanel() { // clipping options panel clippingOptionsTitle = new Label(); clippingOptionsTitle.setStyleName("panelTitle"); clippingOptionsPanel = new FlowPanel(); cbUseClipping = new CheckBox(); cbUseClipping.setStyleName("checkBoxPanel"); clippingOptionsPanel.add(cbUseClipping); // clippingOptionsPanel.add(Box.createRigidArea(new Dimension(10, // 0))); cbShowClipping = new CheckBox(); cbShowClipping.setStyleName("checkBoxPanel"); clippingOptionsPanel.add(cbShowClipping); add(clippingOptionsTitle); indent(clippingOptionsPanel); cbUseClipping.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().setUseClippingCube(cbUseClipping .getValue()); view.repaintView(); } }); cbShowClipping.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().setShowClippingCube(cbShowClipping .getValue()); view.repaintView(); } }); // clipping box size boxSizeTitle = new Label(); boxSizeTitle.setStyleName("panelTitle"); boxSizePanel = new FlowPanel(); radioClippingSmall = new RadioButton("radioClipping"); radioClippingMedium = new RadioButton("radioClipping"); radioClippingLarge = new RadioButton("radioClipping"); boxSizePanel.add(radioClippingSmall); boxSizePanel.add(radioClippingMedium); boxSizePanel.add(radioClippingLarge); add(boxSizeTitle); indent(boxSizePanel); radioClippingSmall.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().getSettings() .setClippingReduction( GeoClippingCube3D.REDUCTION_SMALL); view.repaintView(); } }); radioClippingMedium.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().getSettings() .setClippingReduction( GeoClippingCube3D.REDUCTION_MEDIUM); view.repaintView(); } }); radioClippingLarge.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().getSettings() .setClippingReduction( GeoClippingCube3D.REDUCTION_LARGE); view.repaintView(); } }); } /** * update clipping properties (use and size) */ public void update3DProperties() { cbYAxisVertical.setValue(get3dview() .getYAxisVertical()); cbUseLight.setValue(get3dview().getUseLight()); cbUseClipping.setValue(get3dview().useClippingCube()); cbShowClipping .setValue(get3dview().showClippingCube()); int flag = get3dview().getClippingReduction(); radioClippingSmall .setValue(flag == GeoClippingCube3D.REDUCTION_SMALL); radioClippingMedium .setValue(flag == GeoClippingCube3D.REDUCTION_MEDIUM); radioClippingLarge .setValue(flag == GeoClippingCube3D.REDUCTION_LARGE); } @Override public void setLabels() { super.setLabels(); cbYAxisVertical.setText(loc.getMenu("YAxisVertical")); cbUseLight.setText(loc.getMenu("UseLighting")); clippingOptionsTitle.setText(loc.getMenu("Clipping")); cbUseClipping.setText(loc.getMenu("UseClipping")); cbShowClipping.setText(loc.getMenu("ShowClipping")); boxSizeTitle.setText(loc.getMenu("BoxSize")); radioClippingSmall.setText(loc.getMenu("BoxSize.small")); radioClippingMedium.setText(loc.getMenu("BoxSize.medium")); radioClippingLarge.setText(loc.getMenu("BoxSize.large")); } } @Override protected GridTab newGridTab() { return new GridTab3D(); } class GridTab3D extends GridTab { @Override protected void addGridType(FlowPanel gridTickAnglePanel) { // TODO remove this when implemented } @Override protected void addOnlyFor2D(Widget w) { // TODO remove this when implemented } @Override protected void setGridTypeLabel() { lblGridType.setText(loc.getMenu("GridType") + " : " + loc.getMenu("Cartesian")); } } private class ProjectionTab extends EuclidianTab { private ProjectionButtons projectionButtons; private FlowPanel orthoPanel, perspPanel, obliquePanel, glassesPanel; private Label orthoTitle, perspTitle, obliqueTitle, glassesTitle; private AutoCompleteTextFieldW tfPersp, tfGlassesEyeSep, tfObliqueAngle, tfObliqueFactor; private Label tfPerspLabel, tfGlassesLabel, tfObliqueAngleLabel, tfObliqueFactorLabel; private CheckBox cbGlassesGray, cbGlassesShutDownGreen; private class ProjectionButtons implements ClickHandler { private MyToggleButtonW[] buttons; private int buttonSelected; ProjectionButtons() { buttons = new MyToggleButtonW[4]; buttons[EuclidianView3D.PROJECTION_ORTHOGRAPHIC] = new MyToggleButtonW( new Image(StyleBar3DResources.INSTANCE .viewOrthographic())); buttons[EuclidianView3D.PROJECTION_PERSPECTIVE] = new MyToggleButtonW( new Image( StyleBar3DResources.INSTANCE.viewPerspective())); buttons[EuclidianView3D.PROJECTION_GLASSES] = new MyToggleButtonW( new Image(StyleBar3DResources.INSTANCE.viewGlasses())); buttons[EuclidianView3D.PROJECTION_OBLIQUE] = new MyToggleButtonW( new Image(StyleBar3DResources.INSTANCE.viewOblique())); for (int i = 0; i < 4; i++) { buttons[i].addClickHandler(this); } buttonSelected = get3dview().getProjection(); buttons[buttonSelected].setDown(true); } public ToggleButton getButton(int i) { return buttons[i]; } @Override public void onClick(ClickEvent event) { MyToggleButtonW source = (MyToggleButtonW) event.getSource(); if (source == buttons[get3dview().getProjection()]) { source.setDown(true); return; } for (int i = 0; i < buttons.length; i++) { if (buttons[i].equals(source)) { get3dview().getSettings().setProjection(i); view.repaintView(); buttons[i].setDown(true); } else { buttons[i].setDown(false); } } } } public ProjectionTab() { super(); projectionButtons = new ProjectionButtons(); // orthographic projection orthoTitle = new Label(""); orthoTitle.setStyleName("panelTitle"); orthoPanel = new FlowPanel(); orthoPanel.add(projectionButtons .getButton(EuclidianView3D.PROJECTION_ORTHOGRAPHIC)); add(orthoTitle); indent(orthoPanel); // perspective projection perspTitle = new Label(""); perspTitle.setStyleName("panelTitle"); perspPanel = new FlowPanel(); tfPerspLabel = new Label(""); tfPersp = getTextField(); tfPersp.addKeyHandler(new KeyHandler() { @Override public void keyReleased(KeyEvent e) { if (e.isEnterKey()) { processPerspText(); } } }); tfPersp.addFocusListener(new FocusListenerW(this) { @Override protected void wrapFocusLost() { processPerspText(); } }); FlowPanel tfPerspPanel = new FlowPanel(); tfPerspPanel.setStyleName("panelRowCell"); tfPerspPanel.add(tfPerspLabel); tfPerspPanel.add(tfPersp); perspPanel.add(LayoutUtilW.panelRow(projectionButtons .getButton(EuclidianView3D.PROJECTION_PERSPECTIVE), tfPerspPanel)); add(perspTitle); indent(perspPanel); // glasses projection (two images) glassesTitle = new Label(""); glassesTitle.setStyleName("panelTitle"); glassesPanel = new FlowPanel(); tfGlassesLabel = new Label(""); tfGlassesEyeSep = getTextField(); tfGlassesEyeSep.addKeyHandler(new KeyHandler() { @Override public void keyReleased(KeyEvent e) { if (e.isEnterKey()) { processGlassesEyeSepText(); } } }); tfGlassesEyeSep.addFocusListener(new FocusListenerW(this) { @Override protected void wrapFocusLost() { processGlassesEyeSepText(); } }); cbGlassesGray = new CheckBox(loc.getMenu("GrayScale")); cbGlassesGray.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview().setGlassesGrayScaled(cbGlassesGray .getValue()); view.repaintView(); } }); cbGlassesShutDownGreen = new CheckBox(loc.getMenu("ShutDownGreen")); cbGlassesShutDownGreen.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { get3dview() .setGlassesShutDownGreen(cbGlassesShutDownGreen .getValue()); view.repaintView(); } }); FlowPanel tfGlassesPanel = new FlowPanel(); tfGlassesPanel.setStyleName("panelRowCell"); tfGlassesPanel.add(tfGlassesLabel); tfGlassesPanel.add(tfGlassesEyeSep); tfGlassesPanel.add(cbGlassesGray); tfGlassesPanel.add(cbGlassesShutDownGreen); glassesPanel.add(LayoutUtilW.panelRow(projectionButtons .getButton(EuclidianView3D.PROJECTION_GLASSES), tfGlassesPanel)); add(glassesTitle); indent(glassesPanel); // oblique projection obliqueTitle = new Label(""); obliqueTitle.setStyleName("panelTitle"); obliquePanel = new FlowPanel(); tfObliqueAngleLabel = new Label(""); tfObliqueAngle = getTextField(); tfObliqueAngle.addKeyHandler(new KeyHandler() { @Override public void keyReleased(KeyEvent e) { if (e.isEnterKey()) { processObliqueAngleText(); } } }); tfObliqueAngle.addFocusListener(new FocusListenerW(this) { @Override protected void wrapFocusLost() { processObliqueAngleText(); } }); tfObliqueFactorLabel = new Label(""); tfObliqueFactor = getTextField(); tfObliqueFactor.addKeyHandler(new KeyHandler() { @Override public void keyReleased(KeyEvent e) { if (e.isEnterKey()) { processObliqueFactorText(); } } }); tfObliqueFactor.addFocusListener(new FocusListenerW(this) { @Override protected void wrapFocusLost() { processObliqueFactorText(); } }); FlowPanel tfObliquePanel = new FlowPanel(); tfObliquePanel.setStyleName("panelRowCell"); tfObliquePanel.add(tfObliqueAngleLabel); tfObliquePanel.add(tfObliqueAngle); tfObliquePanel.add(tfObliqueFactorLabel); tfObliquePanel.add(tfObliqueFactor); obliquePanel.add(LayoutUtilW.panelRow(projectionButtons .getButton(EuclidianView3D.PROJECTION_OBLIQUE), tfObliquePanel)); add(obliqueTitle); indent(obliquePanel); } protected void processPerspText() { try { int val = Integer.parseInt(tfPersp.getText()); int min = 1; if (val < min) { val = min; tfPersp.setText("" + val); } get3dview().getSettings() .setProjectionPerspectiveEyeDistance(val); view.repaintView(); } catch (NumberFormatException e) { tfPersp.setText("" + (int) get3dview() .getProjectionPerspectiveEyeDistance()); } } protected void processGlassesEyeSepText() { try { int val = Integer.parseInt(tfGlassesEyeSep.getText()); if (val < 0) { val = 0; tfGlassesEyeSep.setText("" + val); } get3dview().getSettings().setEyeSep(val); view.repaintView(); } catch (NumberFormatException e) { tfGlassesEyeSep.setText("" + (int) get3dview().getEyeSep()); } } protected void processObliqueAngleText() { try { double val = Double.parseDouble(tfObliqueAngle.getText()); if (!Double.isNaN(val)) { get3dview().getSettings() .setProjectionObliqueAngle(val); view.repaintView(); } } catch (NumberFormatException e) { tfObliqueAngle.setText("" + get3dview().getProjectionObliqueAngle()); } } protected void processObliqueFactorText() { try { double val = Double.parseDouble(tfObliqueFactor.getText()); if (!Double.isNaN(val)) { if (val < 0) { val = 0; tfObliqueFactor.setText("" + val); } get3dview().setProjectionObliqueFactor(val); view.repaintView(); } } catch (NumberFormatException e) { tfObliqueFactor .setText("" + get3dview() .getProjectionObliqueFactor()); } } protected void indent(FlowPanel panel) { FlowPanel indent = new FlowPanel(); indent.setStyleName("panelIndent"); indent.add(panel); add(indent); } @Override public void setLabels() { orthoTitle.setText(loc.getMenu("Orthographic")); perspTitle.setText(loc.getMenu("Perspective")); tfPerspLabel .setText(loc.getMenu(loc.getMenu("EyeDistance") + ":")); glassesTitle.setText(loc.getMenu("Glasses")); tfGlassesLabel.setText(loc.getMenu("EyesSeparation") + ":"); cbGlassesGray.setText(loc.getMenu("GrayScale")); cbGlassesShutDownGreen.setText(loc.getMenu("ShutDownGreen")); obliqueTitle.setText(loc.getMenu("Oblique")); tfObliqueAngleLabel.setText(loc.getMenu("Angle") + ":"); tfObliqueFactorLabel.setText(loc.getMenu("Dilate.Factor") + ":"); } /** * update text values */ public void updateGUI() { tfPersp.setText("" + (int) get3dview() .getProjectionPerspectiveEyeDistance()); tfGlassesEyeSep.setText("" + (int) get3dview().getEyeSep()); cbGlassesGray.setValue(get3dview() .isGlassesGrayScaled()); cbGlassesShutDownGreen.setValue(get3dview() .isGlassesShutDownGreen()); tfObliqueAngle.setText("" + get3dview().getProjectionObliqueAngle()); tfObliqueFactor.setText("" + get3dview().getProjectionObliqueFactor()); } } /** * constructor * * @param app * application * @param view * 3D view */ public OptionsEuclidian3DW(AppW app, EuclidianViewInterfaceCommon view) { super(app, view); } public EuclidianView3D get3dview() { // TODO Auto-generated method stub return (EuclidianView3D) view; } @Override protected BasicTab newBasicTab() { return new BasicTab3D(); } @Override public void updateGUI() { ((BasicTab3D) basicTab).update3DProperties(); projectionTab.updateGUI(); super.updateGUI(); } @Override public void setLabels() { MultiRowsTabBar tabBar = tabPanel.getTabBar(); super.setLabels(tabBar, 4); tabBar.setTabText(3, loc.getMenu("zAxis")); zAxisTab.setLabels(); tabBar.setTabText(5, loc.getMenu("Projection")); projectionTab.setLabels(); } @Override protected void addAxesTabs() { super.addAxesTabs(); addZAxisTab(); } @Override protected AxisTab newAxisTab(int axis) { return new AxisTab(axis, true); } private void addZAxisTab() { zAxisTab = newAxisTab(EuclidianOptionsModel.Z_AXIS); tabPanel.add(zAxisTab, "z"); } @Override protected void addTabs() { super.addTabs(); addProjectionTab(); } private void addProjectionTab() { projectionTab = new ProjectionTab(); tabPanel.add(projectionTab, "projection"); } }