/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.utils.text.dynamic; import com.jcwhatever.nucleus.utils.PreCon; import com.jcwhatever.nucleus.utils.text.TextColor; import com.jcwhatever.nucleus.utils.text.TextUtils; import com.jcwhatever.nucleus.utils.text.components.IChatMessage; /** * {@link IDynamicText} implementation that displays a status bar * that shows percentage. */ public class StatusBarText implements IDynamicText { private volatile int _width; private volatile double _percent = 1.0D; private volatile IChatMessage _currentText; private volatile char _fullChar = '\u2587'; private volatile char _partialChar = '\u2587'; private volatile char _emptyChar = '\u2587'; private volatile TextColor _fullColor = TextColor.GREEN; private volatile TextColor _partialColor = TextColor.DARK_GREEN; private volatile TextColor _emptyColor = TextColor.DARK_GRAY; private volatile int _refreshCount = 0; private final Object _sync = new Object(); protected volatile boolean _isUpdateRequired = true; /** * Constructor. * * <p>Width is 10 characters.</p> */ public StatusBarText() { this(10); } /** * Constructor. * * @param charWidth The character width of the bar. */ public StatusBarText(int charWidth) { _width = charWidth; } /** * Get the character width of the bar. */ public int getCharWidth() { return _width; } /** * Set the character width of the bar. * * @param width The character width. */ public void setCharWidth(int width) { if (_width == width) return; synchronized (_sync) { if (_width == width) return; _width = width; _isUpdateRequired = true; } } /** * Get the character used to indicate a percentage. */ public char getFullChar() { return _fullChar; } /** * Set the character used to indicate a percentage. * * @param ch The character. */ public void setFullChar(char ch) { if (_fullChar == ch) return; synchronized (_sync) { if (_fullChar == ch) return; _fullChar = ch; _isUpdateRequired = true; } } /** * Get the character used to indicate a partial percentage. */ public char getPartialChar() { return _partialChar; } /** * Set the character used to indicate a partial percentage. * * @param ch The character. */ public void setPartialChar(char ch) { if (_partialChar == ch) return; synchronized (_sync) { if (_partialChar == ch) return; _partialChar = ch; _isUpdateRequired = true; } } /** * Get the character used to indicate no percentage. */ public char getEmptyChar() { return _emptyChar; } /** * Set the character used to indicate no percentage. * * @param ch The character. */ public void setEmptyChar(char ch) { if (_emptyChar == ch) return; synchronized (_sync) { if (_emptyChar == ch) return; _emptyChar = ch; _isUpdateRequired = true; } } /** * Get the character color used to indicate a percentage. */ public TextColor getFullColor() { return _fullColor; } /** * Set the character color used to indicate a percentage. * * @param color The color. */ public void setFullColor(TextColor color) { PreCon.notNull(color); if (_fullColor == color) return; synchronized (_sync) { if (_fullColor == color) return; _fullColor = color; _isUpdateRequired = true; } } /** * Get the character color used to indicate a partial percentage. */ public TextColor getPartialColor() { return _partialColor; } /** * Set the character color used to indicate a partial percentage. * * @param color The color. */ public void setPartialColor(TextColor color) { PreCon.notNull(color); if (_partialColor == color) return; synchronized (_sync) { if (_partialColor == color) return; _partialColor = color; _isUpdateRequired = true; } } /** * Get the character color used to indicate no percentage. * * @return The color. */ public TextColor getEmptyColor() { return _emptyColor; } /** * Set the character color used to indicate no percentage. * * @param color The color. */ public void setEmptyColor(TextColor color) { PreCon.notNull(color); if (_emptyColor == color) return; synchronized (_sync) { if (_emptyColor == color) return; _emptyColor = color; _isUpdateRequired = true; } } /** * Get the current percentage displayed by the bar. * * @return The percent is a number between 0.0 and 1.0 * where 1.0 = 100%. */ public double getPercent() { return _percent; } /** * Set the current percentage displayed by the bar. * * @param percent The percent. The percent is a number between 0.0 * and 1.0 where 1.0 = 100% */ public void setPercent(double percent) { if (Double.compare(percent, _percent) == 0) return; synchronized (_sync) { if (Double.compare(percent, _percent) == 0) return; _percent = percent; _isUpdateRequired = true; } } @Override public IChatMessage nextText() { if (_isUpdateRequired) { synchronized (_sync) { if (!_isUpdateRequired) return _currentText; _isUpdateRequired = false; double dblWidth = Math.min(_width, _width * _percent); double round = Math.round(dblWidth); boolean hasPartial = dblWidth < round; int fullWidth = (int) Math.max(Math.floor(dblWidth), 0); StringBuilder buffer = new StringBuilder(_width + 6); for (int i = 0; i < _width; i++) { if (i < fullWidth) { buffer.append(_fullColor.getFormatCode()); buffer.append(_fullChar); } else if (i == fullWidth && hasPartial) { buffer.append(_partialColor.getFormatCode()); buffer.append(_partialChar); } else { buffer.append(_emptyColor.getFormatCode()); buffer.append(_emptyChar); } } _currentText = TextUtils.format(buffer.toString()); } } return _currentText; } @Override public int getRefreshRate() { if (_isUpdateRequired) { _refreshCount = 5; return 1; } else if (_refreshCount > 0) { _refreshCount--; return 1; } return 0; } @Override public String toString() { return nextText().toString(); } }