/*
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.web.web.gui.dialog;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
import org.geogebra.common.awt.GPoint;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.kernel.CircularDefinitionException;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.geos.GeoBoolean;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.main.Feature;
import org.geogebra.common.main.GeoElementSelectionListener;
import org.geogebra.web.html5.gui.HasKeyboardPopup;
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.main.LocalizationW;
import org.geogebra.web.web.gui.images.AppResources;
import org.geogebra.web.web.gui.view.algebra.InputPanelW;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
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.ListBox;
import com.google.gwt.user.client.ui.PushButton;
/**
* Dialog to create a GeoBoolean object (checkbox) that determines the
* visibility of a list of objects.
*/
public class CheckboxCreationDialogW extends DialogBoxW implements
GeoElementSelectionListener, HasKeyboardPopup {
private class GeoListBox extends ListBox {
private List<GeoElement> geos;
public GeoListBox(boolean isMultipleSelect) {
super(isMultipleSelect);
geos = new ArrayList<GeoElement>();
}
public GeoListBox() {
this(false);
}
public GeoElement getGeoAt(int index) {
return geos.get(index);
}
public GeoElement getSelectedGeo() {
return getGeoAt(getSelectedIndex());
}
protected void add(GeoElement geo) {
if (geo != null) {
addTextOfGeo(geo);
} else {
addItem("");
}
geos.add(geo);
}
protected void addTextOfGeo(GeoElement geo) {
String text = geo.getLongDescription();
if (text.length() < 100) {
addItem(text);
}
else {
addItem(geo.getNameDescription());
}
}
protected boolean contains(GeoElement geo) {
return geos.contains(geo);
}
public void remove(GeoElement geo) {
int idx = geos.lastIndexOf(geo);
if (idx > 0) {
remove(geos.lastIndexOf(geo));
}
}
public void remove(int idx) {
removeItem(idx);
geos.remove(idx);
}
}
private class GeoAttachedListBox extends GeoListBox {
private static final int MAX_VISIBLE_ROWS = 6;
private GeoListBox combo;
public GeoAttachedListBox(GeoListBox combo) {
super();
setVisibleItemCount(MAX_VISIBLE_ROWS);
this.combo = combo;
}
@Override
public void add(GeoElement geo) {
if (contains(geo)) {
return;
}
if (geo.isEuclidianVisible()) {
super.add(geo);
combo.remove(geo);
}
}
}
private AutoCompleteTextFieldW tfCaption;
private Button btOK, btCancel;
private FlowPanel optionPane;
private GeoListBox gbObjects;
private GeoAttachedListBox gbList;
private GPoint location;
private AppW app;
private GeoBoolean geoBoolean;
private LocalizationW loc;
/**
* Input Dialog for a GeoBoolean object Make this *not* modal to allow
* adding geos by clicking in EV
*/
public CheckboxCreationDialogW(AppW app, GPoint loc2,
GeoBoolean geoBoolean) {
super(false, false, null, app.getPanel());
if (app.has(Feature.DIALOGS_OVERLAP_KEYBOARD)) {
setOverlapFeature(true);
}
this.app = app;
this.loc = (LocalizationW) app.getLocalization();
this.location = loc2;
this.geoBoolean = geoBoolean;
initLists();
createGUI(loc.getMenu("CheckBoxTitle"));
center();
}
private void initLists() {
// fill combo box with all geos
gbObjects = new GeoListBox();
TreeSet<GeoElement> sortedSet = app.getKernel().getConstruction()
.getGeoSetNameDescriptionOrder();
// lists for combo boxes to select input and output objects
// fill combobox models
Iterator<GeoElement> it = sortedSet.iterator();
gbObjects.add(null);
while (it.hasNext()) {
GeoElement geo = it.next();
if (geo.isEuclidianShowable()) {
gbObjects.add(geo);
}
}
// fill list with all selected geos
gbList = new GeoAttachedListBox(gbObjects);
// add all selected geos to list
for (int i = 0; i < app.getSelectionManager().getSelectedGeos().size(); i++) {
GeoElement geo = app.getSelectionManager().getSelectedGeos().get(i);
gbList.add(geo);
}
gbObjects.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
GeoElement geo = gbObjects.getSelectedGeo();
if (geo != null) {
gbList.add(geo);
}
}
});
}
@Override
public void geoElementSelected(GeoElement geo, boolean addToSelection) {
gbList.add(geo);
}
protected void createGUI(String title) {
addStyleName("GeoGebraPopup");
getCaption().setText(title);
Label lblSelectObjects = new Label(loc.getMenu("Tool.SelectObjects"));
lblSelectObjects.setStyleName("panelTitle");
// create caption panel
Label captionLabel = new Label(loc.getMenu("Button.Caption") + ":");
String initString = geoBoolean == null ? "" : geoBoolean.getCaption(StringTemplate.defaultTemplate);
InputPanelW ip = new InputPanelW(initString, app, 1, 15, true);
tfCaption = ip.getTextComponent();
tfCaption.setAutoComplete(false);
tfCaption.showPopupSymbolButton(true);
FlowPanel captionPanel = new FlowPanel();
captionPanel.add(LayoutUtilW.panelRow(captionLabel, ip));
FlowPanel listPanel = new FlowPanel();
listPanel.add(gbObjects);
gbList.getElement().addClassName("cbCreationList");
PushButton btnRemove = new PushButton(
new Image(AppResources.INSTANCE.delete_small()));
listPanel.add(lblSelectObjects);
listPanel.add(LayoutUtilW.panelRow(gbList, btnRemove));
btnRemove.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
GeoElement geo = gbList.getSelectedGeo();
if (geo != null) {
gbObjects.add(geo);
gbList.remove(geo);
}
}
});
// buttons
btOK = new Button(loc.getPlain("OK"));
btOK.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
actionPerformed(btOK);
}
});
btCancel = new Button(loc.getPlain("Cancel"));
btCancel.addStyleName("cancelBtn");
btCancel.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
actionPerformed(btCancel);
}
});
FlowPanel btPanel = new FlowPanel();
btPanel.setStyleName("DialogButtonPanel");
btPanel.add(btOK);
btPanel.add(btCancel);
// Create the JOptionPane.
optionPane = new FlowPanel();
// create object list
optionPane.add(captionPanel);
optionPane.add(listPanel);
optionPane.add(btPanel);
// Make this dialog display it.
setWidget(optionPane);
}
public void actionPerformed(Object src) {
if (src == btCancel) {
hide();
} else if (src == btOK) {
apply();
hide();
}
}
private void apply() {
// create new GeoBoolean
if (geoBoolean == null) {
geoBoolean = new GeoBoolean(app.getKernel().getConstruction());
geoBoolean.setAbsoluteScreenLoc(location.x, location.y, true);
geoBoolean.setLabel(null);
}
// set visibility condition for all GeoElements in list
try {
for (int i = 0; i < gbList.getItemCount(); i++) {
GeoElement geo = gbList.getGeoAt(i);
geo.setShowObjectCondition(geoBoolean);
}
} catch (CircularDefinitionException e) {
app.showError("CircularDefinition");
}
// set caption text
String strCaption = tfCaption.getText().trim();
if (strCaption.length() > 0) {
geoBoolean.setCaption(strCaption);
}
// update boolean (updates visibility of geos from list too)
geoBoolean.setValue(true);
geoBoolean.setEuclidianVisible(true);
geoBoolean.setLabelVisible(true);
geoBoolean.updateRepaint();
app.storeUndoInfo();
}
public void windowGainedFocus() {
// make sure this dialog is the current selection listener
if (app.getMode() != EuclidianConstants.MODE_SELECTION_LISTENER
|| app.getCurrentSelectionListener() != this) {
app.setSelectionListenerMode(this);
}
}
@Override
public void setVisible(boolean flag) {
if (!isModal()) {
if (flag) {
// app.setMoveMode();
app.getSelectionManager().addSelectionListener(this);
} else {
app.getSelectionManager().removeSelectionListener(this);
app.setSelectionListenerMode(null);
app.setMode(EuclidianConstants.MODE_SHOW_HIDE_CHECKBOX);
}
}
// if (app.has(Feature.KEYBOARD_BEHAVIOUR)) {
// if (flag) {
// app.registerPopup(this);
// } else {
// app.unregisterPopup(this);
// }
// }
super.setVisible(flag);
}
}