/** * Copyright 2008 - 2015 The Loon Game Engine Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.5 */ package loon.html5.gwt.widgets; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; @SuppressWarnings("deprecation") public class ProgressBar extends Widget implements ResizableWidget { private static final String DEFAULT_TEXT_CLASS_NAME = "gwt-ProgressBar-text"; private String textClassName = DEFAULT_TEXT_CLASS_NAME; private String textFirstHalfClassName = DEFAULT_TEXT_CLASS_NAME + "-firstHalf"; private String textSecondHalfClassName = DEFAULT_TEXT_CLASS_NAME + "-secondHalf"; public abstract static class TextFormatter { protected abstract String getText(ProgressBar bar, double curProgress); } private Element barElement; private double curProgress; private double maxProgress; private double minProgress; private boolean textVisible = true; private Element textElement; private TextFormatter textFormatter; public ProgressBar() { this(0.0, 100.0, 0.0); } public ProgressBar(double curProgress) { this(0.0, 100.0, curProgress); } public ProgressBar(double minProgress, double maxProgress) { this(minProgress, maxProgress, 0.0); } public ProgressBar(double minProgress, double maxProgress, double curProgress) { this(minProgress, maxProgress, curProgress, null); } public ProgressBar(double minProgress, double maxProgress, double curProgress, TextFormatter textFormatter) { this.minProgress = minProgress; this.maxProgress = maxProgress; this.curProgress = curProgress; setTextFormatter(textFormatter); setElement(DOM.createDiv()); DOM.setStyleAttribute(getElement(), "position", "relative"); setStyleName("gwt-ProgressBar-shell"); barElement = DOM.createDiv(); DOM.appendChild(getElement(), barElement); DOM.setStyleAttribute(barElement, "height", "100%"); setBarStyleName("gwt-ProgressBar-bar"); textElement = DOM.createDiv(); DOM.appendChild(getElement(), textElement); DOM.setStyleAttribute(textElement, "position", "absolute"); DOM.setStyleAttribute(textElement, "top", "0px"); setProgress(curProgress); } public double getMaxProgress() { return maxProgress; } public double getMinProgress() { return minProgress; } public double getPercent() { if (maxProgress <= minProgress) { return 0.0; } double percent = (curProgress - minProgress) / (maxProgress - minProgress); return Math.max(0.0, Math.min(1.0, percent)); } public double getProgress() { return curProgress; } public TextFormatter getTextFormatter() { return textFormatter; } public boolean isTextVisible() { return textVisible; } public void onResize(int width, int height) { if (textVisible) { int textWidth = DOM.getElementPropertyInt(textElement, "offsetWidth"); int left = (width / 2) - (textWidth / 2); DOM.setStyleAttribute(textElement, "left", left + "px"); } } public void redraw() { if (isAttached()) { int width = DOM.getElementPropertyInt(getElement(), "clientWidth"); int height = DOM .getElementPropertyInt(getElement(), "clientHeight"); onResize(width, height); } } public void setBarStyleName(String barClassName) { DOM.setElementProperty(barElement, "className", barClassName); } public void setMaxProgress(double maxProgress) { this.maxProgress = maxProgress; curProgress = Math.min(curProgress, maxProgress); resetProgress(); } public void setMinProgress(double minProgress) { this.minProgress = minProgress; curProgress = Math.max(curProgress, minProgress); resetProgress(); } public void setProgress(double curProgress) { this.curProgress = Math.max(minProgress, Math.min(maxProgress, curProgress)); int percent = (int) (100 * getPercent()); DOM.setStyleAttribute(barElement, "width", percent + "%"); DOM.setElementProperty(textElement, "innerHTML", generateText(curProgress)); updateTextStyle(percent); redraw(); } public void setTextFirstHalfStyleName(String textFirstHalfClassName) { this.textFirstHalfClassName = textFirstHalfClassName; onTextStyleChange(); } public void setTextFormatter(TextFormatter textFormatter) { this.textFormatter = textFormatter; } public void setTextSecondHalfStyleName(String textSecondHalfClassName) { this.textSecondHalfClassName = textSecondHalfClassName; onTextStyleChange(); } public void setTextStyleName(String textClassName) { this.textClassName = textClassName; onTextStyleChange(); } public void setTextVisible(boolean textVisible) { this.textVisible = textVisible; if (this.textVisible) { DOM.setStyleAttribute(textElement, "display", ""); redraw(); } else { DOM.setStyleAttribute(textElement, "display", "none"); } } protected String generateText(double curProgress) { if (textFormatter != null) { return textFormatter.getText(this, curProgress); } else { return (int) (100 * getPercent()) + "%"; } } protected Element getBarElement() { return barElement; } protected Element getTextElement() { return textElement; } @Override protected void onLoad() { DOM.setStyleAttribute(getElement(), "position", "relative"); ResizableWidgetCollection.get().add(this); redraw(); } @Override protected void onUnload() { ResizableWidgetCollection.get().remove(this); } protected void resetProgress() { setProgress(getProgress()); } private void onTextStyleChange() { int percent = (int) (100 * getPercent()); updateTextStyle(percent); } private void updateTextStyle(int percent) { if (percent < 50) { DOM.setElementProperty(textElement, "className", textClassName + " " + textFirstHalfClassName); } else { DOM.setElementProperty(textElement, "className", textClassName + " " + textSecondHalfClassName); } } }