/*- * Copyright © 2011 Diamond Light Source Ltd. * * This file is part of GDA. * * GDA is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License version 3 as published by the Free * Software Foundation. * * GDA is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with GDA. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.gda.ui.components; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.Button; import org.eclipse.draw2d.ButtonModel; import org.eclipse.draw2d.ChangeEvent; import org.eclipse.draw2d.ChangeListener; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.LineBorder; import org.eclipse.draw2d.RectangleFigure; import org.eclipse.draw2d.XYLayout; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.FontRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Composite that lists 128, 64, 32, 16, 8, 4, 2, 1 as buttons so that selecting those, the amplification of the * exposure, and the histogram settings can be controlled. */ public class AmplifierStepperComposite extends Composite { private static final Logger logger = LoggerFactory.getLogger(AmplifierStepperComposite.class); private STEPPER selectedStepper = STEPPER.ONE; private void showError(final String dialogTitle, final Exception ex) { if (!this.isDisposed()) { getDisplay().syncExec(new Runnable() { @Override public void run() { MessageDialog.openError(getShell(), dialogTitle, ex.getMessage()); } }); } } /** * Listeners to the amplifier Stepper composite */ public interface AmplifierStepperListener { /** * @param stepper * @throws Exception */ public void performAction(STEPPER stepper) throws Exception; } private List<AmplifierStepperListener> amplifierStepperListeners = new ArrayList<AmplifierStepperComposite.AmplifierStepperListener>(); /** * @param amplifierStepperListener * @return <code>true</code> if the listener is added to the list successfully */ public boolean addAmplifierStepperListener(AmplifierStepperListener amplifierStepperListener) { return amplifierStepperListeners.add(amplifierStepperListener); } /** * @param amplifierStepperListener * @return <code>true</code> if the listener is removed from the list successfully. */ public boolean removeAmplifierStepperListener(AmplifierStepperListener amplifierStepperListener) { return amplifierStepperListeners.remove(amplifierStepperListener); } public void moveStepperTo(STEPPER stepper) { // Expect all the buttons to be present. for (Button btn : buttons) { if (!stepper.equals(btn.getModel().getUserData())) { deselectButton(btn); } else { selectButton(btn); } } } /** * STEPPER enum */ public enum STEPPER { ONE_TWENTY_EIGHT(128) { @Override public String toString() { return "128"; } }, SIXTY_FOUR(64) { @Override public String toString() { return "64"; } }, THIRTY_TWO(32) { @Override public String toString() { return "32"; } }, SIXTEEN(16) { @Override public String toString() { return "16"; } }, EIGHT(8) { @Override public String toString() { return "8"; } }, FOUR(4) { @Override public String toString() { return "4"; } }, TWO(2) { @Override public String toString() { return "2"; } }, ONE(1) { @Override public String toString() { return "1"; } }; private final int val; /** * @param text * @return the {@link STEPPER} for the given text */ public static STEPPER getStepperEnum(String text) { for (STEPPER stepper : values()) { if (stepper.toString().equals(text)) { return stepper; } } return null; } STEPPER(int val) { this.val = val; } public int getValue() { return val; } } private FigureCanvas figCanvas; private FontRegistry fontRegistry; private static final String BOLD_TEXT_7 = "bold-text_7"; private Button btn1; private Button btn2; private Button btn3; private Button btn4; private Button btn5; private Button btn6; private Button btn7; private Button btn8; private Button[] buttons = new Button[8]; /** * @param parent * @param style */ public AmplifierStepperComposite(Composite parent, int style) { super(parent, style); if (Display.getCurrent() != null) { fontRegistry = new FontRegistry(Display.getCurrent()); String fontName = Display.getCurrent().getSystemFont().getFontData()[0].getName(); fontRegistry.put(BOLD_TEXT_7, new FontData[] { new FontData(fontName, 8, SWT.BOLD) }); } GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 0; layout.horizontalSpacing = 0; setLayout(layout); figCanvas = new FigureCanvas(this); figCanvas.setContents(getContents()); figCanvas.getViewport().setContentsTracksHeight(true); figCanvas.getViewport().setContentsTracksWidth(true); figCanvas.setLayoutData(new GridData(GridData.FILL_BOTH)); } private ChangeListener changeListener = new ChangeListener() { @Override public void handleStateChanged(ChangeEvent event) { if (ButtonModel.PRESSED_PROPERTY.equals(event.getPropertyName())) { Button btn = (Button) event.getSource(); if (btn.getModel().isPressed()) { if (!ColorConstants.darkGreen.equals(btn.getBackgroundColor())) { selectButton(btn); STEPPER stepper = (STEPPER) btn.getModel().getUserData(); if (stepper != null) { try { for (AmplifierStepperListener aSl : amplifierStepperListeners) { aSl.performAction(stepper); } } catch (Exception e) { showError("Problem setting amplifier state", e); } for (Button b : buttons) { if (!b.equals(btn)) { deselectButton(b); } } } } } } else if (ButtonModel.MOUSEOVER_PROPERTY.equals(event.getPropertyName())) { Button button = (Button) event.getSource(); button.setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND)); } } }; protected void deselectButton(final Button btn) { if (!isDisposed()) { getDisplay().syncExec(new Runnable() { @Override public void run() { btn.setBackgroundColor(ColorConstants.lightGray); btn.setForegroundColor(ColorConstants.black); } }); } } protected void selectButton(final Button btn) { if (!isDisposed()) { getDisplay().syncExec(new Runnable() { @Override public void run() { btn.setBackgroundColor(ColorConstants.darkGreen); btn.setForegroundColor(ColorConstants.white); } }); } if (btn.equals(btn1)) { selectedStepper = STEPPER.ONE_TWENTY_EIGHT; } else if (btn.equals(btn2)) { selectedStepper = STEPPER.SIXTY_FOUR; } else if (btn.equals(btn3)) { selectedStepper = STEPPER.THIRTY_TWO; } else if (btn.equals(btn4)) { selectedStepper = STEPPER.SIXTEEN; } else if (btn.equals(btn5)) { selectedStepper = STEPPER.EIGHT; } else if (btn.equals(btn6)) { selectedStepper = STEPPER.FOUR; } else if (btn.equals(btn7)) { selectedStepper = STEPPER.TWO; } else if (btn.equals(btn8)) { selectedStepper = STEPPER.ONE; } } public STEPPER getSelectedStepper() { return selectedStepper; } private IFigure getContents() { RectangleFigure boundaryFigure = new RectangleFigure(); boundaryFigure.setBackgroundColor(ColorConstants.white); boundaryFigure.setLayoutManager(new ZoomSliderCompositeLayout()); int count = 0; btn1 = new Button(STEPPER.ONE_TWENTY_EIGHT.toString()); btn1.setBorder(new LineBorder(1)); getButtonLabel(btn1).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn1); btn1.getModel().setUserData(STEPPER.ONE_TWENTY_EIGHT); btn1.addChangeListener(changeListener); buttons[count++] = btn1; // btn2 = new Button(STEPPER.SIXTY_FOUR.toString()); btn2.setBorder(new LineBorder(1)); getButtonLabel(btn2).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn2); btn2.getModel().setUserData(STEPPER.SIXTY_FOUR); btn2.addChangeListener(changeListener); buttons[count++] = btn2; // btn3 = new Button(STEPPER.THIRTY_TWO.toString()); btn3.setBorder(new LineBorder(1)); getButtonLabel(btn3).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn3); btn3.getModel().setUserData(STEPPER.THIRTY_TWO); btn3.addChangeListener(changeListener); buttons[count++] = btn3; // btn4 = new Button(STEPPER.SIXTEEN.toString()); btn4.setBorder(new LineBorder(1)); getButtonLabel(btn4).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn4); btn4.getModel().setUserData(STEPPER.SIXTEEN); btn4.addChangeListener(changeListener); buttons[count++] = btn4; // btn5 = new Button(STEPPER.EIGHT.toString()); btn5.setBorder(new LineBorder(1)); getButtonLabel(btn5).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn5); btn5.getModel().setUserData(STEPPER.EIGHT); btn5.addChangeListener(changeListener); buttons[count++] = btn5; // btn6 = new Button(STEPPER.FOUR.toString()); btn6.setBorder(new LineBorder(1)); getButtonLabel(btn6).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn6); btn6.getModel().setUserData(STEPPER.FOUR); btn6.addChangeListener(changeListener); buttons[count++] = btn6; // btn7 = new Button(STEPPER.TWO.toString()); btn7.setBorder(new LineBorder(1)); getButtonLabel(btn7).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn7); btn7.getModel().setUserData(STEPPER.TWO); btn7.addChangeListener(changeListener); buttons[count++] = btn7; // btn8 = new Button(STEPPER.ONE.toString()); btn8.setBorder(new LineBorder(1)); btn8.getModel().setUserData(STEPPER.ONE); getButtonLabel(btn8).setFont(fontRegistry.get(BOLD_TEXT_7)); boundaryFigure.add(btn8); btn8.addChangeListener(changeListener); buttons[count++] = btn8; // return boundaryFigure; } private class ZoomSliderCompositeLayout extends XYLayout { @Override public void layout(IFigure parent) { super.layout(parent); Rectangle parentBounds = parent.getBounds(); parent.setSize(35, parentBounds.height); Dimension textExtents = getButtonLabel(btn1).getTextUtilities().getTextExtents( getButtonLabel(btn1).getText(), getFont()); Dimension buttonSize = new Dimension(textExtents.width + 5, textExtents.height + 5); getButtonLabel(btn1).setSize(textExtents); btn1.setSize(buttonSize); btn1.setLocation(new Point(3, 5)); textExtents = getButtonLabel(btn2).getTextUtilities().getTextExtents(getButtonLabel(btn2).getText(), getFont()); getButtonLabel(btn2).setSize(textExtents); btn2.setSize(buttonSize); btn2.setLocation(new Point(3, parentBounds.height / 8)); textExtents = getButtonLabel(btn3).getTextUtilities().getTextExtents(getButtonLabel(btn3).getText(), getFont()); getButtonLabel(btn3).setSize(textExtents); btn3.setSize(buttonSize); btn3.setLocation(new Point(3, parentBounds.height / 4)); textExtents = getButtonLabel(btn4).getTextUtilities().getTextExtents(getButtonLabel(btn4).getText(), getFont()); getButtonLabel(btn4).setSize(textExtents); btn4.setSize(buttonSize); btn4.setLocation(new Point(3, 3 * parentBounds.height / 8)); textExtents = getButtonLabel(btn5).getTextUtilities().getTextExtents(getButtonLabel(btn5).getText(), getFont()); getButtonLabel(btn5).setSize(textExtents); btn5.setSize(buttonSize); btn5.setLocation(new Point(3, parentBounds.height / 2)); textExtents = getButtonLabel(btn6).getTextUtilities().getTextExtents(getButtonLabel(btn6).getText(), getFont()); getButtonLabel(btn6).setSize(textExtents); btn6.setSize(buttonSize); btn6.setLocation(new Point(3, 5 * parentBounds.height / 8)); textExtents = getButtonLabel(btn7).getTextUtilities().getTextExtents(getButtonLabel(btn7).getText(), getFont()); getButtonLabel(btn7).setSize(textExtents); btn7.setSize(buttonSize); btn7.setLocation(new Point(3, 3 * parentBounds.height / 4)); textExtents = getButtonLabel(btn8).getTextUtilities().getTextExtents(getButtonLabel(btn8).getText(), getFont()); getButtonLabel(btn8).setSize(textExtents); btn8.setSize(buttonSize); btn8.setLocation(new Point(3, 7 * parentBounds.height / 8)); } } @SuppressWarnings("rawtypes") private Label getButtonLabel(Button btn) { List children = btn.getChildren(); for (Object child : children) { if (child instanceof Label) { return (Label) child; } } return null; } public static void main(String[] args) { final Display display = new Display(); final Shell shell = new Shell(display, SWT.SHELL_TRIM); shell.setBounds(new org.eclipse.swt.graphics.Rectangle(0, 0, 100, 400)); shell.setLayout(new GridLayout()); shell.setBackground(ColorConstants.black); AmplifierStepperComposite sliderComposite = new AmplifierStepperComposite(shell, SWT.None); shell.setText(sliderComposite.getClass().getName()); GridData layoutData = new GridData(GridData.FILL_BOTH); layoutData.heightHint = 400; layoutData.widthHint = 100; sliderComposite.setLayoutData(layoutData); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } @Override public void dispose() { logger.info("Disposing"); try { for (Button btn : buttons) { btn.removeChangeListener(changeListener); } buttons = null; amplifierStepperListeners.clear(); amplifierStepperListeners = null; fontRegistry = null; figCanvas.dispose(); } catch (Exception ex) { logger.error("Problem disposing", ex); } super.dispose(); } }