So this is definitely not complete, but I think this is a big part of what you need.
Limitations / Assumptions
- So far, I have implemented only touch processing, since I find it harder. If I get time later, I will come back and add a trackball .
- I did not give any momentum to the spinning discs. After the user finger leaves the disk, it will stop rotating.
- I'm not sure if the transitions between the drives are 100% right. You will need to do some testing. At least they are right.
- When you mentioned Canvas in the title, I assumed that this does not mean that you need to use J2ME Canvas . Writing BlackBerry applications with RIM interface libraries is pretty much everything I've done.
Decision
Essentially, I created a subclass of Field to represent each drive. You create a field by passing an array of labels to fit around the perimeter, radius, and color. The hardcoded in each DiscField is an insert for text for text, which implies a certain size difference between the disks. You should probably make this more dynamic.
public class DiscField extends Field { private int _offset = 0; private int _radius; private int _fillColor; private double _currentRotation = 0.0; private double _lastTouchAngle = 0.0; private boolean _rotating = false; private String[] _labels; private static final int INSET = 30; private DiscField() { } public DiscField(String[] labels, int radius, int fillColor) { super(Field.FOCUSABLE); _labels = labels; _radius = radius; _fillColor = fillColor; } protected void layout(int width, int height) { setExtent(Math.min(width, getPreferredWidth()), Math.min(height, getPreferredHeight())); } private void drawFilledCircle(Graphics g, int x, int y, int r) {
Contains all DiscField objects - this is DiscManager . It aligns the DiscFields in sublayout() and handles the proper delegation of touch events ... since the fields overlap and touch within the DiscField , which is also not included in its radius (i.e. angles), must be processed by a large disk.
private class DiscManager extends Manager { private int _maxRadius = 0; public DiscManager(long style){ super(style); DiscField outerDisc = new DiscField(new String[] { "1", "2", "3", "4", "5", "6" }, 180, Color.BLUE); _maxRadius = outerDisc.getRadius(); DiscField middleDisc = new DiscField(new String[] { "1", "2", "3", "4", "5" }, 120, Color.GRAY); middleDisc.setOffset(_maxRadius - middleDisc.getRadius()); DiscField innerDisc = new DiscField(new String[] { "1", "2", "3", "4" }, 60, Color.RED); innerDisc.setOffset(_maxRadius - innerDisc.getRadius());
Finally, a screen for using them:
public class DiscScreen extends MainScreen { public DiscScreen() { super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR); add(new DiscManager(Field.USE_ALL_WIDTH)); } }
results
