package org.csstudio.sds.components.ui.internal.figures; import org.csstudio.sds.ui.figures.BorderAdapter; import org.csstudio.sds.ui.figures.CrossedOutAdapter; import org.csstudio.sds.ui.figures.IBorderEquippedWidget; 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.Graphics; import org.eclipse.draw2d.GridData; import org.eclipse.draw2d.GridLayout; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.LineBorder; import org.eclipse.draw2d.RectangleFigure; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; /** * Sixteen Bit Binary Bar widget figure. * * @author Alen Vrecko, Joerg Rathlev */ public class RefreshableSixteenBinaryBarFigure extends RectangleFigure implements IAdaptable { /** * The orientation (horizontal==true | vertical==false). */ private boolean _orientationHorizontal = true; /** * A border adapter, which covers all border handlings. */ private IBorderEquippedWidget _borderAdapter; private int _value; private int _internalFrameThickness; private Color _internalFrameColor; private OnOffBox[] _boxes; private GridLayout _layout; private int _bitRangeFrom = 0; private int _bitRangeTo = 15; private boolean _showLabels; private Font _labelFont; private Color _labelColor; private ICrossedFigure _crossedOutAdapter; private IRhombusEquippedWidget _rhombusAdapter; private Color _onColor; private Color _offColor; /** * * Constructor. */ public RefreshableSixteenBinaryBarFigure() { createLayoutAndBoxes(); } @Override public void paint(final Graphics graphics) { super.paint(graphics); _crossedOutAdapter.paint(graphics); _rhombusAdapter.paint(graphics); } /** * Creates the layout and the boxes for this figure. */ private void createLayoutAndBoxes() { int column = 1; if (_orientationHorizontal) { column = numberOfBits(); } _layout = new GridLayout(column, false); _layout.horizontalSpacing = 0; _layout.verticalSpacing = 0; _layout.marginHeight = 0; _layout.marginWidth = 0; setLayoutManager(_layout); _boxes = new OnOffBox[numberOfBits()]; for (int i = 0; i < numberOfBits(); i++) { OnOffBox box = new OnOffBox(_bitRangeFrom + i); box.setShowLabel(_showLabels); box.setFont(_labelFont); box.setForegroundColor(_labelColor); box.setOnColor(_onColor); box.setOffColor(_offColor); applyInternalBorderSettings(box); add(box); GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; gridData.grabExcessVerticalSpace = true; gridData.grabExcessHorizontalSpace = true; setConstraint(box, gridData); _boxes[i] = box; } } /** * Removes the boxes from this figure, then recreates them and refreshes the * layout. */ private void recreateLayoutAndBoxes() { removeBoxes(); createLayoutAndBoxes(); updateBoxes(); } /** * Removes the boxes from this figure. */ private void removeBoxes() { removeAll(); } /** * Updates the on/off state of the boxes based on the current value. */ private void updateBoxes() { int multi = 1; if (_bitRangeFrom > _bitRangeTo) { multi = -1; } for (int i = 0; i < numberOfBits(); i++) { _boxes[i] .setOn(((1 << (_bitRangeFrom + (multi * i))) & _value) != 0); } } /** * Sets the orientation (horizontal==true | vertical==false). * * @param horizontal * The orientation. */ public void setHorizontal(final boolean horizontal) { _orientationHorizontal = horizontal; if (_orientationHorizontal) { _layout.numColumns = numberOfBits(); } else { _layout.numColumns = 1; } revalidate(); } /** * * {@inheritDoc} */ @Override @SuppressWarnings("rawtypes") public final Object getAdapter(final Class adapter) { if (adapter == IBorderEquippedWidget.class) { if (_borderAdapter == null) { _borderAdapter = new BorderAdapter(this); } return _borderAdapter; } else 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; } /** * * @param showLabels * . */ public void setShowLabels(final Boolean showLabels) { _showLabels = showLabels; for (OnOffBox box : _boxes) { box.setShowLabel(showLabels); } } /** * * @param newValue * the new Binary value */ public void setValue(final Integer newValue) { _value = newValue; updateBoxes(); } /** * * @param font * . */ public void setLabelFont(final Font font) { _labelFont = font; for (OnOffBox box : _boxes) { box.setFont(font); } } /** * * @param onColor * . */ public void setOnColor(final Color onColor) { this._onColor = onColor; if (onColor != null) { for (OnOffBox box : _boxes) { box.setOnColor(onColor); } } } /** * * @param offColor * . */ public void setOffColor(final Color offColor) { this._offColor = offColor; if (offColor != null) { for (OnOffBox box : _boxes) { box.setOffColor(offColor); } } } /** * * @param internalFrameThickness * . */ public void setInternalBorderThickness(final int internalFrameThickness) { _internalFrameThickness = internalFrameThickness; for (OnOffBox box : _boxes) { applyInternalBorderSettings(box); } } /** * * @param internalFrameColor * . */ public void setInternalBorderColor(final Color internalFrameColor) { _internalFrameColor = internalFrameColor; for (OnOffBox box : _boxes) { applyInternalBorderSettings(box); } } /** * Applies the current settings for the internal frame thickness and color * to the given box. * * @param box * the box. */ private void applyInternalBorderSettings(final OnOffBox box) { if (_internalFrameColor != null) { box.setInternalFrame(_internalFrameThickness, _internalFrameColor); } else { box.setInternalFrame(_internalFrameThickness, null); } } /** * @param labelColor * . */ public final void setLabelColor(final Color labelColor) { if (labelColor == null) { return; } _labelColor = labelColor; for (OnOffBox box : _boxes) { box.setForegroundColor(_labelColor); } } /** * Sets the range of bits that are displayed by this figure. * * @param from * the index of the lowest bit to display. * @see #setBitRangeTo(int) */ public void setBitRangeFrom(final int from) { this._bitRangeFrom = from; recreateLayoutAndBoxes(); } /** * Sets the range of bits that are displayed by this figure. * * @param to * the index of the highest bit to display. * @see #setBitRangeFrom(int) */ public void setBitRangeTo(final int to) { this._bitRangeTo = to; recreateLayoutAndBoxes(); } /** * Returns the number of bits displayed in this figure. * * @return the number of bits displayed in this figure. */ private int numberOfBits() { if (_bitRangeTo > _bitRangeFrom) { return _bitRangeTo - _bitRangeFrom + 1; } return _bitRangeFrom - _bitRangeTo + 1; } private class OnOffBox extends Label { private final int _bitIndex; private Color _onColor; private Color _offColor; private boolean _isOn; public OnOffBox(int bitIndex) { this._bitIndex = bitIndex; _onColor = CustomMediaFactory.getInstance().getColor(0, 150, 150); _offColor = CustomMediaFactory.getInstance().getColor(200, 200, 200); this.setOpaque(true); } public void setOnColor(final Color onColor) { if (onColor != null && !onColor.equals(_onColor)) { _onColor = onColor; setOn(_isOn); } } public void setOffColor(final Color offColor) { if (offColor != null && !offColor.equals(_offColor)) { _offColor = offColor; setOn(_isOn); } } public void setInternalFrame(int thickness, Color color) { if (color != null) { if (thickness > 0) { setBorder(new LineBorder(color, thickness)); } else { setBorder(null); } } } public void setOn(boolean isOn) { this._isOn = isOn; setBackgroundColor(_isOn ? _onColor : _offColor); } public void setShowLabel(boolean show) { if (show) { setText(String.format("%02d", _bitIndex)); } else { setText(""); } } } }