package org.geogebra.web.web.gui.dialog;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.gui.util.TableSymbols;
import org.geogebra.common.gui.util.TableSymbolsLaTeX;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoText;
import org.geogebra.common.main.App;
import org.geogebra.common.main.Localization;
import org.geogebra.common.util.lang.Unicode;
import org.geogebra.web.html5.Browser;
import org.geogebra.web.html5.gui.inputfield.ITextEditPanel;
import org.geogebra.web.html5.gui.inputfield.SymbolTableW;
import org.geogebra.web.html5.gui.util.NoDragImage;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.html5.main.StringHandler;
import org.geogebra.web.web.gui.images.AppResources;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Panel with symbols and GeoElements to be inserted into the GeoText editor
*
* @author G. Sturr
*
*/
public class TextEditAdvancedPanel extends TabLayoutPanel {
private AppW app;
protected ITextEditPanel editPanel;
private VerticalPanel geoPanel;
private VerticalPanel symbolPanel;
private VerticalPanel latexPanel;
private TextPreviewPanelW previewer;
private Localization loc;
private Label previewLabel, latexLabel;
public TextEditAdvancedPanel(App app, ITextEditPanel editPanel) {
super(30, Unit.PX);
this.app = (AppW) app;
this.editPanel = editPanel;
loc = app.getLocalization();
addStyleName("textEditorAdvancedPanel");
createGeoListBox();
createSymbolPanel();
createLatexPanel();
getPreviewer();
previewer.onResize();
Image geoTabImage = new NoDragImage(AppResources.INSTANCE.geogebra()
.getSafeUri().asString(),AppResources.INSTANCE.geogebra().getWidth());
// create the tabs
previewLabel = new Label(loc.getMenu("Preview"));
add(new ScrollPanel(getPreviewer().getPanel()),
previewLabel);
add(new ScrollPanel(geoPanel), geoTabImage);
add(new ScrollPanel(symbolPanel), Unicode.alphaBetaGamma + "");
latexLabel = new Label(loc.getMenu("LaTeXFormula"));
add(new ScrollPanel(latexPanel), latexLabel);
registerListeners();
setLabels();
}
@Override
public void insert(final Widget child, Widget tab, int beforeIndex) {
super.insert(child, tab, beforeIndex);
tab.addDomHandler(new MouseDownHandler(){
@Override
public void onMouseDown(MouseDownEvent event) {
TextEditAdvancedPanel.this.selectTab(child);
event.preventDefault();
}
}, MouseDownEvent.getType());
}
private void registerListeners() {
// update the geoPanel when selected
addSelectionHandler(new SelectionHandler<Integer>() {
@Override
public void onSelection(SelectionEvent<Integer> event) {
if (event.getSelectedItem() == 1) {
updateGeoList();
// geoPanel.setFocus(true);
}
}
});
}
public TextPreviewPanelW getPreviewer() {
if (previewer == null) {
previewer = new TextPreviewPanelW(app.getKernel());
previewer.getPanel().setStyleName("previewPanel");
}
return previewer;
}
public void setLabels() {
previewLabel.setText(loc.getMenu("Preview"));
latexLabel.setText(loc.getPlain("LaTeXFormula"));
}
// =====================================================
// GeoElement panel
// =====================================================
private void createGeoListBox() {
// If this flag is True, it sucks on iPad. If it is false, it still
// sucks on iPad.
geoPanel = new VerticalPanel();
geoPanel.setWidth("100%");
geoPanel.setHeight("100%");
geoPanel.getElement().getStyle().setBorderStyle(BorderStyle.NONE);
//geoPanel.setVisibleItemCount(10);
/*geoPanel.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
String label = geoPanel.getItemText(geoPanel.getSelectedIndex());
editPanel.insertGeoElement(app.getKernel().lookupLabel(label));
}
});*/
}
public void updateGeoList() {
geoPanel.clear();
Object[] datas = getGeoObjectList(editPanel.getEditGeo());
String[] geoLabels = (String[]) datas[0];
GColor[] geoColors = (GColor[]) datas[1];
final SymbolTableW symTable = newSymbolTable(geoLabels, false,
2,
new StringHandler() {
@Override
public void handle(String s) {
editPanel.insertGeoElement(app.getKernel().lookupLabel(
s));
}
}, geoColors);
symTable.getColumnFormatter().setStyleName(0, "geoSelectFirst");
geoPanel.add(symTable);
}
/**
* Creates an array of labels and colors of existing geos that can be
* inserted into the editor content
*/
private Object[] getGeoObjectList(GeoText editGeo) {
TreeSet<GeoElement> ts = app.getKernel().getConstruction()
.getGeoSetLabelOrder();
ArrayList<String> list = new ArrayList<String>();
ArrayList<GColor> colors = new ArrayList<GColor>();
// first possibility : create empty box
list.add(loc.getMenu("EmptyBox"));
colors.add(null);
// add all geos
Iterator<GeoElement> iter = ts.iterator();
while (iter.hasNext()) {
GeoElement g = iter.next();
if (g.isLabelSet() && !g.equals(editGeo)) {
list.add(g.getLabelSimple());
colors.add(g.getAlgebraColor());
}
}
String[] geoArray = new String[list.size()];
geoArray = list.toArray(geoArray);
GColor[] colorArray = new GColor[colors.size()];
colorArray = colors.toArray(colorArray);
Object[] objArray = new Object[2];
objArray[0] = geoArray;
objArray[1] = colorArray;
return objArray;
}
// =====================================================
// Symbol panel
// =====================================================
private void createSymbolPanel() {
int defaultRowSize = 15;
symbolPanel = new VerticalPanel();
symbolPanel.setWidth("100%");
symbolPanel.setHeight("100%");
String[][] map = TableSymbols.basicSymbolsMap(loc);
addTable(TableSymbols.basicSymbols(loc, map), false,
defaultRowSize, false);
addTable(TableSymbols.operators, false, defaultRowSize, true);
addTable(TableSymbols.greekLettersPlusVariants(), false,
defaultRowSize, true);
addTable(TableSymbols.analysis, false, defaultRowSize, true);
addTable(TableSymbols.sets, false, defaultRowSize, true);
addTable(TableSymbols.logical, false, defaultRowSize, true);
addTable(TableSymbols.sub_superscripts, false, defaultRowSize, true);
addTable(TableSymbols.basic_arrows, false, defaultRowSize, true);
addTable(TableSymbols.otherArrows, false, defaultRowSize, true);
addTable(TableSymbols.geometricShapes, false, defaultRowSize, true);
addTable(TableSymbols.games_music, false, defaultRowSize, true);
addTable(TableSymbols.currency, false, defaultRowSize, true);
addTable(TableSymbols.handPointers, false, defaultRowSize, true);
}
private void addTable(String[] tableSymbols, final boolean isLatex,
int rowSize,
boolean addSeparator) {
final SymbolTableW symTable = newSymbolTable(tableSymbols, isLatex,
rowSize, new StringHandler() {
@Override
public void handle(String s) {
editPanel.insertTextString(s, isLatex);
}
}, null);
if (addSeparator) {
symbolPanel.add(new HTML("<hr>"));
}
symbolPanel.add(symTable);
}
// =====================================================
// LaTeX panel
// =====================================================
private void createLatexPanel() {
int defaultRowSize = 15;
latexPanel = new VerticalPanel();
latexPanel.setWidth("100%");
latexPanel.setHeight("100%");
addLaTeXTable(
TableSymbolsLaTeX.roots_fractions, /* "RootsAndFractions", */
defaultRowSize, false);
addLaTeXTable(TableSymbolsLaTeX.sums, /* "SumsAndIntegrals", */
defaultRowSize, true);
addLaTeXTable(TableSymbolsLaTeX.accents,
/* "Accents", */ defaultRowSize,
true);
addLaTeXTable(TableSymbolsLaTeX.accentsExtended, /* "AccentsExt", */
defaultRowSize, true);
addLaTeXTable(TableSymbolsLaTeX.brackets,
/* "Brackets", */ defaultRowSize,
true);
// addLaTeXTable(TableSymbolsLaTeX.matrices, "Matrices", defaultRowSize,
// true);
// addLaTeXTable(TableSymbolsLaTeX.mathfrak(), "FrakturLetters",
// defaultRowSize, true);
// addLaTeXTable(TableSymbolsLaTeX.mathcal(), "CalligraphicLetters",
// defaultRowSize, true);
// addLaTeXTable(TableSymbolsLaTeX.mathbb(), "BlackboardLetters",
// defaultRowSize, true);
// addLaTeXTable(TableSymbolsLaTeX.mathscr(), "CursiveLetters",
// defaultRowSize, true);
}
private void addLaTeXTable(String[] tableSymbols,
int rowSize, boolean addSeparator) {
final SymbolTableW symTable = newSymbolTable(tableSymbols, true,
rowSize, new StringHandler() {
@Override
public void handle(String s) {
editPanel.insertTextString(s, true);
editPanel.ensureLaTeX();
}
}, null);
if (addSeparator) {
latexPanel.add(new HTML("<hr>"));
}
// latexPanel.add(new Label(header));
latexPanel.add(symTable);
}
// =====================================================
// Symbol table utilities
// =====================================================
private SymbolTableW newSymbolTable(String[] table, boolean isLatexSymbol,
int rowSize, final StringHandler onChange, GColor[] colors) {
final SymbolTableW symTable = new SymbolTableW(table,
isLatexSymbol, rowSize, app, colors);
if (Browser.isIE10plus()) {
symTable.addDomHandler(new MouseDownHandler() {
@Override
public void onMouseDown(MouseDownEvent event) {
/*
* Cell clickCell = ((HTMLTable) event.getSource())
* .getCellForEvent(event); if (clickCell == null) { return; }
* String text = symTable.getSymbolText(clickCell.getRowIndex(),
* clickCell.getCellIndex());
*/
Element td = ((SymbolTableW) event.getSource())
.getEventTargetCell(Event
.as(event.getNativeEvent()));
if (td != null) {
int row = TableRowElement.as(td.getParentElement())
.getSectionRowIndex();
int column = TableCellElement.as(td).getCellIndex();
onChange.handle(symTable.getSymbolText(row, column));
}
event.preventDefault();
event.stopPropagation();
// editPanel.insertTextString(clickCell.getElement()
// .getInnerText(), false);
}
}, MouseDownEvent.getType());
} else {
symTable.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
HTMLTable.Cell clickCell = ((HTMLTable) event
.getSource()).getCellForEvent(event);
if (clickCell == null) {
return;
}
String text = symTable.getSymbolText(
clickCell.getRowIndex(), clickCell.getCellIndex());
onChange.handle(text);
}
});
}
return symTable;
}
}