/*
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.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
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 java.util.Iterator;
import java.util.TreeSet;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;
import org.geogebra.common.gui.dialog.ButtonDialogModel;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.util.debug.Log;
import org.geogebra.desktop.gui.editor.GeoGebraEditorPane;
import org.geogebra.desktop.gui.inputfield.AutoCompleteTextFieldD;
import org.geogebra.desktop.gui.view.algebra.InputPanelD;
import org.geogebra.desktop.gui.view.algebra.MyComboBoxListener;
import org.geogebra.desktop.main.AppD;
import org.geogebra.desktop.main.LocalizationD;
public class ButtonDialogD extends JDialog
implements ActionListener, KeyListener, WindowListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextComponent tfCaption, tfScript;
private JPanel btPanel;
// private DefaultListModel listModel;
private ButtonDialogModel model;
private DefaultComboBoxModel comboModel;
private JButton btOK, btCancel;
private JPanel optionPane;
private AppD app;
InputPanelD inputPanel, inputPanel2;
private LocalizationD loc;
/**
* Creates a dialog to create a new GeoNumeric for a slider.
*
* @param app
* application
*
* @param x
* location of button in screen coords
* @param y
* location of button in screen coords
* @param textField
* whether we need an input box
*/
public ButtonDialogD(AppD app, int x, int y, boolean textField) {
super(app.getFrame(), false);
this.app = app;
this.loc = app.getLocalization();
// this.textField = textField;
addWindowListener(this);
model = new ButtonDialogModel(app, x, y, textField);
// create temp geos that may be returned as result
// Construction cons = app.getKernel().getConstruction();
// button = textField ? new GeoTextField(cons) : new GeoButton(cons);
// button.setEuclidianVisible(true);
// button.setAbsoluteScreenLoc(x, y);
createGUI();
pack();
setLocationRelativeTo(app.getMainComponent());
}
private void createGUI() {
setTitle(model.getTitle());
setResizable(true);
// create caption panel
JLabel captionLabel = new JLabel(loc.getMenu("Button.Caption") + ":");
InputPanelD ip = new InputPanelD(model.getInitString(), app, 1, 25,
true);
tfCaption = ip.getTextComponent();
if (tfCaption instanceof AutoCompleteTextFieldD) {
AutoCompleteTextFieldD atf = (AutoCompleteTextFieldD) tfCaption;
atf.setAutoComplete(false);
}
captionLabel.setLabelFor(tfCaption);
JPanel captionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
captionPanel.add(captionLabel);
captionPanel.add(ip);
// combo box to link GeoElement to TextField
comboModel = new DefaultComboBoxModel();
TreeSet<GeoElement> sortedSet = app.getKernel().getConstruction()
.getGeoSetNameDescriptionOrder();
final JComboBox cbAdd = new JComboBox(comboModel);
if (model.isTextField()) {
// lists for combo boxes to select input and output objects
// fill combobox models
Iterator<GeoElement> it = sortedSet.iterator();
comboModel.addElement(null);
FontMetrics fm = getFontMetrics(getFont());
// minimum width
// make sure if there are just objects with short descriptions
// eg sliders
// then they display OK
int width = app.getGUIFontSize() * 10;
while (it.hasNext()) {
GeoElement geo = it.next();
if (!geo.isGeoImage() && !(geo.isGeoButton())
&& !(geo.isGeoBoolean())) {
comboModel.addElement(geo);
String str = geo.toString(StringTemplate.defaultTemplate);
if (width < fm.stringWidth(str)) {
width = fm.stringWidth(str);
}
}
}
// make sure it's not too wide (eg long GeoList)
Dimension size = new Dimension(
Math.min(AppD.getScreenSize().width / 2, width),
cbAdd.getPreferredSize().height);
cbAdd.setMaximumSize(size);
cbAdd.setPreferredSize(size);
if (comboModel.getSize() > 1) {
// listener for the combobox
MyComboBoxListener ac = new MyComboBoxListener() {
@Override
public void doActionPerformed(Object source) {
model.setLinkedGeo(
(GeoElement) cbAdd.getSelectedItem());
// cbAdd.removeActionListener(this);
//
// cbAdd.setSelectedItem(null);
// cbAdd.addActionListener(this);
}
};
cbAdd.addActionListener(ac);
cbAdd.addMouseListener(ac);
captionPanel.add(cbAdd);
}
}
// create script panel
JLabel scriptLabel = new JLabel(loc.getMenu("Script") + ":");
// XXX Remark 1: This has been incorrect as it assumes the click script
// is GgbScript. However I'm only adapting it to the new scripting
// structure so it will need to be dealt with later
InputPanelD ip2 = new InputPanelD(model.getClickScript(), app, 10, 40,
false);
Dimension dim = ((GeoGebraEditorPane) ip2.getTextComponent())
.getPreferredSizeFromRowColumn(10, 40);
ip2.setPreferredSize(dim);
ip2.setShowLineNumbering(true);
tfScript = ip2.getTextComponent();
// add a small margin
tfScript.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
if (tfScript instanceof AutoCompleteTextFieldD) {
AutoCompleteTextFieldD atf = (AutoCompleteTextFieldD) tfScript;
atf.setAutoComplete(false);
}
scriptLabel.setLabelFor(tfScript);
JPanel scriptPanel = new JPanel(new BorderLayout(5, 5));
scriptPanel.add(scriptLabel, BorderLayout.NORTH);
scriptPanel.add(ip2, BorderLayout.CENTER);
scriptPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel linkedPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel linkedLabel = new JLabel(loc.getMenu("LinkedObject") + ":");
linkedPanel.add(linkedLabel);
linkedPanel.add(cbAdd);
// 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);
btPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
btPanel.add(btOK);
btPanel.add(btCancel);
// Create the JOptionPane.
optionPane = new JPanel(new BorderLayout(5, 5));
// create object list
optionPane.add(captionPanel, BorderLayout.NORTH);
if (model.isTextField()) {
optionPane.add(linkedPanel, BorderLayout.CENTER);
} else {
optionPane.add(scriptPanel, BorderLayout.CENTER);
}
optionPane.add(btPanel, BorderLayout.SOUTH);
optionPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Make this dialog display it.
setContentPane(optionPane);
// TODO: for buttons too when script panel works in RTL
if (model.isTextField()) {
app.setComponentOrientation(this);
}
/*
*
* inputPanel = new InputPanel("ggbApplet.evalCommand('A=(3,4)');", app,
* 10, 50, false, true, false ); inputPanel2 = new InputPanel(
* "function func() {\n}", app, 10, 50, false, true, false );
*
* JPanel centerPanel = new JPanel(new BorderLayout());
*
* centerPanel.add(inputPanel, BorderLayout.CENTER);
* centerPanel.add(inputPanel2, BorderLayout.SOUTH);
* getContentPane().add(centerPanel, BorderLayout.CENTER);
* //centerOnScreen();
*
* setContentPane(centerPanel); pack();
* setLocationRelativeTo(app.getFrame());
*/
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
Log.debug(tfScript.getText());
if (source == btOK) {
model.apply(tfCaption.getText(), tfScript.getText());
setVisible(false);
} else if (source == btCancel) {
model.cancel();
setVisible(false);
}
}
@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) {
// nothing to do
}
@Override
public void keyTyped(KeyEvent arg0) {
// nothing to do
}
@Override
public void windowActivated(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowClosed(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowClosing(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowDeactivated(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowDeiconified(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowIconified(WindowEvent arg0) {
// nothing to do
}
@Override
public void windowOpened(WindowEvent arg0) {
// setLabelFieldFocus();
}
}