/*******************************************************************************
* 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;
};
}