/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
This program 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.
*/
package org.geogebra.desktop.gui.dialog;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.Border;
import org.geogebra.common.euclidian.smallscreen.AdjustSlider;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.geos.GeoAngle;
import org.geogebra.common.kernel.geos.GeoAngle.AngleStyle;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.desktop.gui.properties.SliderPanel;
import org.geogebra.desktop.gui.view.algebra.InputPanelD;
import org.geogebra.desktop.main.AppD;
import org.geogebra.desktop.main.LocalizationD;
/**
* Dialog for slider creation
*/
public class SliderDialogD extends JDialog
implements ActionListener, KeyListener, WindowListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton btOK, btCancel;
private JRadioButton rbNumber, rbAngle, rbInteger;
private InputPanelD tfLabel;
private JPanel optionPane;
private JCheckBox cbRandom;
private AppD app;
private SliderPanel sliderPanel;
private GeoElement geoResult;
private GeoNumeric number;
private GeoAngle angle;
private LocalizationD loc;
/**
* Creates a dialog to create a new GeoNumeric for a slider.
*
* @param x
* x-coordinate of slider in screen coords
* @param y
* x-coordinate of slider in screen coords
* @param app
* application
*/
public SliderDialogD(AppD app, int x, int y) {
super(app.getFrame(), false);
this.app = app;
this.loc = app.getLocalization();
addWindowListener(this);
// create temp geos that may be returned as result
Construction cons = app.getKernel().getConstruction();
number = new GeoNumeric(cons);
angle = new GeoAngle(cons);
// allow outside range 0-360
angle.setAngleStyle(AngleStyle.UNBOUNDED);
GeoNumeric.setSliderFromDefault(number, false);
GeoNumeric.setSliderFromDefault(angle, true);
number.setValue(1);
angle.setValue(45 * Math.PI / 180);
number.setSliderLocation(x, y, true);
angle.setSliderLocation(x, y, true);
geoResult = null;
createGUI();
}
private void createGUI() {
setTitle(loc.getMenu("Slider"));
setResizable(false);
// Create components to be displayed
// radio buttons for number or angle
ButtonGroup bg = new ButtonGroup();
rbNumber = new JRadioButton(loc.getMenu("Numeric"));
rbAngle = new JRadioButton(loc.getMenu("Angle"));
rbInteger = new JRadioButton(loc.getMenu("Integer"));
rbNumber.addActionListener(this);
rbAngle.addActionListener(this);
rbInteger.addActionListener(this);
bg.add(rbNumber);
bg.add(rbAngle);
bg.add(rbInteger);
rbNumber.setSelected(true);
// JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5,
// 5));
JPanel radioPanel = new JPanel();
radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS));
radioPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 20));
radioPanel.add(rbNumber);
radioPanel.add(rbAngle);
radioPanel.add(rbInteger);
// label textfield
tfLabel = new InputPanelD(number.getDefaultLabel(), app, 1, 10, true);
tfLabel.getTextComponent().addKeyListener(this);
Border border = BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder(loc.getMenu("Name")),
BorderFactory.createEmptyBorder(5, 5, 5, 5));
tfLabel.setBorder(border);
cbRandom = new JCheckBox(loc.getMenu("Random"));
// put together label textfield and radioPanel
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout(0, 0));
JPanel labelPanel = new JPanel(new BorderLayout(0, 0));
labelPanel.add(tfLabel, BorderLayout.NORTH);
labelPanel.add(cbRandom, BorderLayout.SOUTH);
topPanel.add(labelPanel, BorderLayout.CENTER);
topPanel.add(radioPanel, app.getLocalization().borderWest());
// slider panels
sliderPanel = new SliderPanel(app, null, true, false);
JPanel slPanel = new JPanel(new BorderLayout(0, 0));
GeoElement[] geos = { number };
slPanel.add(sliderPanel.updatePanel(geos), BorderLayout.CENTER);
// buttons
btOK = new JButton(loc.getMenu("OK"));
btOK.setActionCommand("OK");
btOK.addActionListener(this);
btCancel = new JButton(loc.getMenu("Cancel"));
btCancel.setActionCommand("Cancel");
btCancel.addActionListener(this);
JPanel btPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
btPanel.add(btOK);
btPanel.add(btCancel);
// Create the JOptionPane.
optionPane = new JPanel(new BorderLayout(5, 5));
optionPane.add(topPanel, BorderLayout.NORTH);
optionPane.add(slPanel, BorderLayout.CENTER);
optionPane.add(btPanel, BorderLayout.SOUTH);
optionPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Make this dialog display it.
setContentPane(optionPane);
app.setComponentOrientation(this);
pack();
setLocationRelativeTo(app.getFrame());
}
/**
* @return resulting slider
*/
public GeoElement getResult() {
if (geoResult != null) {
// set label of geoResult
String strLabel;
String text = tfLabel.getText();
try {
strLabel = app.getKernel().getAlgebraProcessor()
.parseLabel(text);
} catch (Exception e) {
strLabel = null;
}
geoResult.setLabel(strLabel);
// allow eg a=2 in the Name dialog to set the initial value
if (strLabel != null && text.indexOf('=') > -1
&& text.indexOf('=') == text.lastIndexOf('=')) {
try {
double val = Double
.parseDouble(text.substring(text.indexOf('=') + 1));
GeoNumeric geoNum = ((GeoNumeric) geoResult);
if (val > geoNum.getIntervalMax()) {
geoNum.setIntervalMax(val);
} else if (val < geoNum.getIntervalMin()) {
geoNum.setIntervalMin(val);
}
geoNum.setValue(val);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return geoResult;
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == btOK) {
geoResult = rbAngle.isSelected() ? angle : number;
getResult();
geoResult.setLabelMode(GeoElement.LABEL_NAME_VALUE);
geoResult.setLabelVisible(true);
geoResult.update();
if (!rbAngle.isSelected()) {
AdjustSlider.ensureOnScreen((GeoNumeric) geoResult,
app.getActiveEuclidianView());
}
((GeoNumeric) geoResult).setRandom(cbRandom.isSelected());
setVisible(false);
app.storeUndoInfo();
} else if (source == btCancel) {
setVisible(false);
} else if (source == rbNumber || source == rbAngle
|| source == rbInteger) {
GeoElement selGeo = rbAngle.isSelected() ? angle : number;
if (source == rbInteger) {
number.setAutoStep(false);
number.setAnimationStep(1);
number.setIntervalMin(1);
number.setIntervalMax(30);
} else if (source == rbNumber) {
GeoNumeric num = app.getKernel().getAlgoDispatcher()
.getDefaultNumber(false);
number.setAutoStep(num.isAutoStep());
number.setAnimationStep(num.getAnimationStep());
number.setIntervalMin(num.getIntervalMin());
number.setIntervalMax(num.getIntervalMax());
}
GeoElement[] geos = { selGeo };
sliderPanel.updatePanel(geos);
// update label text field
tfLabel.setText(selGeo.getDefaultLabel(source == rbInteger));
setLabelFieldFocus();
}
}
private void setLabelFieldFocus() {
tfLabel.getTextComponent().requestFocus();
tfLabel.selectText();
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
default:
// do nothing
break;
case KeyEvent.VK_ENTER:
btOK.doClick();
break;
case KeyEvent.VK_ESCAPE:
btCancel.doClick();
e.consume();
break;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
// only key press is important
}
@Override
public void keyTyped(KeyEvent arg0) {
// only key press is important
}
@Override
public void windowActivated(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowClosed(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowClosing(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowDeactivated(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowDeiconified(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowIconified(WindowEvent arg0) {
// only window opened is important
}
@Override
public void windowOpened(WindowEvent arg0) {
setLabelFieldFocus();
}
}