package totalcross.ui; import totalcross.sys.*; import totalcross.ui.dialog.*; import totalcross.ui.event.*; import totalcross.ui.gfx.*; import totalcross.ui.image.*; /** MultiButton is a control that displays a single line button with a set of titles. * Can be used to replace a Check (with on/off) or a Radio (with their options). * Sample: * <pre> * MultiButton b = new MultiButton(new String[]{"+","-"}); b.setBackColor(Color.CYAN); add(b,LEFT+50,TOP+50,200,fmH*3/2); * </pre> * @since TotalCross 2.0 */ public class MultiButton extends Control { private Image npback,npsel; private String[] tits; private int sel=-1; private boolean []disabled; /** The color used to divide the texts. */ public int divColor=-1; /** The selection color. */ public int selColor=-1; /** Defines if the text will have a 3d style. */ public boolean is3dText; /** Set to true to behave like a Radio, false like a Button */ public boolean isSticky; /** Constructs a MultiButton with the given captions. */ public MultiButton(String[] captions) { this.tits = captions; } public void onColorsChanged(boolean colorsChanged) { npback = null; } /** Sets the selected index, or -1 to unset it. Only an enabled index can be selected. */ public void setSelectedIndex(int sel) { if (sel == -1 || (0 <= sel && sel < tits.length && (disabled == null || !disabled[sel]))) { this.sel = sel; repaintNow(); postPressedEvent(); if (!isSticky) { if (Settings.onJavaSE) Vm.sleep(20); this.sel = -1; repaint(); } } } /** Enables or disables a caption */ public void setEnabled(int idx, boolean enabled) { if (disabled == null) disabled = new boolean[tits.length]; disabled[idx] = !isEnabled(); repaint(); } /** Returns if a caption is enabled or not */ public boolean isEnabled(int idx) { return disabled == null || !disabled[idx]; } /** Returns the selected index */ public int getSelectedIndex() { return sel; } public void onPaint(Graphics g) { try { int bc = getBackColor(); int tcolor = Color.darker(bc,32); if (npback == null) { int c = isEnabled() ? bc : Color.getCursorColor(tcolor); if (divColor == -1) divColor = Color.darker(c,92); if (selColor == -1) selColor = Color.darker(backColor,64); npback = NinePatch.getInstance().getNormalInstance(NinePatch.COMBOBOX, width, height, c, false); npsel = NinePatch.getInstance().getPressedInstance(npback, backColor, selColor); } // without this, clicking will make the button fade out g.backColor = parent.getBackColor(); g.fillRect(0,0,width,height); NinePatch.tryDrawImage(g,npback,0,0); int w = width / tits.length; if (sel != -1) g.copyRect(npsel,sel*w+2,0,w-2,height,sel*w+2,1); for (int i = 0, x0 = 0, n = tits.length-1; i <= n; i++, x0 += w) { String s = tits[i]; int tw = fm.stringWidth(s); int tx = (w - tw) / 2 + x0; int ty = (height - fmH) / 2 -1 ; boolean textEnabled = isEnabled() && (disabled == null || !disabled[i]); if (is3dText && textEnabled) { g.foreColor = tcolor; g.drawText(s, tx+1,ty-1); g.foreColor = i == sel ? tcolor : bc; g.drawText(s, tx-1,ty+1); } g.foreColor = textEnabled ? getForeColor() : Color.brighter(foreColor); g.drawText(s, tx,ty); g.drawText(tits[i], tx, ty); if (i < n) { g.foreColor = isEnabled() ? divColor : Color.brighter(divColor); int y1 = (height - fmH)/2, y2 = y1 + fmH, xx = x0+w; g.drawLine(xx,y1,xx,y2); xx++; g.foreColor = tcolor; g.drawLine(xx,y1,xx,y2); } } } catch (Exception ee) { MessageBox.showException(ee,true); } } public void onEvent(Event e) { switch (e.type) { case PenEvent.PEN_UP: if (isEnabled() && !hadParentScrolled()) { PenEvent pe = (PenEvent)e; int sel = isInsideOrNear(pe.x,pe.y) ? pe.x / (width / tits.length) : -1; if (sel != this.sel && (sel == -1 || disabled == null || (sel < disabled.length && !disabled[sel]))) setSelectedIndex(sel); } break; case KeyEvent.SPECIAL_KEY_PRESS: if (isEnabled()) { KeyEvent ke = (KeyEvent)e; if (ke.isPrevKey()) { for (int i = tits.length; --i >= 0;) { if (--sel < 0) sel = tits.length-1; if (disabled == null || !disabled[sel]) break; } if (!Settings.keyboardFocusTraversable) postPressedEvent(); repaint(); } else if (ke.isNextKey()) { for (int i = tits.length; --i >= 0;) { if (++sel >= tits.length) sel = 0; if (disabled == null || !disabled[sel]) break; } if (!Settings.keyboardFocusTraversable) postPressedEvent(); repaint(); } else if (ke.isActionKey()) { int sel = this.sel; sel = -1; setSelectedIndex(sel); } } break; } } public int getPreferredHeight() { return fmH + Edit.prefH; } public int getPreferredWidth() { int w = 0; for (int i = tits.length; --i >= 0;) w += fm.stringWidth(tits[i]); return w + fmH*2; } }