/*
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.view.algebra;
import java.util.ArrayList;
import java.util.List;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.gui.inputfield.InputHelper;
import org.geogebra.common.gui.view.algebra.AlgebraView;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.geos.HasExtendedAV;
import org.geogebra.common.kernel.geos.HasSymbolicMode;
import org.geogebra.common.kernel.kernelND.GeoElementND;
import org.geogebra.common.main.App;
import org.geogebra.common.main.Feature;
import org.geogebra.common.main.GuiManagerInterface.Help;
import org.geogebra.common.main.Localization;
import org.geogebra.common.main.error.ErrorHandler;
import org.geogebra.common.util.AsyncOperation;
import org.geogebra.common.util.IndexHTMLBuilder;
import org.geogebra.common.util.StringUtil;
import org.geogebra.common.util.debug.Log;
import org.geogebra.common.util.lang.Unicode;
import org.geogebra.web.html5.css.GuiResourcesSimple;
import org.geogebra.web.html5.gui.GPopupPanel;
import org.geogebra.web.html5.gui.inputfield.AbstractSuggestionDisplay;
import org.geogebra.web.html5.gui.inputfield.AutoCompleteTextFieldW;
import org.geogebra.web.html5.gui.inputfield.AutoCompleteW;
import org.geogebra.web.html5.gui.tooltip.ToolTipManagerW;
import org.geogebra.web.html5.gui.tooltip.ToolTipManagerW.ToolTipLinkType;
import org.geogebra.web.html5.gui.util.LayoutUtilW;
import org.geogebra.web.html5.gui.util.LongTouchManager;
import org.geogebra.web.html5.gui.util.MathKeyboardListener;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.html5.main.DrawEquationW;
import org.geogebra.web.web.css.GuiResources;
import org.geogebra.web.web.gui.inputbar.HasHelpButton;
import org.geogebra.web.web.gui.inputbar.InputBarHelpPanelW;
import org.geogebra.web.web.gui.inputbar.InputBarHelpPopup;
import org.geogebra.web.web.gui.layout.panels.AlgebraDockPanelW;
import org.geogebra.web.web.gui.util.MyToggleButtonW;
import org.geogebra.web.web.gui.util.Resizer;
import org.geogebra.web.web.main.AppWFull;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DragStartEvent;
import com.google.gwt.event.dom.client.DragStartHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
/**
* main -> marblePanel content controls
*
* content -> plainTextitem | latexItem | c | (definitionPanel outputPanel)
*
* sliderContent -> [sliderPanel minmaxPanel]
*
* plaintextitem -> STRING | (definitionPanel, outputPanel)
*
* outputPanel -> valuePanel
*
* definitionPanel -> c | STRING
*/
@SuppressWarnings("javadoc")
public abstract class RadioTreeItem extends AVTreeItem
implements MathKeyboardListener,
AutoCompleteW, RequiresResize, HasHelpButton {
private static final int DEFINITION_ROW_EDIT_MARGIN = 5;
static final int BROWSER_SCROLLBAR_WIDTH = 17;
protected static final int LATEX_MAX_EDIT_LENGHT = 1500;
static final String CLEAR_COLOR_STR = GColor
.getColorString(GColor.newColor(255, 255, 255, 0));
static final String CLEAR_COLOR_STR_BORDER = GColor
.getColorString(GColor.newColor(220, 220, 220));
Boolean stylebarShown;
/** Help popup */
protected InputBarHelpPopup helpPopup;
/** label "Input..." */
protected Label dummyLabel;
/**
* The main widget of the tree item containing all others
*/
protected FlowPanel main;
/** Item content after marble */
protected FlowPanel content;
/** Item controls like delete, play, etc */
protected ItemControls controls;
protected Canvas canvas;
private Canvas valCanvas;
String commandError;
protected String errorMessage;
protected String lastInput;
protected GeoElement geo = null;
protected Kernel kernel;
protected AppWFull app;
protected AlgebraView av;
protected boolean latex = false;
public FlowPanel latexItem;
private FlowPanel plainTextItem;
// GTextBox tb;
private boolean needsUpdate;
/** Clears input only when editing */
protected PushButton btnClearInput;
/**
* this panel contains the marble (radio) button
*/
protected MarblePanel marblePanel;
protected FlowPanel sliderContent;
protected boolean definitionAndValue;
protected FlowPanel valuePanel;
protected FlowPanel definitionPanel;
protected FlowPanel outputPanel;
protected Localization loc;
private RadioTreeItemController controller;
String lastTeX;
public void updateOnNextRepaint() {
needsUpdate = true;
}
protected IndexHTMLBuilder getBuilder(final Widget w) {
return new IndexHTMLBuilder(false) {
Element sub = null;
@Override
public void append(String s) {
if (sub == null) {
w.getElement()
.appendChild(Document.get().createTextNode(s));
} else {
sub.appendChild(Document.get().createTextNode(s));
}
}
@Override
public void startIndex() {
sub = Document.get().createElement("sub");
sub.getStyle().setFontSize((int) (app.getFontSize() * 0.8),
Unit.PX);
}
@Override
public void endIndex() {
if (sub != null) {
w.getElement().appendChild(sub);
}
sub = null;
}
@Override
public String toString() {
if (sub != null) {
endIndex();
}
return w.getElement().getInnerHTML();
}
@Override
public void clear() {
w.getElement().removeAllChildren();
sub = null;
}
@Override
public boolean canAppendRawHtml() {
return false;
}
@Override
public void appendHTML(String str) {
append(str);
}
};
}
/**
* Minimal constructor
*
* @param kernel
*/
public RadioTreeItem(Kernel kernel) {
super();
this.kernel = kernel;
app = (AppWFull) kernel.getApplication();
loc = app.getLocalization();
av = app.getAlgebraView();
definitionAndValue = app.has(Feature.AV_DEFINITION_AND_VALUE);
main = new FlowPanel();
content = new FlowPanel();
plainTextItem = new FlowPanel();
setWidget(main);
setController(createController());
getController().setLongTouchManager(LongTouchManager.getInstance());
setDraggable();
}
/**
* Creates a new RadioTreeItem for displaying/editing an existing GeoElement
*
* @param geo0
* the existing GeoElement to display/edit
*/
public RadioTreeItem(final GeoElement geo0) {
this(geo0.getKernel());
geo = geo0;
addMarble();
if (geo.isSimple()) {
getPlainTextItem().addStyleName("avDefinitionSimple");
}
getPlainTextItem().addStyleName("sqrtFontFix");
getPlainTextItem().addStyleName("avPlainTextItem");
if (app.has(Feature.AV_TEXT_BLACK)) {
getElement().getStyle().setColor("black");
} else {
updateColor(getPlainTextItem());
}
updateFont(getPlainTextItem());
styleContent();
addControls();
content.add(getPlainTextItem());
buildPlainTextItem();
// if enabled, render with LaTeX
String ltx = getLatexString(null, true);
if (ltx != null) {
if (getAV().isLaTeXLoaded()) {
doUpdate();
} else {
setNeedsUpdate(true);
av.repaintView();
}
}
createAvexWidget();
addAVEXWidget(content);
}
protected abstract RadioTreeItemController createController();
protected void addMarble() {
main.addStyleName("elem");
main.addStyleName("panelRow");
marblePanel = new MarblePanel(this);
main.add(marblePanel);
}
protected void styleContent() {
content.addStyleName("elemText");
}
protected void createControls() {
controls = new ItemControls(this);
}
protected void addControls() {
if (controls != null) {
return;
}
createControls();
main.add(controls);
controls.setVisible(true);
}
/**
*
*/
protected void createAvexWidget() {
// only for checkboxes
}
protected final String getLatexString(Integer limit,
boolean output) {
return getLatexString(geo, limit, output);
}
private String getLatexString(GeoElement geo1,
Integer limit, boolean output) {
if ((kernel.getAlgebraStyle() != Kernel.ALGEBRA_STYLE_VALUE
&& !isDefinitionAndValue()) || !geo1.isDefined()
|| (output && !geo1.isLaTeXDrawableGeo())) {
return null;
}
String text = geo1.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate);
if ((text != null) && (limit == null || (text.length() < limit))) {
return text;
}
return null;
}
protected abstract void clearInput();
private void buildPlainTextItem() {
if (geo.isIndependent() && geo.getDefinition() == null) {
geo.getAlgebraDescriptionTextOrHTMLDefault(
getBuilder(getPlainTextItem()));
} else {
switch (kernel.getAlgebraStyle()) {
case Kernel.ALGEBRA_STYLE_VALUE:
geo.getAlgebraDescriptionTextOrHTMLDefault(
getBuilder(getPlainTextItem()));
break;
case Kernel.ALGEBRA_STYLE_DESCRIPTION:
geo.addLabelTextOrHTML(
geo.getDefinitionDescription(StringTemplate.defaultTemplate),
getBuilder(getPlainTextItem()));
break;
case Kernel.ALGEBRA_STYLE_DEFINITION:
geo.addLabelTextOrHTML(
geo.getDefinition(StringTemplate.defaultTemplate),
getBuilder(getPlainTextItem()));
break;
default:
case Kernel.ALGEBRA_STYLE_DEFINITION_AND_VALUE:
buildItemContent();
break;
}
}
}
protected void createDVPanels() {
if (definitionPanel == null) {
definitionPanel = new FlowPanel();
}
if (outputPanel == null) {
outputPanel = new FlowPanel();
outputPanel.addStyleName("avOutput");
}
if (valuePanel == null) {
valuePanel = new FlowPanel();
valuePanel.addStyleName("avValue");
}
}
protected boolean isGeoFraction() {
return geo instanceof GeoNumeric && geo.getDefinition() != null
&& geo.getDefinition().isFraction();
}
private boolean isLatexTrivial() {
if (!latex) {
return false;
}
String text = getTextForEditing(false, StringTemplate.latexTemplate);
String[] eq = text.split("=");
if (eq.length < 2) {
return false;
}
String leftSide = eq[0].trim();
String rightSide = eq[1].replaceFirst("\\\\left", "")
.replaceFirst("\\\\right", "").replaceAll(" ", "");
return leftSide.equals(rightSide);
}
private boolean updateDefinitionPanel() {
if (lastInput != null) {
definitionFromTeX(lastTeX);
} else if (latex || isGeoFraction()) {
String text = getTextForEditing(false,
StringTemplate.latexTemplate);
definitionFromTeX(text);
} else if (geo != null) {
IndexHTMLBuilder sb = getBuilder(definitionPanel);
geo.addLabelTextOrHTML(
geo.getDefinition(StringTemplate.defaultTemplate), sb);
}
return true;
}
private void definitionFromTeX(String text) {
definitionPanel.clear();
canvas = latexToCanvas(text);
canvas.addStyleName("canvasDef");
if (geo == null) {
Log.debug("CANVAS to DEF");
}
definitionPanel.add(canvas);
}
private boolean isSymbolicDiffers() {
if (!(geo instanceof HasSymbolicMode)) {
return false;
}
HasSymbolicMode sm = (HasSymbolicMode) geo;
boolean orig = sm.isSymbolicMode();
String text1 = geo.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate);
sm.setSymbolicMode(!orig, false);
String text2 = geo.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate);
sm.setSymbolicMode(orig, false);
if (text1 == null) {
return true;
}
return !text1.equals(text2);
}
private void addPrefixLabel(String text) {
final Label label = new Label(text);
if (!latex) {
label.addStyleName("prefix");
} else {
label.addStyleName("prefixLatex");
}
outputPanel.add(label);
}
protected boolean updateValuePanel(String text) {
return updateValuePanel(geo, text);
}
private boolean updateValuePanel(GeoElement geo1, String text) {
if (geo1 == null || !geo1.needToShowBothRowsInAV()) {
return false;
}
outputPanel.clear();
if (isSymbolicDiffers()) {
final MyToggleButtonW btnSymbolic = new MyToggleButtonW(
GuiResourcesSimple.INSTANCE.modeToggleSymbolic(),
GuiResourcesSimple.INSTANCE.modeToggleNumeric());
btnSymbolic.addStyleName("symbolicButton");
if (getOutputPrefix() == Unicode.CAS_OUTPUT_NUMERIC) {
btnSymbolic.setSelected(true);
}
if (getOutputPrefix() == Unicode.CAS_OUTPUT_PREFIX) {
btnSymbolic.setSelected(false);
btnSymbolic.addStyleName("btn-prefix");
}
btnSymbolic.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
toggleSymbolic(btnSymbolic);
}
});
outputPanel.add(btnSymbolic);
} else {
addPrefixLabel(kernel.getLocalization().rightToLeftReadingOrder ? Unicode.CAS_OUTPUT_PREFIX_RTL
: Unicode.CAS_OUTPUT_PREFIX);
}
valuePanel.clear();
if (latex && geo != null
&& (geo.isLaTeXDrawableGeo() || isGeoFraction())) {
valCanvas = DrawEquationW.paintOnCanvas(geo1, text, valCanvas,
getFontSize());
valCanvas.addStyleName("canvasVal");
valuePanel.clear();
valuePanel.add(valCanvas);
} else {
IndexHTMLBuilder sb = new IndexHTMLBuilder(false);
geo1.getAlgebraDescriptionTextOrHTMLDefault(sb);
valuePanel.add(new HTML(sb.toString()));
}
return true;
}
private void buildItemContent() {
if (isDefinitionAndValue()) {
if (controller.isEditing() || geo == null) {
return;
}
if ((geo.needToShowBothRowsInAV() && !isLatexTrivial())
|| lastTeX != null) {
buildItemWithTwoRows();
updateItemColor();
} else {
buildItemWithSingleRow();
}
} else {
buildPlainTextItem();
}
adjustToPanel(content);
}
private void buildItemWithTwoRows() {
createDVPanels();
String text = getLatexString(LATEX_MAX_EDIT_LENGHT,
false);
latex = text != null;
if (latex) {
definitionPanel.addStyleName("avDefinition");
} else {
definitionPanel.addStyleName("avDefinitionPlain");
}
content.clear();
if (updateDefinitionPanel()) {
plainTextItem.clear();
plainTextItem.add(definitionPanel);
}
if (updateValuePanel(geo.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate))) {
outputPanel.add(valuePanel);
plainTextItem.add(outputPanel);
}
// updateFont(plainTextItem);
content.add(plainTextItem);
}
public void clearPreview() {
content.removeStyleName("avPreview");
content.addStyleName("noPreview");
if (valuePanel == null) {
return;
}
valuePanel.clear();
outputPanel.clear();
}
public void previewValue(GeoElement previewGeo) {
if (!previewGeo.needToShowBothRowsInAV() || getController().isInputAsText()) {
clearPreview();
return;
}
content.removeStyleName("noPreview");
content.addStyleName("avPreview");
boolean forceLatex = false;
if (previewGeo.isGeoFunction() || previewGeo.isGeoFunctionNVar()
|| previewGeo.isGeoFunctionBoolean()) {
forceLatex = true;
}
InputHelper.updateSymbolicMode(previewGeo);
createDVPanels();
content.addStyleName("avPreview");
plainTextItem.clear();
plainTextItem.add(outputPanel);
outputPanel.clear();
valuePanel.clear();
IndexHTMLBuilder sb = new IndexHTMLBuilder(false);
previewGeo.getAlgebraDescriptionTextOrHTMLDefault(sb);
String plain = sb.toString();
String text = previewGeo
.getAlgebraDescription(StringTemplate.latexTemplate)
.replace("undefined", "").trim();
if (!StringUtil.empty(text)
&& (text.charAt(0) == ':' || text.charAt(0) == '=')) {
text = text.substring(1);
}
if (!plain.equals(text) || forceLatex) {
// LaTeX
valCanvas = DrawEquationW.paintOnCanvas(previewGeo, text,
valCanvas,
getFontSize());
valCanvas.addStyleName("canvasVal");
valuePanel.clear();
valuePanel.add(valCanvas);
}
addPrefixLabel(kernel.getLocalization().rightToLeftReadingOrder
? Unicode.CAS_OUTPUT_PREFIX_RTL : Unicode.CAS_OUTPUT_PREFIX);
if (outputPanel.getWidgetIndex(valuePanel) == -1) {
outputPanel.add(valuePanel);
}
if (content.getWidgetIndex(plainTextItem) == -1) {
content.add(plainTextItem);
}
}
protected void buildItemWithSingleRow() {
// LaTeX
String text = getLatexString(LATEX_MAX_EDIT_LENGHT,
true);
latex = text != null;
if (latex) {
if (isInputTreeItem()) {
text = geo.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate);
}
canvas = DrawEquationW.paintOnCanvas(geo, text, canvas,
getFontSize());
content.clear();
if (geo == null) {
Log.debug("CANVAS to IHTML");
}
content.add(canvas);
}
else {
geo.getAlgebraDescriptionTextOrHTMLDefault(
getBuilder(getPlainTextItem()));
updateItemColor();
// updateFont(getPlainTextItem());
content.clear();
content.add(getPlainTextItem());
adjustToPanel(plainTextItem);
}
}
/**
*
* @param button
* @return true if output is numeric, false otherwise
*/
void toggleSymbolic(MyToggleButtonW button) {
if (geo instanceof HasSymbolicMode) {
((HasSymbolicMode) geo)
.setSymbolicMode(!((HasSymbolicMode) geo).isSymbolicMode(),
true);
if (getOutputPrefix() == Unicode.CAS_OUTPUT_NUMERIC) {
button.setSelected(true);
} else {
button.setSelected(false);
}
geo.updateRepaint();
}
}
private void updateFont(Widget w) {
int size = app.getFontSizeWeb() + 2;
w.getElement().getStyle().setFontSize(size, Unit.PX);
}
protected void createSliderContent() {
if (sliderContent == null) {
sliderContent = new FlowPanel();
} else {
sliderContent.clear();
}
}
protected void styleContentPanel() {
sliderContent.addStyleName("elemPanel");
sliderContent.removeStyleName("avItemContent");
controls.updateAnimPanel();
}
protected boolean first = false;
public void setFirst(boolean first) {
this.first = first;
updateButtonPanelPosition();
}
/**
* Method to be overridden in InputTreeItem
*/
public boolean popupSuggestions() {
return false;
}
/**
* Method to be overridden in InputTreeItem
*
* @param str
* GeoGebra input
* @param latexx
* LaTeX value
*/
public void addToHistory(String str, String latexx) {
// override
}
public void repaint() {
if (isNeedsUpdate()) {
doUpdate();
}
// highlight only
boolean selected = geo.doHighlighting();
setSelected(selected);
// select only if it is in selection really.
selectItem(selected);
}
public boolean commonEditingCheck() {
return av.isEditItem() || controller.isEditing() || isInputTreeItem()
|| geo == null;
}
/**
* Updates all the contents of the AV Item
*/
protected void doUpdate() {
setNeedsUpdate(false);
if (hasMarblePanel()) {
marblePanel.update();
}
if (controls != null) {
controls.updateAnimPanel();
}
if (!isInputTreeItem() && isDefinitionAndValue()) {
buildItemContent();
} else {
updateTextItems();
}
if (plainTextItem != null) {
updateFont(plainTextItem);
}
}
protected void doUpdateEnsureNoEditor() {
doUpdate();
if (!latex) {
content.clear();
content.add(getPlainTextItem());
}
}
protected void updateTextItems() {
// check for new LaTeX
boolean latexAfterEdit = false;
if (!isDefinitionAndValue() && outputPanel != null) {
content.remove(outputPanel);
}
if (kernel.getAlgebraStyle() == Kernel.ALGEBRA_STYLE_VALUE
|| isDefinitionAndValue()) {
String text = "";
if (geo != null) {
text = getLatexString(LATEX_MAX_EDIT_LENGHT,
true);
latexAfterEdit = (text != null);
} else {
latexAfterEdit = true;
}
if (latex && latexAfterEdit) {
// Both original and edited text is LaTeX
if (isInputTreeItem() && geo != null) {
text = geo.getLaTeXAlgebraDescription(true,
StringTemplate.latexTemplate);
}
updateLaTeX(text);
} else if (latexAfterEdit) {
// Edited text is latex now, but the original is not.
renderLatex(text, getPlainTextItem(), isInputTreeItem());
latex = true;
}
} else if (geo == null) {
return;
}
// edited text is plain
if (!latexAfterEdit) {
buildPlainTextItem();
if (!latex) {
// original text was plain
updateItemColor();
} else {
// original text was latex.
updateItemColor();
content.clear();
content.add(getPlainTextItem());
latex = false;
}
}
}
private void updateItemColor() {
if (app.has(Feature.AV_TEXT_BLACK)) {
if (isDefinitionAndValue() && definitionPanel != null) {
definitionPanel.getElement().getStyle().setColor("black");
}
} else {
updateColor(getPlainTextItem());
if (isDefinitionAndValue() && definitionPanel != null) {
updateColor(definitionPanel);
}
}
}
protected abstract void renderLatex(String text0, Widget w,
boolean forceMQ);
private Canvas latexToCanvas(String text) {
return DrawEquationW.paintOnCanvas(geo, text, canvas, getFontSize());
}
private void updateLaTeX(String text) {
if (!isDefinitionAndValue()) {
content.clear();
canvas = DrawEquationW.paintOnCanvas(geo, text, canvas,
getFontSize());
content.add(canvas);
return;
}
}
protected void adjustToPanel(final FlowPanel panel) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
int width = panel.getOffsetWidth()
+ marblePanel.getOffsetWidth();
setAVItemWidths(width);
}
});
}
void setAVItemWidths(int width) {
if (getOffsetWidth() < width) {
getAV().setItemWidth(width);
}
}
public void setItemWidth(int width) {
if (getOffsetWidth() != width) {
if (isInputTreeItem()) {
Element inputParent = getWidget().getElement().getParentElement();
Resizer.setPixelWidth(inputParent, width);
} else {
setWidth(width + "px");
}
}
onResize();
}
protected void replaceToCanvas(String text, Widget old) {
updateLaTeX(text);
LayoutUtilW.replace(content, canvas, old);
}
/**
* @return size for JLM texts. Due to different fonts we need a bit more
* than app.getFontSize(), but +3 looked a bit too big
*/
protected int getFontSize() {
return app.getFontSizeWeb() + 1;
}
protected void updateColor(Widget w) {
if (geo != null) {
w.getElement().getStyle()
.setColor(GColor.getColorString(geo.getAlgebraColor()));
}
}
public abstract void cancelEditing();
/**
* Switches to edit mode
*
* @param substituteNumbers
* whether value should be used
* @return whether it was successful
*/
public boolean enterEditMode(boolean substituteNumbers) {
if (app.has(Feature.AV_INPUT_BUTTON_COVER)) {
content.addStyleName("scrollableTextBox");
if (isInputTreeItem()) {
setItemWidth(getAV().getOffsetWidth());
}
}
if (controller.isEditing()) {
return true;
}
if (controls != null) {
controls.update(true);
}
controller.setEditing(true);
if (!onEditStart(false)) {
return false;
}
if (controls != null) {
controls.setVisible(true);
updateButtonPanelPosition();
}
maybeSetPButtonVisibility(true);
return true;
}
protected String getTextForEditing(boolean substituteNumbers,
StringTemplate tpl) {
return geo.getLaTeXAlgebraDescriptionWithFallback(
substituteNumbers
|| (geo instanceof GeoNumeric
&& geo.isSimple()),
tpl, true);
}
/**
* Starts the equation editor for the item
*/
public abstract boolean onEditStart(boolean substituteNumbers);
protected boolean isDefinitionAndValue() {
return definitionAndValue && kernel
.getAlgebraStyle() == Kernel.ALGEBRA_STYLE_DEFINITION_AND_VALUE;
}
private static boolean isMoveablePoint(GeoElement point) {
return (point.isPointInRegion() || point.isPointOnPath())
&& point.isPointerChangeable();
}
public void styleEditor() {
if (!app.has(Feature.AV_INPUT_BUTTON_COVER)) {
return;
}
if (isInputTreeItem()) {
// setItemWidth(getAV().getMaxItemWidth());
} else {
content.removeStyleName("scrollableTextBox");
}
}
public void styleScrollBox() {
content.addStyleName("scrollableTextBox");
}
public final void stopEditing(String newValue0,
final AsyncOperation<GeoElementND> callback) {
stopEditing(newValue0, callback, true);
}
public final void stopEditing(String newValue0,
final AsyncOperation<GeoElementND> callback,
boolean allowSliderDialog) {
lastTeX = null;
lastInput = null;
styleEditor();
if (stylebarShown != null) {
getAlgebraDockPanel().showStyleBarPanel(stylebarShown);
stylebarShown = null;
}
removeCloseButton();
controller.setEditing(false);
av.cancelEditItem();
getAV().setLaTeXLoaded();
if (app.has(Feature.AV_INPUT_BUTTON_COVER)) {
if (btnClearInput != null && !app.has(Feature.AV_SINGLE_TAP_EDIT)) {
content.remove(btnClearInput);
btnClearInput = null;
}
if (controls != null) {
controls.setVisible(true);
}
}
if (newValue0 != null) {
String rawInput = stopCommon(newValue0);
String newValue = app.getKernel().getInputPreviewHelper()
.getInput(rawInput);
boolean valid = rawInput != null && rawInput.equals(newValue);
// Formula Hacks ended.
if (geo != null) {
boolean redefine = !isMoveablePoint(geo);
RadioTreeItem.this.lastInput = newValue;
RadioTreeItem.this.lastTeX = RadioTreeItem.this
.getEditorLatex();
if (RadioTreeItem.this.lastTeX == null) {
RadioTreeItem.this.lastInput = null;
}
kernel.getAlgebraProcessor().changeGeoElement(geo, newValue,
redefine, true,
getErrorHandler(valid, allowSliderDialog),
new AsyncOperation<GeoElementND>() {
@Override
public void callback(GeoElementND geo2) {
if (geo2 != null) {
geo = geo2.toGeoElement();
lastTeX = null;
lastInput = null;
}
if (marblePanel != null) {
marblePanel.updateIcons(false);
}
updateAfterRedefine(true);
if (callback != null) {
callback.callback(geo2);
}
}
});
if (app.has(Feature.AV_SINGLE_TAP_EDIT)
&& !geo.isIndependent()) {
if (callback != null) {
callback.callback(geo);
}
}
return;
}
} else {
if (isDefinitionAndValue()) {
cancelDV();
}
}
// empty new value -- consider success to make sure focus goes away
updateAfterRedefine(newValue0 == null);
}
protected abstract String getEditorLatex();
/**
* @param success
* whether redefinition was successful
*/
protected void updateAfterRedefine(boolean success) {
if (latexItem == null) {
return;
}
if (!this.isInputTreeItem() && canvas != null
&& content.getElement().isOrHasChild(latexItem.getElement())) {
if (geo != null) {
LayoutUtilW.replace(content, canvas, latexItem);
}
}
if (success && typeChanged()) {
av.remove(geo);
av.add(geo);
}
if (!latex && !this.isInputTreeItem() && getPlainTextItem() != null
&& content.getElement().isOrHasChild(latexItem.getElement())) {
LayoutUtilW.replace(content, getPlainTextItem(), latexItem);
}
// maybe it's possible to enter something which is non-LaTeX
if (success) {
doUpdateEnsureNoEditor();
}
}
private boolean typeChanged() {
return (isSliderItem() != SliderTreeItemRetex.match(geo))
|| (isCheckBoxItem() != CheckboxTreeItem.match(geo));
}
private void cancelDV() {
// LayoutUtilW.replace(ihtml, definitionPanel, latexItem);
doUpdateEnsureNoEditor();
}
protected String stopCommon(String newValue) {
return newValue;
}
protected abstract void blurEditor();
private static final int MARGIN_RESIZE = 50;
protected void clearErrorLabel() {
commandError = null;
errorMessage = null;
}
/**
* @param valid
* whether this is for valid string (false = last valid substring
* used)
* @return error handler
*/
protected final ErrorHandler getErrorHandler(final boolean valid,
final boolean allowSliders) {
clearErrorLabel();
return new ErrorHandler(){
@Override
public void showError(String msg) {
RadioTreeItem.this.errorMessage = valid ? msg
: loc.getError("InvalidInput");
RadioTreeItem.this.commandError = null;
showCurrentError();
saveError();
}
@Override
public void resetError() {
showError(null);
}
@Override
public boolean onUndefinedVariables(String string,
AsyncOperation<String[]> callback) {
if (allowSliders && valid) {
return showSliderDialog(string, callback);
} else if (app.getLocalization()
.getReverseCommand(getCurrentCommand()) != null) {
showCommandError(app.getLocalization()
.getReverseCommand(getCurrentCommand()), null);
return false;
}
callback.callback(new String[] { "7" });
return false;
}
@Override
public void showCommandError(final String command,
final String message) {
RadioTreeItem.this.commandError = command;
RadioTreeItem.this.errorMessage = message;
showCurrentError();
saveError();
}
@Override
public String getCurrentCommand() {
return RadioTreeItem.this.getCommand();
}
};
}
protected boolean showSliderDialog(String string,
AsyncOperation<String[]> callback) {
return app.getGuiManager().checkAutoCreateSliders(string, callback);
}
protected void saveError() {
if (geo != null) {
geo.setUndefined();
geo.updateRepaint();
RadioTreeItem.this.updateAfterRedefine(true);
if (marblePanel != null) {
marblePanel.updateIcons(true);
}
}
}
boolean showCurrentError() {
if (commandError != null) {
ToolTipManagerW.sharedInstance().setBlockToolTip(false);
ToolTipManagerW.sharedInstance().showBottomInfoToolTip(
StringUtil.toHTMLString(errorMessage),
app.getGuiManager().getHelpURL(Help.COMMAND, commandError),
ToolTipLinkType.Help, app, true);
ToolTipManagerW.sharedInstance().setBlockToolTip(true);
return true;
}
if (errorMessage != null) {
ToolTipManagerW.sharedInstance().showBottomMessage(errorMessage,
true, app);
return true;
}
return false;
}
protected boolean setErrorText(String msg) {
if (StringUtil.empty(msg)) {
clearErrorLabel();
return true;
}
ToolTipManagerW.sharedInstance().showBottomMessage(msg, true,
app);
return false;
}
/**
* @param show
* whether to show input help
*/
/**
* @param show
* true to show input help
*/
public void setShowInputHelpPanel(boolean show) {
if (show) {
if (!av.isEditItem()) {
ensureEditing();
}
removeDummy();
if (isInputTreeItem()) {
getController().setFocus(true);
}
InputBarHelpPanelW helpPanel = (InputBarHelpPanelW) app
.getGuiManager().getInputHelpPanel();
if (helpPopup == null) {
helpPopup = new InputBarHelpPopup(this.app, this,
"helpPopupAV");
helpPopup.addAutoHidePartner(this.getElement());
helpPopup.addCloseHandler(new CloseHandler<GPopupPanel>() {
@Override
public void onClose(CloseEvent<GPopupPanel> event) {
focusAfterHelpClosed();
}
});
if (marblePanel != null) {
helpPopup.setBtnHelpToggle(marblePanel.getBtnHelpToggle());
}
} else if (helpPopup.getWidget() == null) {
helpPanel = (InputBarHelpPanelW) app.getGuiManager()
.getInputHelpPanel();
helpPopup.add(helpPanel);
}
updateHelpPosition(helpPanel);
} else if (helpPopup != null) {
helpPopup.hide();
}
}
protected void focusAfterHelpClosed() {
content.getElement().getElementsByTagName("textarea").getItem(0).focus();
}
boolean styleBarCanHide() {
if (!getAlgebraDockPanel().isStyleBarPanelShown()) {
return false;
}
int itemTop = this.isInputTreeItem()
? main.getElement()
.getAbsoluteTop() : getElement()
.getAbsoluteTop();
return (itemTop - getAlgebraDockPanel().getAbsoluteTop() < 35);
}
protected int getWidthForEdit() {
if (app.has(Feature.AV_SINGLE_TAP_EDIT)) {
if (isDefinitionAndValue() && geo.needToShowBothRowsInAV()
&& definitionPanel != null
&& definitionPanel.getWidget(0) != null) {
return marblePanel.getOffsetWidth()
+ definitionPanel.getWidget(0).getOffsetWidth()
+ controls.getOffsetWidth() + DEFINITION_ROW_EDIT_MARGIN
+ MARGIN_RESIZE;
}
return marblePanel.getOffsetWidth() + content.getOffsetWidth()
+ MARGIN_RESIZE;
}
int appWidth = (int) app.getWidth();
if (appWidth < 1) {// for case app is not part of DOM
appWidth = 600;
}
int maxToExpand = Math.min(content.getOffsetWidth() + 70,
getAV().getOffsetWidth() * 2);
return Math.min(maxToExpand, appWidth);
}
public void update() {
// marblePanel.setBackground();
}
protected void updateButtonPanelPosition() {
if (controls == null) {
return;
}
boolean accurate = true; // used for testing the new code
if (styleBarCanHide()) {
ScrollPanel algebraPanel = ((AlgebraDockPanelW) app.getGuiManager()
.getLayout().getDockManager().getPanel(App.VIEW_ALGEBRA))
.getAbsolutePanel();
if (accurate) { // new code
controls.reposition();
} else { // old code
if (algebraPanel != null
&& algebraPanel.getOffsetWidth() > algebraPanel.getElement()
.getClientWidth()) {
controls.addStyleName(
"positionedObjectStyleBar_scrollbarVisible");
controls.removeStyleName("positionedObjectStyleBar");
} else {
controls.addStyleName("positionedObjectStyleBar");
controls
.removeStyleName("positionedObjectStyleBar_scrollbarVisible");
}
}
} else {
if (accurate) {
controls.reposition();
// controls.getElement().getStyle().setRight(visibleRight,
// Unit.PX);
} else {
controls.removeStyleName("positionedObjectStyleBar");
controls
.removeStyleName("positionedObjectStyleBar_scrollbarVisible");
}
}
}
protected AlgebraViewW getAV() {
return (AlgebraViewW) av;
}
public GeoElement getGeo() {
return geo;
}
private boolean selectedItem = false;
// controls must appear on select or not
private boolean forceControls = false;
/**
* This method shall only be called when we are not doing editing, so this
* is for the delete button at selection
*/
protected PushButton getPButton() {
return null;
}
/**
* @param bool
* whether pbutton should be visible
*/
protected void maybeSetPButtonVisibility(boolean bool) {
// only show the delete button, but not the extras
}
public void scrollIntoView() {
this.getElement().scrollIntoView();
}
public void removeCloseButton() {
this.maybeSetPButtonVisibility(true);
if (controls != null) {
controls.setVisible(false);
}
}
protected void addAVEXWidget(Widget w) {
main.add(w);
}
protected boolean hasGeoExtendedAV() {
return (geo instanceof HasExtendedAV && ((HasExtendedAV) geo)
.isShowingExtendedAV());
}
public void setDraggable() {
Widget draggableContent = main;
getElement().setAttribute("position", "absolute");
draggableContent.getElement().setDraggable(Element.DRAGGABLE_TRUE);
draggableContent.addDomHandler(new DragStartHandler() {
@Override
public void onDragStart(DragStartEvent event) {
event.setData("text", "draggginggg");
event.getDataTransfer().setDragImage(getElement(), 10, 10);
event.stopPropagation();
getAV().dragStart(event, geo);
}
}, DragStartEvent.getType());
}
// @Override
public AppW getApplication() {
return app;
}
@Override
public void ensureEditing() {
if (!controller.isEditing()) {
enterEditMode(geo == null || isMoveablePoint(geo));
if (av != null && ((AlgebraViewW) av).isNodeTableEmpty()) {
updateGUIfocus(this, false);
}
}
}
/**
* Update GUI after focus
*
* @param source
* event source
* @param blurtrue
* blur
*/
protected void updateGUIfocus(Object source, boolean blurtrue) {
// only in input element
}
@Override
public boolean getAutoComplete() {
// TODO Auto-generated method stub
return false;
}
@Override
public List<String> resetCompletions() {
// TODO Auto-generated method stub
return null;
}
@Override
public List<String> getCompletions() {
// TODO Auto-generated method stub
return null;
}
@Override
public final void toggleSymbolButton(boolean toggled) {
// Just for compatibility with AutoCompleteTextFieldW
}
@Override
public ArrayList<String> getHistory() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setText(String s) {
// TODO Auto-generated method stub
}
@Override
public boolean isSuggesting() {
// TODO Auto-generated method stub
return false;
}
@Override
public void requestFocus() {
// TODO Auto-generated method stub
}
@Override
public final Widget toWidget() {
return main;
}
@Override
public void onResize() {
if (!app.has(Feature.AV_INPUT_BUTTON_COVER)) {
if (first && isSelected()) {
controls.update(true);
}
}
updateButtonPanelPosition();
}
public boolean isItemSelected() {
return selectedItem;
}
private void toggleControls() {
// GGB-986 Don't show controls if geo is only highlighted
// but no selected.
if (controls == null) {
return;
}
if (isForceControls()) {
setForceControls(false);
controls.setVisible(true);
return;
}
showControlsInSelection();
}
private void showControlsInSelection() {
boolean geoInSelection = app.getSelectionManager()
.containsSelectedGeo(geo);
if (!controls.isVisible() && geoInSelection) {
if (controls.update(true)) {
// don't show controls for multiselect
controls.setVisible(true);
}
} else if (controls.isVisible() && !geoInSelection) {
controls.setVisible(false);
}
}
public void selectItem(boolean selected) {
// Log.printStacktrace("[RTI] selectItem: " + selected);
if (app.has(Feature.AV_SINGLE_TAP_EDIT)) {
if (controls != null) {
controls.show(
!controller.hasMultiGeosSelected() && selected);
}
} else {
toggleControls();
}
if (selectedItem == selected) {
return;
}
setForceControls(false);
selectedItem = selected;
if (selected) {
addStyleName("avSelectedRow");
} else {
removeStyleName("avSelectedRow");
}
if (marblePanel != null) {
marblePanel.setHighlighted(selected);
}
if (!selected
// && geo != AVSelectionController.get(app).getLastSelectedGeo()
) {
controls.reset();
}
}
@Override
public UIObject asWidget() {
return main.asWidget();
}
/**
* cast method with no 'instanceof' check.
*
* @param item
* TreeItem to be casted
* @return Casted item to RadioTreeItem
*/
public static RadioTreeItem as(TreeItem item) {
return (RadioTreeItem) item;
}
public Element getScrollElement() {
return getWidget().getElement();
}
protected AlgebraDockPanelW getAlgebraDockPanel() {
return (AlgebraDockPanelW) app.getGuiManager().getLayout()
.getDockManager().getPanel(App.VIEW_ALGEBRA);
}
@Override
public void autocomplete(String s) {
// TODO implement autocomplete in RTI
}
public FlowPanel getPlainTextItem() {
return plainTextItem;
}
public void setPlainTextItem(FlowPanel plainTextItem) {
this.plainTextItem = plainTextItem;
}
public boolean isNeedsUpdate() {
return needsUpdate;
}
public void setNeedsUpdate(boolean needsUpdate) {
this.needsUpdate = needsUpdate;
}
/**
*
* @return if the item is the input or not.
*/
public boolean isInputTreeItem() {
return false;
}
protected boolean hasAnimPanel() {
return controls.animPanel != null;
}
protected boolean hasMarblePanel() {
return marblePanel != null;
}
private String getOutputPrefix() {
if (geo instanceof HasSymbolicMode
&& !((HasSymbolicMode) geo).isSymbolicMode()) {
return Unicode.CAS_OUTPUT_NUMERIC;
}
if (kernel.getLocalization().rightToLeftReadingOrder) {
return Unicode.CAS_OUTPUT_PREFIX_RTL;
}
return Unicode.CAS_OUTPUT_PREFIX;
}
public void setLabels() {
if (hasMarblePanel()) {
marblePanel.setLabels();
}
}
/**
* Remove the main panel from parent
*/
public void removeFromParent() {
main.removeFromParent();
}
public final boolean hasHelpPopup() {
return this.helpPopup != null;
}
public void replaceXButtonDOM() {
// TODO Auto-generated method stub
}
public abstract void handleFKey(int key, GeoElement geo1);
@Override
public Widget getHelpToggle() {
return this.marblePanel;
}
private void updateIcons(boolean warning) {
if (this.marblePanel != null) {
marblePanel.updateIcons(warning);
}
}
protected void updateHelpPosition(final InputBarHelpPanelW helpPanel) {
helpPopup.setPopupPositionAndShow(new GPopupPanel.PositionCallback() {
@Override
public void setPosition(int offsetWidth, int offsetHeight) {
Widget btn = marblePanel.getBtnHelpToggle() == null ?
marblePanel.getBtnPlus():
marblePanel.getBtnHelpToggle();
double scale = app.getArticleElement().getScaleX();
double renderScale = app.getArticleElement().getDataParamApp()
? scale : 1;
helpPopup.getElement().getStyle()
.setProperty("left",
(btn.getAbsoluteLeft()
- app.getAbsLeft()
+ btn.getOffsetWidth())
* renderScale
+ "px");
int maxOffsetHeight;
int totalHeight = (int) app.getHeight();
int toggleButtonTop = (int) ((btn
.getParent()
.getAbsoluteTop() - (int) app.getAbsTop()) / scale);
if (toggleButtonTop < totalHeight / 2) {
int top = (toggleButtonTop
+ btn.getParent()
.getOffsetHeight());
maxOffsetHeight = totalHeight - top;
helpPopup.getElement().getStyle().setProperty("top",
top * renderScale + "px");
helpPopup.getElement().getStyle().setProperty("bottom",
"auto");
helpPopup.removeStyleName("helpPopupAVBottom");
helpPopup.addStyleName("helpPopupAV");
} else {
int minBottom = app.isApplet() ? 0 : 10;
int bottom = (totalHeight
- toggleButtonTop);
maxOffsetHeight = bottom > 0 ? totalHeight - bottom
: totalHeight - minBottom;
helpPopup.getElement().getStyle().setProperty("bottom",
(bottom > 0 ? bottom : minBottom) * renderScale
+ "px");
helpPopup.getElement().getStyle().setProperty("top",
"auto");
helpPopup.removeStyleName("helpPopupAV");
helpPopup.addStyleName("helpPopupAVBottom");
}
helpPanel.updateGUI(maxOffsetHeight, 1);
helpPopup.show();
}
});
}
protected final void insertHelpToggle() {
updateIcons(false);
if (marblePanel == null) {
this.addMarble();
}
main.insert(marblePanel, 0);
}
/**
* @return whether input text is empty
*/
protected boolean isEmpty() {
return "".equals(getText().trim());
}
protected void addDummyLabel() {
if (dummyLabel == null) {
dummyLabel = new Label(
loc.getMenu("InputLabel") + Unicode.ellipsis);
dummyLabel.addStyleName("avDummyLabel");
}
updateFont(dummyLabel);
if (canvas != null) {
canvas.setVisible(false);
}
// if (dummyLabel.getElement() != null) {
// if (dummyLabel.getElement().hasParentElement()) {
// in theory, this is done in insertFirst,
// just making sure here as well
// dummyLabel.getElement().removeFromParent();
// }
content.insert(dummyLabel, 0);
removeOutput();
// }
if (app.has(Feature.AV_INPUT_BUTTON_COVER)) {
if (btnClearInput != null) {
btnClearInput.removeFromParent();
btnClearInput = null;
}
if (controls != null) {
controls.setVisible(true);
}
setLatexItemVisible(false);
}
}
private void setLatexItemVisible(boolean b) {
if (this.latexItem != null) {
this.latexItem.setVisible(b);
}
}
protected void removeDummy() {
if (this.dummyLabel != null) {
dummyLabel.removeFromParent();
}
if (canvas != null) {
canvas.setVisible(true);
}
if (app.has(Feature.AV_INPUT_BUTTON_COVER)) {
if (!app.has(Feature.AV_SINGLE_TAP_EDIT) || isInputTreeItem()) {
boolean hasMoreMenu = app.has(Feature.AV_MORE_MENU);
if (!hasMoreMenu) {
content.insert(getClearInputButton(), 0);
}
if (controls != null) {
controls.setVisible(hasMoreMenu);
}
adjustStyleBar();
}
setLatexItemVisible(true);
}
}
protected void updateEditorFocus(Object source, boolean blurtrue) {
// deselects current selection
((AlgebraViewW) av).setActiveTreeItem(null);
boolean emptyCase = ((AlgebraViewW) av).isNodeTableEmpty()
&& !this.getAlgebraDockPanel().hasLongStyleBar();
// update style bar icon look
if (emptyCase) {
getAlgebraDockPanel().showStyleBarPanel(blurtrue);
} else {
getAlgebraDockPanel().showStyleBarPanel(true);
}
// After changing the stylebar visibility, maybe the small stylebar's
// position will be changed too
if (controls != null) {
updateButtonPanelPosition();
}
// always show popup, except (blurtrue && emptyCase) == true
// this basically calls the showPopup method, like:
// showPopup(!blurtrue || !emptyCase);
AutoCompleteTextFieldW.showSymbolButtonIfExists(source,
!blurtrue || !emptyCase);
// afterwards, if the popup shall be showing,
// then all of our three icons are visible in theory
// except pButton, if it is null...
// if (!blurtrue || !emptyCase) {
// typing(false);
// }
}
public abstract RadioTreeItem copy();
@Override
public void updatePosition(AbstractSuggestionDisplay sug) {
sug.setPositionRelativeTo(content);
}
@Override
public boolean isForCAS() {
return false;
}
@Override
public boolean needsAutofocus() {
return true;
}
protected PushButton getClearInputButton() {
if (btnClearInput == null) {
btnClearInput = new PushButton(
new Image(GuiResources.INSTANCE.algebra_delete()));
btnClearInput.addMouseDownHandler(new MouseDownHandler() {
@Override
public void onMouseDown(MouseDownEvent event) {
clearInput();
getController().setFocus(true);
event.stopPropagation();
}
});
btnClearInput.addStyleName("ggb-btnClearAVInput");
}
return btnClearInput;
}
public boolean isForceControls() {
return forceControls;
}
public void setForceControls(boolean forceControls) {
this.forceControls = forceControls;
}
/**
* @param pixelRatio
* pixel ratio for input panel
*/
public void setPixelRatio(double pixelRatio) {
// only for LaTeX tree item
}
public boolean isSliderItem() {
return false;
}
public boolean isCheckBoxItem() {
return false;
}
public RadioTreeItemController getController() {
return controller;
}
public void setController(RadioTreeItemController controller) {
this.controller = controller;
}
public void reposition() {
if (controls != null) {
controls.reposition();
}
}
public boolean hasGeo() {
return geo != null;
}
public void hideControls() {
if (controls != null) {
controls.setVisible(false);
}
}
void adjustStyleBar() {
// expandSize(getWidthForEdit());
if (styleBarCanHide() && (!getAlgebraDockPanel().isStyleBarVisible())) {
stylebarShown = getAlgebraDockPanel().isStyleBarPanelShown();
getAlgebraDockPanel().showStyleBarPanel(false);
if (controls != null) {
controls.reposition();
}
}
if (!app.has(Feature.AV_SINGLE_TAP_EDIT) && controls != null) {
controls.removeAnimPanel();
}
}
public void showControls() {
if (controls != null) {
controls.setVisible(true);
}
}
protected void showKeyboard() {
app.showKeyboard(this);
}
/**
* @param x
* click event x-coord
* @param y
* click event y-coord
*/
public void adjustCaret(int x, int y) {
// only in JLM
}
public void updateFonts() {
// only in JLM
}
public void preventBlur() {
// TODO Auto-generated method stub
}
public void setError(String error) {
this.errorMessage = error;
this.commandError = null;
if (marblePanel != null) {
marblePanel.updateIcons(error != null);
}
}
public void setCommandError(String command) {
this.commandError = command;
if (marblePanel != null) {
marblePanel.updateIcons(true);
}
}
public void removeOutput() {
if (outputPanel != null) {
outputPanel.removeFromParent();
}
}
}