package org.geogebra.common.gui.dialog.options.model;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.algos.AlgoBarChart;
import org.geogebra.common.kernel.algos.AlgoElement;
import org.geogebra.common.kernel.geos.GProperty;
import org.geogebra.common.kernel.geos.GeoButton;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.main.App;
import org.geogebra.common.main.GeoGebraColorConstants;
import org.geogebra.common.util.StringUtil;
public class ColorObjectModel extends OptionsModel {
public interface IColorObjectListener extends PropertyListener {
void updateChooser(boolean equalObjColor,
boolean equalObjColorBackground, boolean allFillable,
boolean hasBackground, boolean hasAlpha);
void updatePreview(GColor col, double alpha);
boolean isBackgroundColorSelected();
void updateNoBackground(GeoElement geo, GColor col, double alpha,
boolean updateAlphaOnly, boolean allFillable);
}
public static final int ALL_BARS = 0;
private boolean allFillable;
private boolean hasBackground;
private boolean hasImageGeo;
private IColorObjectListener listener;
private Kernel kernel;
public ColorObjectModel(App app) {
super(app);
kernel = app.getKernel();
}
public void setListener(IColorObjectListener listener) {
this.listener = listener;
}
@Override
public void updateProperties() {
GeoElement geo0 = getGeoAt(0);
// check geos for similar properties
boolean equalObjColor = true;
boolean equalObjColorBackground = true;
hasImageGeo = geo0.isGeoImage();
allFillable = geo0.isFillable();
hasBackground = geo0.hasBackgroundColor();
GeoElement temp;
for (int i = 1; i < getGeosLength(); i++) {
temp = getGeoAt(i);
// same object color
if (!geo0.getObjectColor().equals(temp.getObjectColor())) {
equalObjColor = false;
}
// has fill color
if (!temp.isFillable()) {
allFillable = false;
}
// has background
if (!temp.hasBackgroundColor()) {
hasBackground = false;
}
// has image geo
if (temp.isGeoImage()) {
hasImageGeo = true;
}
}
if (hasBackground) {
equalObjColorBackground = true;
if (geo0.getBackgroundColor() == null) {
// test for all null background color
for (int i = 1; i < getGeosLength(); i++) {
temp = getGeoAt(i);
if (temp.getBackgroundColor() != null) {
equalObjColorBackground = false;
break;
}
}
} else {
// test for all same background color
for (int i = 1; i < getGeosLength(); i++) {
temp = getGeoAt(i);
// same background color
if (!geo0.getBackgroundColor().equals(temp.getBackgroundColor())) {
equalObjColorBackground = false;
break;
}
}
}
}
listener.updateChooser(equalObjColor, equalObjColorBackground,
allFillable, hasBackground, hasOpacity(geo0));
}
protected boolean hasOpacity(GeoElement geo) {
boolean hasOpacity = true;
if (geo instanceof GeoButton) {
hasOpacity = false;
}
return hasOpacity;
}
/**
* Sets color of selected GeoElements
*/
private void updateColor(GColor col, double alpha,
boolean updateAlphaOnly) {
if (col == null || getGeos() == null) {
return;
}
listener.updatePreview(col, alpha);
GeoElement geo;
for (int i = 0; i < getGeosLength(); i++) {
geo = getGeoAt(i);
if (hasBackground && listener.isBackgroundColorSelected()) {
geo.setBackgroundColor(col);
} else {
listener.updateNoBackground(geo, col, alpha, updateAlphaOnly,
allFillable);
}
geo.updateVisualStyle(GProperty.COLOR);
}
kernel.notifyRepaint();
}
/**
* Sets the background color of selected GeoElements to null
*/
public void clearBackgroundColor() {
GeoElement geo;
for (int i = 0; i < getGeosLength(); i++) {
geo = getGeoAt(i);
geo.setBackgroundColor(null);
geo.updateVisualStyle(GProperty.COLOR_BG);
}
kernel.notifyRepaint();
}
@Override
public boolean checkGeos() {
return true;
}
/**
* Listens for color chooser state changes
*/
public void applyChanges(GColor color, double alpha, boolean alphaOnly) {
updateColor(color, alpha, alphaOnly);
storeUndoInfo();
}
public boolean hasImageGeo() {
return hasImageGeo;
}
public boolean hasBackground() {
return hasBackground;
}
@Override
protected boolean isValidAt(int index) {
// TODO Auto-generated method stub
return false;
}
public static String getColorAsString(App app, GColor color) {
String result = "";
int blue = color.getBlue();
String rgbDec = color.getRed() + ", " + color.getGreen() + ", " + blue;
String name = GeoGebraColorConstants.getGeogebraColorName(app, color);
if (name != null) {
result = name + " " + rgbDec;
} else {
result = rgbDec;
}
result += " (" + StringUtil.toHtmlColor(color) + ")";
return result;
}
/*
* public static String getColorAsString(App app, GColor color) {
* ColorObjectModel.app = app; return getColorAsString(color); }
*/
public void setSequential(boolean b) {
GeoElement geo;
for (int i = 0; i < getGeosLength(); i++) {
geo = getGeoAt(i);
geo.setAutoColor(b);
geo.updateVisualStyle(GProperty.COLOR);
}
kernel.notifyRepaint();
}
public boolean isSequentialColor() {
for (int i = 0; i < getGeosLength(); i++) {
if (!getGeoAt(i).isAutoColor()) {
return false;
}
}
return getGeosLength() > 0;
}
public boolean hasDefaultGeos() {
for (int i = 0; i < getGeosLength(); i++) {
if (getGeoAt(i).isDefaultGeo()) {
return true;
}
}
return false;
}
@Override
public PropertyListener getListener() {
return listener;
}
protected AlgoElement getAlgorithm() {
return getGeoAt(0).getParentAlgorithm();
}
public AlgoBarChart getAlgoBarChart() {
AlgoElement algo = getAlgorithm();
return (algo instanceof AlgoBarChart ? (AlgoBarChart) algo : null);
}
public boolean isBarChart() {
return (getAlgorithm() instanceof AlgoBarChart);
}
public int getBarChartIntervals() {
return getAlgoBarChart().getIntervals();
}
public void applyBar(int idx, GColor color, double alpha) {
AlgoBarChart algo = getAlgoBarChart();
boolean updateAlphaOnly = color == null;
if (idx == ALL_BARS) {
GeoElement geo = getGeoAt(0);
for (int numBar = 1; numBar < getBarChartIntervals()
+ 1; numBar++) {
algo.setBarColor(null, numBar);
algo.setBarAlpha(-1, numBar);
}
geo.setAlphaValue(alpha);
if (!updateAlphaOnly) {
geo.setObjColor(color);
}
algo.setBarAlpha(alpha, idx);
kernel.notifyRepaint();
return;
}
if (!updateAlphaOnly) {
algo.setBarColor(color, idx);
}
algo.setBarAlpha(alpha, idx);
kernel.notifyRepaint();
}
}