package org.geogebra.common.kernel.scripting; import org.geogebra.common.awt.GColor; import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.Command; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.ExpressionValue; import org.geogebra.common.kernel.arithmetic.MyDouble; import org.geogebra.common.kernel.arithmetic.NumberValue; import org.geogebra.common.kernel.commands.CmdScripting; import org.geogebra.common.kernel.commands.EvalInfo; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoText; import org.geogebra.common.main.GeoGebraColorConstants; import org.geogebra.common.main.MyError; import org.geogebra.common.util.StringUtil; /** * SetColor */ public class CmdSetColor extends CmdScripting { /** true for CmdSetBackgroundColor */ protected boolean background = false; /** * Create new command processor * * @param kernel * kernel */ public CmdSetColor(Kernel kernel) { super(kernel); } @Override protected GeoElement[] perform(Command c) throws MyError { int n = c.getArgumentNumber(); EvalInfo argInfo = new EvalInfo(false); boolean oldMacroMode = cons.isSuppressLabelsActive(); cons.setSuppressLabelCreation(true); GeoElement[] arg; // SetBackgroundColor["red"] if (background && n == 1) { ExpressionNode en = c.getArguments()[0]; ExpressionValue ev = en.evaluate(StringTemplate.defaultTemplate); String color = ev.toString(StringTemplate.defaultTemplate); try { color = StringUtil.removeSpaces(color.replace("\"", "")); // lookup Color GColor col = GeoGebraColorConstants.getGeogebraColor(app, color); // SetBackgroundColor("none") is NOT OK if (col == null) { throw argErr(app, c, ev); } setViewBackground(col); return null; } catch (Exception e) { e.printStackTrace(); throw argErr(app, c, ev); } } // SetBackgroundColor[0,1,0] if (background && n == 3) { GeoElement[] args = resArgs(c); GeoElement enR = args[0]; GeoElement enG = args[1]; GeoElement enB = args[2]; double redD = enR.evaluateDouble(); double greenD = enG.evaluateDouble(); double blueD = enB.evaluateDouble(); if (Double.isNaN(redD) || Double.isInfinite(redD)) { throw argErr(app, c, enR.evaluate(StringTemplate.defaultTemplate)); } if (Double.isNaN(greenD) || Double.isInfinite(greenD)) { throw argErr(app, c, enG.evaluate(StringTemplate.defaultTemplate)); } if (Double.isNaN(blueD) || Double.isInfinite(blueD)) { throw argErr(app, c, enB.evaluate(StringTemplate.defaultTemplate)); } int red = MyDouble.normalize0to255(redD); int green = MyDouble.normalize0to255(greenD); int blue = MyDouble.normalize0to255(blueD); GColor col = GColor.newColor(red, green, blue); setViewBackground(col); return null; } if (n == 2) { // adapted from resArgs() ExpressionNode[] args = c.getArguments(); arg = new GeoElement[args.length]; // resolve first argument args[0].resolveVariables(argInfo); arg[0] = resArg(args[0], argInfo)[0]; try { // resolve second argument args[1].resolveVariables(argInfo); arg[1] = resArg(args[1], argInfo)[0]; } catch (Error e) { // if there's a problem with the second argument, just wrap in // quotes in case it's a color // eg SetColor[A,blue] rather than SetColor[A,"blue"] arg[1] = new GeoText(cons, args[1].toString(StringTemplate.defaultTemplate)); } cons.setSuppressLabelCreation(oldMacroMode); } else { arg = resArgs(c); } switch (n) { case 2: if (!arg[1].isGeoText()) { throw argErr(app, c, arg[1]); } try { String color = StringUtil .removeSpaces(((GeoText) arg[1]).getTextString()); // lookup Color // HashMap<String, Color> colors = app.getColorsHashMap(); // Color col = colors.get(color); GColor col = GeoGebraColorConstants.getGeogebraColor(app, color); // SetBackgroundColor(text1, "none") is OK if (col == null && !background) { throw argErr(app, c, arg[1]); } if (background) { arg[0].setBackgroundColor(col); } else { arg[0].setObjColor(col); } arg[0].updateRepaint(); return arg; } catch (Exception e) { e.printStackTrace(); throw argErr(app, c, arg[0]); } case 4: boolean[] ok = new boolean[n]; arg = resArgs(c); if ((ok[1] = arg[1] instanceof NumberValue) && (ok[2] = arg[2] instanceof NumberValue) && (ok[3] = arg[3] instanceof NumberValue)) { int red = MyDouble .normalize0to255(((NumberValue) arg[1]).getDouble()); int green = MyDouble .normalize0to255(((NumberValue) arg[2]).getDouble()); int blue = MyDouble .normalize0to255(((NumberValue) arg[3]).getDouble()); if (background) { arg[0].setBackgroundColor( GColor.newColor(red, green, blue)); } else { arg[0].setObjColor(GColor.newColor(red, green, blue)); } arg[0].updateRepaint(); return arg; } else if (!ok[1]) { throw argErr(app, c, arg[1]); } else if (!ok[2]) { throw argErr(app, c, arg[2]); } else { throw argErr(app, c, arg[3]); } default: throw argNumErr(app, c, n); } } private void setViewBackground(GColor col) { EuclidianViewInterfaceCommon view = app.getActiveEuclidianView(); view.getSettings().setBackground(col); view.updateBackground(); } }