package org.csstudio.sds.components.ui.internal.figures;
import java.util.Arrays;
import org.csstudio.sds.ui.figures.CrossedOutAdapter;
import org.csstudio.sds.ui.figures.ICrossedFigure;
import org.csstudio.sds.ui.figures.IRhombusEquippedWidget;
import org.csstudio.sds.ui.figures.RhombusAdapter;
import org.csstudio.ui.util.CustomMediaFactory;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.Label;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base figure for a widget based on {@link AbstractBoolWidgetModel}.
*
* @author Xihui Chen
*
*/
public class AbstractBoolFigure extends Figure implements IAdaptable {
private static final Logger LOG = LoggerFactory.getLogger(AbstractBoolFigure.class);
protected Label boolLabel;
protected long value = 0;
protected int bit = -1;
protected boolean showBooleanLabel = false;
protected boolean boolValue = false;
protected String onLabel = "ON";
protected String offLabel = "OFF";
protected Color onColor = CustomMediaFactory.getInstance()
.getColor(CustomMediaFactory.COLOR_GREEN);
protected Color offColor = CustomMediaFactory.getInstance().getColor(new RGB(0, 128, 0));
private CrossedOutAdapter _crossedOutAdapter;
private RhombusAdapter _rhombusAdapter;
protected AbstractBoolFigure() {
boolLabel = new Label(offLabel);
}
@Override
public void paint(final Graphics graphics) {
super.paint(graphics);
_crossedOutAdapter.paint(graphics);
_rhombusAdapter.paint(graphics);
}
@Override
public boolean isOpaque() {
return false;
}
/**
* @return the boolValue
*/
public boolean getBoolValue() {
return boolValue;
}
/**
* @param value
* the value to set
*/
public void setValue(final double value) {
this.value = (long) value;
updateBoolValue();
revalidate();
repaint();
}
public void setBooleanValue(final Boolean value) {
this.boolValue = value;
updateValue();
}
/**
* @param bit
* the bit to set
*/
public void setBit(final int bit) {
this.bit = bit;
updateBoolValue();
}
/**
* update the boolValue from value and bit. All the boolValue based behavior changes should be
* implemented here by inheritance.
*/
protected void updateBoolValue() {
// get boolValue
if (bit == -1) {
boolValue = (this.value != 0);
} else if (bit >= 0) {
char[] binArray = Long.toBinaryString(this.value).toCharArray();
if (bit >= binArray.length) {
boolValue = false;
} else {
boolValue = (binArray[binArray.length - 1 - bit] == '1');
}
}
// change boolLabel text
if (boolValue) {
boolLabel.setText(onLabel);
} else {
boolLabel.setText(offLabel);
}
}
/**
* update the value from boolValue
*/
protected void updateValue() {
// get boolValue
if (bit == -1) {
setValue(boolValue ? 1 : 0);
} else if (bit >= 0) {
char[] binArray = Long.toBinaryString(value).toCharArray();
if ((bit >= 64) || (bit < -1)) {
try {
throw new Exception("bit is out of range: [-1,63]");
} catch (Exception e) {
LOG.error(e.toString());
}
} else {
char[] bin64Array = new char[64];
Arrays.fill(bin64Array, '0');
for (int i = 0; i < binArray.length; i++) {
bin64Array[64 - binArray.length + i] = binArray[i];
}
bin64Array[63 - bit] = boolValue ? '1' : '0';
String binString = new String(bin64Array);
if (binString.indexOf('1') <= -1) {
binArray = new char[] { '0' };
} else {
binArray = new char[64 - binString.indexOf('1')];
for (int i = 0; i < binArray.length; i++) {
binArray[i] = bin64Array[i + 64 - binArray.length];
}
}
binString = new String(binArray);
setValue(Long.parseLong(binString, 2));
}
}
}
/**
* @param showBooleanLabel
* the showBooleanLabel to set
*/
public void setShowBooleanLabel(final boolean showBooleanLabel) {
this.showBooleanLabel = showBooleanLabel;
boolLabel.setVisible(showBooleanLabel);
}
/**
* @param onLabel
* the onLabel to set
*/
public void setOnLabel(final String onLabel) {
this.onLabel = onLabel;
if (boolValue) {
boolLabel.setText(onLabel);
}
}
/**
* @param offLabel
* the offLabel to set
*/
public void setOffLabel(final String offLabel) {
this.offLabel = offLabel;
if (!boolValue) {
boolLabel.setText(offLabel);
}
}
public void setOnColor(final Color color) {
this.onColor = color;
}
public void setOffColor(final Color color) {
this.offColor = color;
}
@Override
public void setFont(final Font f) {
super.setFont(f);
boolLabel.setFont(f);
}
@Override
public Object getAdapter(final Class adapter) {
if (adapter == ICrossedFigure.class) {
if(_crossedOutAdapter==null) {
_crossedOutAdapter = new CrossedOutAdapter(this);
}
return _crossedOutAdapter;
} else if (adapter == IRhombusEquippedWidget.class) {
if(_rhombusAdapter==null) {
_rhombusAdapter = new RhombusAdapter(this);
}
return _rhombusAdapter;
}
return null;
}
}