/******************************************************************************* * Copyright (c) 2016 ARM Ltd. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * ARM Ltd and ARM Germany GmbH - Initial API and implementation *******************************************************************************/ package com.arm.cmsis.pack.ui.tree; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TypedListener; /** * A spinner that can represent hex, binary, octal numbers in the box. */ public class NumberSpinner extends Composite { static final int BUTTON_WIDTH = 16; Text text; Button up, down; long minimum, maximum; int base; Composite parent; long spinStep = 1; public NumberSpinner(Composite parent, int style) { super(parent, style); this.parent = parent; text = new Text(this, style | SWT.SINGLE | SWT.BORDER); up = new Button(this, style | SWT.ARROW | SWT.UP); down = new Button(this, style | SWT.ARROW | SWT.DOWN); text.addListener(SWT.Verify, new Listener() { @Override public void handleEvent(Event e) { verify(e); } }); text.addListener(SWT.Traverse, new Listener() { @Override public void handleEvent(Event e) { mytraverse(e); } }); up.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { up(); } }); down.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event e) { down(); } }); addListener(SWT.Resize, new Listener() { @Override public void handleEvent(Event e) { resize(); } }); addListener(SWT.FocusIn, new Listener() { @Override public void handleEvent(Event e) { focusIn(); } }); text.setFont(getFont()); setSelection(0); } void verify(Event e) { } void mytraverse(Event e) { switch (e.detail) { case SWT.TRAVERSE_ARROW_PREVIOUS: if (e.keyCode == SWT.ARROW_UP) { e.doit = true; e.detail = SWT.NULL; up(); } break; case SWT.TRAVERSE_ARROW_NEXT: if (e.keyCode == SWT.ARROW_DOWN) { e.doit = true; e.detail = SWT.NULL; down(); } break; } } void up() { setSelection(getSelection() + spinStep); notifyListeners(SWT.Selection, new Event()); } void down() { setSelection(getSelection() - spinStep); notifyListeners(SWT.Selection, new Event()); } void focusIn() { text.setFocus(); } @Override public void setFont(Font font) { super.setFont(font); text.setFont(font); } public void setBase(int base) { this.base = base; } public void setSelection(long selection) { if (selection < minimum) { selection = minimum; } else if (selection > maximum) { selection = maximum; } switch (base) { case 10: text.setText(Long.toString(selection)); break; case 16: text.setText("0x" + Long.toHexString(selection).toUpperCase()); //$NON-NLS-1$ break; case 8: text.setText("0" + Long.toOctalString(selection)); //$NON-NLS-1$ break; case 2: text.setText("0b" + Long.toBinaryString(selection)); //$NON-NLS-1$ default: break; } text.selectAll(); text.setFocus(); } public long getSelection() { try { String num = getContent(); switch (base) { case 16: case 2: num = num.substring(2); break; case 8: num = num.substring(1); break; default: break; } return Long.parseLong(num, base); } catch (NumberFormatException e) { return minimum; } } public void setMaximum(long maximum) { checkWidget(); this.maximum = maximum; } public long getMaximum() { return maximum; } public void setMinimum(long minimum) { this.minimum = minimum; } public long getMinimum() { return minimum; } void resize() { Point pt = computeSize(SWT.DEFAULT, SWT.DEFAULT); int textWidth = pt.x - BUTTON_WIDTH; int buttonHeight = pt.y / 2; text.setBounds(0, 0, textWidth, pt.y); up.setBounds(textWidth, 0, BUTTON_WIDTH, buttonHeight); down.setBounds(textWidth, pt.y - buttonHeight - 2, BUTTON_WIDTH, buttonHeight); } @Override public Point computeSize(int wHint, int hHint, boolean changed) { Point pt = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); int width = pt.x; try { //FIXME: better way to calculate the width? width = ((Tree) parent).getColumn(1).getWidth(); } catch (Exception e) { } int height = pt.y; if (wHint != SWT.DEFAULT) { width = wHint; } if (hHint != SWT.DEFAULT) { height = hHint; } return new Point(width, height); } public void addSelectionListener(SelectionListener listener) { if (listener == null) { throw new SWTError(SWT.ERROR_NULL_ARGUMENT); } addListener(SWT.Selection, new TypedListener(listener)); } @Override public void dispose() { text.dispose(); up.dispose(); down.dispose(); } public Text getText() { return text; } /** * @return the text in the text control */ public String getContent() { return text.getText(); } /** * @param spinStep */ public void setIncrement(long spinStep) { this.spinStep = spinStep; }; }