package org.geogebra.web.web.gui.view.spreadsheet;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.gui.view.spreadsheet.CellFormat;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.geos.GeoBoolean;
import org.geogebra.common.kernel.geos.GeoButton;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoText;
import org.geogebra.web.html5.main.AppW;
import org.geogebra.web.html5.main.DrawEquationW;
import org.geogebra.web.html5.main.MyImageW;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
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.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
public class MyCellRendererW implements MouseDownHandler, MouseUpHandler {
// ggb fields
private AppW app;
private Kernel kernel;
private SpreadsheetViewW view;
private Grid table;
// LaTeX
// private ImageIcon latexIcon, emptyIcon;
// Cell formats
private CellFormat formatHandler;
// Cell geo
private GeoElement geo;
/*********************************************************
* Constructor
*
* @param app
* @param view
* @param formatHandler
*/
public MyCellRendererW(AppW app, SpreadsheetViewW view,
MyTableW table, CellFormat formatHandler) {
this.app = app;
this.kernel = app.getKernel();
this.formatHandler = formatHandler;
this.view = view;
this.table = table.getGrid();
}
public void updateCellFormat(GeoElement geo, int row, int column) {
Style s = table.getCellFormatter().getElement(row, column).getStyle();
//cellPoint.setLocation(column, row);
// Font style
Integer fontStyle = (Integer) formatHandler.getCellFormat(column, row,
CellFormat.FORMAT_FONTSTYLE);
s.setFontSize(app.getFontSizeWeb(), Unit.PX);
if (fontStyle == null) {
s.setFontStyle(Style.FontStyle.NORMAL);
s.setFontWeight(Style.FontWeight.NORMAL);
} else {
if (fontStyle == CellFormat.STYLE_ITALIC
|| fontStyle == CellFormat.STYLE_BOLD_ITALIC) {
s.setFontStyle(Style.FontStyle.ITALIC);
} else {
s.setFontStyle(Style.FontStyle.NORMAL);
}
if (fontStyle == CellFormat.STYLE_BOLD
|| fontStyle == CellFormat.STYLE_BOLD_ITALIC) {
s.setFontWeight(Style.FontWeight.BOLD);
} else {
s.setFontWeight(Style.FontWeight.NORMAL);
}
}
// Foreground color
if (geo != null) {
if (geo.getLabelColor() != null) {
s.setColor(geo.getLabelColor().toString());
} else {
s.clearColor();
}
}
// Alignment
Integer alignment = (Integer) formatHandler.getCellFormat(column, row,
CellFormat.FORMAT_ALIGN);
if (alignment != null) {
s.setProperty("textAlign",
alignment == CellFormat.ALIGN_LEFT ? "left"
: (alignment == CellFormat.ALIGN_RIGHT ? "right"
: "center"));
} else if (geo != null && geo.isGeoText()) {
s.setProperty("textAlign", "left");
} else {
s.setProperty("textAlign", "right");
}
// Background color
updateCellBackground(geo, row, column);
// Border
updateCellBorder(row, column);
}
public void clearBorder(int row, int column) {
Style s = table.getCellFormatter().getElement(row, column).getStyle();
s.clearProperty("borderBottomColor");
s.clearProperty("borderRightColor");
}
public void updateColumnBorder(int column) {
Byte border = (Byte) formatHandler.getCellFormat(column, -1,
CellFormat.FORMAT_BORDER);
if (border != null) {
if (!CellFormat.isZeroBit(border, 0)) {
for (int row = 0; row < 20; row++) {
// left borders' width is 0px, so left neighbor's right
// border
// will be colored.
if (column > 0) {
Style sLeft = table.getCellFormatter()
.getElement(row, column - 1).getStyle();
sLeft.setProperty("borderRightColor", "#000000");
}
}
}
if (!CellFormat.isZeroBit(border, 2)) {
for (int row = 0; row < 20; row++) {
Style s = table.getCellFormatter().getElement(row, column)
.getStyle();
s.setProperty("borderRightColor", "#000000");
}
}
}
}
public void updateRowBorder(int row) {
Byte border = (Byte) formatHandler.getCellFormat(-1, row,
CellFormat.FORMAT_BORDER);
if (border != null) {
if (!CellFormat.isZeroBit(border, 1)) {
// top borders' width is 0px, so top neighbor's bottom border
// will be colored.
for (int column = 0; column < 20; column++) {
if (row > 0) {
Style sTop = table.getCellFormatter()
.getElement(row - 1, column).getStyle();
sTop.setProperty("borderBottomColor", "#000000");
}
}
}
if (!CellFormat.isZeroBit(border, 3)) {
for (int column = 0; column < 20; column++) {
Style s = table.getCellFormatter()
.getElement(row - 1, column).getStyle();
s.setProperty("borderBottomColor", "#000000");
}
}
}
}
public void updateCellBorder(int row, int column) {
Byte border = (Byte) formatHandler.getCellFormat(column, row,
CellFormat.FORMAT_BORDER);
if ((row == -1) || (column == -1)) {
return;
}
Style s = table.getCellFormatter().getElement(row, column).getStyle();
// s.clearProperty("borderBottomColor");
// s.clearProperty("borderRightColor");
if (border != null) {
// left bar, 0
if (!CellFormat.isZeroBit(border, 0)) {
// left borders' width is 0px, so left neighbor's right border
// will be colored.
if (column > 0) {
Style sLeft = table.getCellFormatter()
.getElement(row, column - 1).getStyle();
sLeft.setProperty("borderRightColor", "#000000");
}
}
// top bar, 1
if (!CellFormat.isZeroBit(border, 1)) {
// top borders' width is 0px, so top neighbor's bottom border
// will be colored.
if (row > 0) {
Style sTop = table.getCellFormatter()
.getElement(row - 1, column).getStyle();
sTop.setProperty("borderBottomColor", "#000000");
}
}
// right bar, 2
if (!CellFormat.isZeroBit(border, 2)) {
s.setProperty("borderRightColor", "#000000");
}
// bottom bar, 3
if (!CellFormat.isZeroBit(border, 3)) {
s.setProperty("borderBottomColor", "#000000");
}
}
}
public void updateCellBackground(GeoElement geo, int row,
int column) {
GColor bgColor = (GColor) formatHandler.getCellFormat(column, row,
CellFormat.FORMAT_BGCOLOR);
if (geo != null) {
if (bgColor == null && geo.getBackgroundColor() != null) {
bgColor = geo.getBackgroundColor();
}
// adjust selection color when there is a bgColor
if (geo.doHighlighting()) {
if (bgColor != null) {
bgColor = bgColor.darker();
} else {
bgColor = MyTableW.SELECTED_BACKGROUND_COLOR;
}
}
}
Style s = table.getCellFormatter().getElement(row, column).getStyle();
if (bgColor != null) {
s.setBackgroundColor(bgColor.toString());
} else {
s.clearBackgroundColor();
}
}
public void updateTableCellValue(Grid table, Object value, final int row, final int column) {
// Get the cell geo, exit if null
if (value != null) {
geo = (GeoElement) value;
} else {
table.setText(row, column, " ");
return;
}
if (geo.isGeoImage()) {
final MyImageW mw = (MyImageW) geo.getFillImage();
if (mw != null) {
SimplePanel sp = new SimplePanel();
sp.addStyleName("SVCenterParent");
Canvas canv = Canvas.createIfSupported();
canv.addStyleName("SVCenterContent");
canv.setCoordinateSpaceWidth(mw.getWidth());
canv.setCoordinateSpaceHeight(mw.getHeight());
canv.setWidth(mw.getWidth() + "px");
canv.setHeight(mw.getHeight() + "px");
Context2d c2d = canv.getContext2d();
c2d.drawImage(mw.getImage(), 0, 0);
sp.add(canv);
table.setWidget(row, column, sp);
table.getCellFormatter().getElement(row, column)
.addClassName("SVCenterTD");
return;
}
}
table.getCellFormatter().getElement(row, column)
.removeClassName("SVCenterTD");
// Set text according to algebra style
String text = "";
String latex = null;
if (geo.isEmptySpreadsheetCell()) {
text = "";
} else if (geo.isIndependent()) {
if (geo.isLaTeXDrawableGeo()
&& (!geo.isGeoText() || ((GeoText) geo).isLaTeX())) {
latex = geo.getLaTeXdescription();
}
text = geo.toValueString(StringTemplate.defaultTemplate);
} else {
switch (kernel.getAlgebraStyleSpreadsheet()) {
default:
case Kernel.ALGEBRA_STYLE_VALUE:
if (geo.isLaTeXDrawableGeo()
&& (!geo.isGeoText() || ((GeoText) geo).isLaTeX())) {
latex = geo.getLaTeXdescription();
}
text = geo.toValueString(StringTemplate.defaultTemplate);
break;
case Kernel.ALGEBRA_STYLE_DESCRIPTION:
text = geo
.getDefinitionDescription(StringTemplate.defaultTemplate);
break;
case Kernel.ALGEBRA_STYLE_DEFINITION:
text = geo
.getDefinition(StringTemplate.defaultTemplate);
break;
}
}
if (useSpecialEditor()) {
updateSpecialEditor(table, geo, row, column);
return;
}
Canvas c = null;
if (latex != null) {
Widget current = table.getWidget(row, column);
if (!(current instanceof Canvas)) {
c = Canvas.createIfSupported();
table.setWidget(row, column, c);
} else {
c = (Canvas) current;
}
}
if (c == null) {
table.setText(row, column, text);
} else {
DrawEquationW.paintOnCanvas(geo, latex, c, app.getFontSizeWeb());
}
}
@Override
public void onMouseDown(MouseDownEvent e) {
// TODO: maybe use CancelEvents.instance?
e.stopPropagation();
}
@Override
public void onMouseUp(MouseUpEvent e) {
// TODO: maybe use CancelEvents.instance?
e.stopPropagation();
}
private boolean useSpecialEditor() {
if (!view.allowSpecialEditor()
|| (kernel.getAlgebraStyleSpreadsheet() != Kernel.ALGEBRA_STYLE_VALUE)) {
return false;
}
return geo.isGeoBoolean() || geo.isGeoButton() || geo.isGeoList();
}
private void updateSpecialEditor(Grid table, GeoElement geo, int row,
int column) {
if (geo.isGeoBoolean()) {
FlowPanel fp = new FlowPanel();
final CheckBox checkbox = new CheckBox();
fp.add(checkbox);
checkbox.getElement()
.getStyle()
.setBackgroundColor(
table.getElement().getStyle().getBackgroundColor());
fp.getElement().getStyle().setTextAlign(Style.TextAlign.CENTER);
checkbox.setEnabled(geo.isIndependent());
checkbox.getElement().addClassName(
"geogebraweb-checkbox-spreadsheet");
if (geo.isLabelVisible()) {
// checkBox.setText(geo.getCaption());
}
checkbox.setValue(((GeoBoolean) geo).getBoolean());
final GeoBoolean geoBoolean = (GeoBoolean) geo;
checkbox.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent ce) {
if (view.allowSpecialEditor()) {
geoBoolean.setValue(!geoBoolean.getBoolean());
// Don't update all cell, see #5153
// kernel.updateConstruction();
geoBoolean.updateRepaint();
}
}
});
table.setWidget(row, column, fp);
return;
}
if (geo.isGeoButton()) {
final GeoButton gb = (GeoButton) geo;
final Button button = new Button();
button.getElement()
.getStyle()
.setBackgroundColor(
table.getElement().getStyle().getBackgroundColor());
button.setText(geo.getCaption(StringTemplate.defaultTemplate));
button.getElement().getStyle()
.setColor(geo.getObjectColor().toString());
button.getElement().addClassName("geogebraweb-button-spreadsheet");
button.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent ce) {
gb.runClickScripts(null);
gb.getKernel().updateConstruction();
}
});
table.setWidget(row, column, button);
return;
}
if (geo.isGeoList()) {
final GeoList list = (GeoList) geo;
final ListBox lb = new ListBox();
lb.setVisibleItemCount(1);
lb.setEnabled(true);
lb.getElement()
.getStyle()
.setBackgroundColor(
table.getElement().getStyle().getBackgroundColor());
lb.getElement().addClassName("geogebraweb-select-spreadsheet");
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
// toString doesn't work for some reason
lb.addItem(list.get(i).toValueString(
StringTemplate.defaultTemplate));
}
lb.setSelectedIndex(list.getSelectedIndex());
}
lb.addMouseDownHandler(this);
lb.addMouseUpHandler(this);
lb.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent ce) {
if (view.allowSpecialEditor()) {
list.setSelectedIndex(lb.getSelectedIndex(), true);
}
}
});
table.setWidget(row, column, lb);
return;
}
}
}