/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine 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. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.ui; import totalcross.sys.*; import totalcross.ui.gfx.*; import totalcross.ui.image.*; /** A basic progress bar, with the bar and a text. * The text is comprised of a prefix and a suffix. * <p> * You can create a horizontal endless ProgressBar, always going from left to right, * by setting the given parameters: * <ul> * <li> call setEndless() * <li> max-min: used to compute the width of the bar * <li> prefix and suffix: displayed, but the current value is not displayed * <li> setValue(n): n used to increment the current value, not to set the value to n. * </ul> * Then set a timer to update the value. See the UIGadgets sample. */ public class ProgressBar extends Control { /** The minimum value of a progress bar. */ public int min; /** The maximum value of a progress bar. */ public int max; /** The current value of a progress bar. */ private int value; /** The string prefix. The displayed label will be prefix+value+sufix. The default is an empty string. */ public String prefix=""; /** The string prefix. The displayed label will be prefix+value+sufix. The default is the percentage symbol. */ public String suffix="%"; /** Set to false to don't let the text be drawn. * @since TotalCross 1.0 */ public boolean drawText = true; /** Set to false to don't let the value be drawn. Note that the prefix and suffix will still be drawn. * @since TotalCross 1.0 */ public boolean drawValue = true; /** The text color */ public int textColor = Color.RED; // guich@340_5 /** If false, no border is drawn. */ public boolean drawBorder = true; /** If true, the text is highlighted. */ public boolean highlight; /** The highlight color, or -1 to use one based on textColor. */ public int highlightColor = -1; /** If false, use horizontal mode (default) * @since TotalCross 1.15 */ public boolean vertical; // guich@tc115_67 /** Used for String concatenations */ private static StringBuffer sb = new StringBuffer(10); private boolean endless; private Image npback,npfore; /** * Creates a progress bar, with minimum and maximum set as 0 and 100, respectively. */ public ProgressBar() { this(0,100); } /** * Creates a progress bar, String is set to <code>null</code>, which is the default. * Uses the specified minimum for the initial value of the progress bar. * @param min The minimum value * @param max The maximum value */ public ProgressBar(int min, int max) { this.min = value = min; this.max = max; foreColor = 0x0000C8; focusTraversable = false; if (uiAndroid) transparentBackground = true; } /** Call this method to make this ProgressBar a horizontal endless progressbar; * just keep calling <code>setValue(step)</code> * to increase the value of the progressbar. */ public void setEndless() // guich@tc125_19 { if (vertical) throw new RuntimeException("Endless progressbar cannot be vertical, only horizontal)"); suffix = ""; endless = true; } /** Gets the preferred width, which is the parent's width-6, or the screen's width. */ public int getPreferredWidth() { if (vertical) return fm.stringWidth(max+prefix+suffix)+8; return parent==null ? Settings.screenWidth : (parent.getWidth()-6); } /** Returns the preferred height, which is fmH+2 */ public int getPreferredHeight() { if (vertical) return parent==null ? Settings.screenHeight : (parent.getHeight()-6); return fmH+2; } /** * Sets the current value. Due to performance reasons, * min and max are not verified. * If the value was not changed, nothing happens. * The progress bar is repainted immediately. * <p> * If this is an endless ProgressBar, the given number is used as * an increment to the current value. Note that n must be greater than 0. * * If you call this method and the bar isnt updated, you can try to call <code>MainWindow.pumpEvents()</code>. * * @param n The new value * @see #getValue */ public void setValue(int n) { if (endless || value != n) { value = endless ? value+n : n; repaintNow(); } } /** * Sets the current value and the prefix and suffix. Note that, due to performance reasons, * min and max are not verified. This does not check if the value had changed; it always * repaint the progress bar immediately. * * @param value The new value * @see #getValue */ public void setValue(int value, String prefix, String suffix) { this.value = endless ? this.value+value : value; this.prefix = prefix; this.suffix = suffix; repaintNow(); } /** Returns the current value */ public int getValue() { return value; } public void onColorsChanged(boolean b) { npback = npfore = null; } public void onBoundsChanged(boolean b) { npback = npfore = null; } /** Paint the Progress Bar. The filled part of the bar is painted with the foreground color; * the empty part of the bar is painted with the background color; the text is painted with * the defined textColor color; no border is drawn. */ public void onPaint(Graphics g) { // computes the current width of the bar int dif = max-min; int size = vertical ? height : width; int s = (dif == 0 || value==max) ? size : (value == 0) ? 0 : (int)((long)size * (long)(value - min) / (long)dif); if (s > size) s = size; // draw the filled part int bc = getBackColor(); int fc = getForeColor(); if (uiAndroid) try { if (npback == null) { int type = vertical ? width < fmH ? NinePatch.SCROLLPOSV : NinePatch.PROGRESSBARV : height < fmH ? NinePatch.SCROLLPOSH : NinePatch.PROGRESSBARH; npback = NinePatch.getInstance().getNormalInstance(type,width,height,bc,false); npfore = NinePatch.getInstance().getNormalInstance(type,width,height,fc,false); } if (endless) // only horizontal { int d = value-dif; g.copyRect(npback, 0,0,d,height,0,0); g.copyRect(npback, value,0,width-value,height,value,0); g.copyRect(npfore, d,0,dif,height,d,0); } else { if (vertical) { int r = height-s; g.copyRect(npback, 0,0,width,r,0,0); g.copyRect(npfore, 0,r,width,s,0,r); } else { int r = width-s; g.copyRect(npfore, 0,0,s,height,0,0); g.copyRect(npback, s,0,r,height,s,0); } } } catch (Exception e) {e.printStackTrace();} else { if (s > 0) { if (endless) { g.backColor = bc; g.fillRect(0,0,width,height); } if (uiVista && isEnabled()) // guich@573_6 { if (vertical) g.fillVistaRect(0, height - s, width, s, fc, false, false); else if (!endless) g.fillVistaRect(0,0,s,height,fc,false,false); else g.fillVistaRect(value-dif,0,dif,height,fc,false,false); } else { g.backColor = fc; if (vertical) g.fillRect(0, height - s, width, s); else if (!endless) g.fillRect(0,0,s,height); else g.fillRect(value-dif,0,dif,height); } } // draw the empty part g.backColor = bc; int ss = size-s; if (ss > 0 && !transparentBackground) { if (vertical) g.fillRect(0,0,width,ss); else g.fillRect(s,0,ss,height); } } if (endless && value-dif >= width) value = 0; // draw the text if (drawText) { StringBuffer sb = ProgressBar.sb; // get a local reference sb.setLength(0); sb.append(prefix); if (!endless && drawValue) sb.append(value); String st = sb.append(suffix).toString(); int x = (width-fm.stringWidth(st))>>1; int y = ((height-fmH)>>1)-1; int shadow = textShadowColor != -1 ? textShadowColor : !highlight ? -1 : highlightColor == -1 ? Color.getCursorColor(textColor) : highlightColor; g.foreColor = textColor; g.drawText(st, x, y, shadow != -1, shadow); } g.foreColor = textColor; if (drawBorder && !uiAndroid) g.drawRect(0,0,width,height); } /** Clears this control, setting the value to clearValueInt. */ public void clear() // guich@572_19 { setValue(clearValueInt); } }