Allow more than one background image to be specified, and if there are

multiple, rotate through them as things are downloaded.
This commit is contained in:
Charlie Groves
2007-10-12 18:46:40 +00:00
parent b8f3333124
commit a22d5c3707
6 changed files with 174 additions and 46 deletions
@@ -66,6 +66,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import com.threerings.getdown.Log;
import com.threerings.getdown.launcher.RotatingBackgrounds;
import com.threerings.getdown.util.ConfigUtil;
import com.threerings.getdown.util.FileUtil;
import com.threerings.getdown.util.LaunchUtil;
@@ -97,7 +98,10 @@ public class Application
/** The human readable name of this application. */
public String name;
/** The path (relative to the appdir) to the background image. */
/** Background image specifiers for {@link RotatingBackgrounds}. */
public String[] rotatingBackgrounds;
/** The path (relative to the appdir) to a single background image. */
public String backgroundImage;
/** The path (relative to the appdir) to the progress bar image. */
@@ -575,7 +579,7 @@ public class Application
ui.backgroundImage = (String)cdata.get("ui.background");
}
ui.progressImage = (String)cdata.get("ui.progress_image");
ui.rotatingBackgrounds = ConfigUtil.getMultiValue(cdata, "ui.rotating_background");
_dockIconPath = (String)cdata.get("ui.mac_dock_icon");
if (_dockIconPath == null) {
_dockIconPath = "../desktop.icns"; // use a sensible default
@@ -71,7 +71,7 @@ import com.threerings.getdown.util.ProgressObserver;
* Manages the main control for the Getdown application updater and deployment system.
*/
public abstract class Getdown extends Thread
implements Application.StatusDisplay
implements Application.StatusDisplay, ImageLoader
{
public static void main (String[] args)
{
@@ -717,23 +717,35 @@ public abstract class Getdown extends Thread
}
EventQueue.invokeLater(new Runnable() {
public void run () {
if (_status == null) {
_container = createContainer();
_status = new StatusPanel(_msgs);
_container.add(_status, BorderLayout.CENTER);
_background = getBackground();
}
_status.init(_ifc, getBackgroundImage(), getProgressImage());
_status.init(_ifc, _background, getProgressImage());
showContainer();
}
});
}
protected Image getBackgroundImage ()
protected RotatingBackgrounds getBackground ()
{
return loadImage(_ifc.backgroundImage);
if (_ifc.rotatingBackgrounds != null) {
if (_ifc.backgroundImage != null) {
Log.warning("ui.background_image and ui.rotating_background were "
+ " both specified. The rotating images are being used.");
}
return new RotatingBackgrounds(_ifc.rotatingBackgrounds, Getdown.this);
} else if (_ifc.backgroundImage != null) {
return new RotatingBackgrounds(loadImage(_ifc.backgroundImage));
} else {
return new RotatingBackgrounds();
}
}
protected Image getProgressImage ()
{
return loadImage(_ifc.progressImage);
@@ -805,7 +817,7 @@ public abstract class Getdown extends Thread
* we will look to see if we can find a localized version by sticking a
* _<language> in front of the "." in the filename.
*/
protected BufferedImage loadImage (String path)
public BufferedImage loadImage (String path)
{
String localeStr = Locale.getDefault().getLanguage();
@@ -926,6 +938,7 @@ public abstract class Getdown extends Thread
protected Container _container;
protected StatusPanel _status;
protected AbortPanel _abort;
protected RotatingBackgrounds _background;
protected boolean _dead;
protected boolean _silent;
@@ -22,19 +22,18 @@ package com.threerings.getdown.launcher;
import java.awt.Container;
import java.awt.Image;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JApplet;
import javax.swing.JPanel;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.File;
import java.io.PrintStream;
import com.samskivert.util.RunAnywhere;
import com.samskivert.util.StringUtil;
import com.threerings.getdown.Log;
/**
@@ -42,6 +41,7 @@ import com.threerings.getdown.Log;
* given privileges).
*/
public class GetdownApplet extends JApplet
implements ImageLoader
{
@Override // documentation inherited
public void init ()
@@ -50,16 +50,22 @@ public class GetdownApplet extends JApplet
// signer
String appbase = getParameter("appbase");
String appname = getParameter("appname");
String imgpath = getParameter("bgimage");
String imgpath = getParameter("bgimage");;
if (appbase == null) {
appbase = "";
}
if (appname == null) {
appname = "";
}
if (imgpath == null) {
imgpath = "";
final RotatingBackgrounds bgimages;
if(imgpath == null) {
bgimages = new RotatingBackgrounds();
} else if(imgpath.contains(",")) {
bgimages = new RotatingBackgrounds(imgpath.split(","), this);
} else {
bgimages = new RotatingBackgrounds(loadImage(imgpath));
}
Log.info("App Base: " + appbase);
Log.info("App Name: " + appname);
@@ -68,16 +74,6 @@ public class GetdownApplet extends JApplet
try {
appdir = initGetdown(appbase, appname, imgpath);
// if a background image was specified, grabbit
try {
if (!StringUtil.isBlank(imgpath)) {
_bgimage = getImage(new URL(getDocumentBase(), imgpath));
}
} catch (Exception e) {
Log.info("Failed to load background image [path=" + imgpath + "].");
Log.logStackTrace(e);
}
// record a few things for posterity
Log.info("------------------ VM Info ------------------");
Log.info("-- OS Name: " + System.getProperty("os.name"));
@@ -103,6 +99,9 @@ public class GetdownApplet extends JApplet
getContentPane().removeAll();
return getContentPane();
}
protected RotatingBackgrounds getBackground () {
return bgimages;
}
protected void showContainer () {
((JPanel)getContentPane()).revalidate();
}
@@ -115,10 +114,6 @@ public class GetdownApplet extends JApplet
protected JApplet getApplet () {
return GetdownApplet.this;
}
protected Image getBackgroundImage () {
return _bgimage == null ?
super.getBackgroundImage() : _bgimage;
}
protected void exit (int exitCode) {
// don't exit as we're in an applet
}
@@ -132,6 +127,17 @@ public class GetdownApplet extends JApplet
}
}
public Image loadImage (String path)
{
try {
return getImage(new URL(getDocumentBase(), path));
} catch (MalformedURLException e) {
Log.warning("Failed to load background image [path=" + path + "].");
Log.logStackTrace(e);
return null;
}
}
@Override // documentation inherited
public void start ()
{
@@ -257,9 +263,6 @@ public class GetdownApplet extends JApplet
/** Handles all the actual getting down. */
protected Getdown _getdown;
/** A background image drawn to make things look purdy. */
protected Image _bgimage;
/** An error encountered during initialization. */
protected String _errmsg;
}
@@ -0,0 +1,9 @@
package com.threerings.getdown.launcher;
import java.awt.Image;
public interface ImageLoader
{
public Image loadImage (String path);
}
@@ -0,0 +1,98 @@
package com.threerings.getdown.launcher;
import java.awt.Image;
import com.threerings.getdown.Log;
public class RotatingBackgrounds
{
/**
* Creates a placeholder if there are no images. Just returns null from getImage every time.
*/
public RotatingBackgrounds ()
{
makeEmpty();
}
/** Creates a single image background. */
public RotatingBackgrounds (Image background)
{
percentages = new int[] { 0 };
minDisplayTime = new int[] { 0 };
images = new Image[] { background };
}
/**
* Create a sequence of images to be rotated through from <code>backgrounds</code>.
*
* Each String in backgrounds should be the path to the image, a semicolon, and the minimum
* amount of time to display the image in seconds. Each image will be active for an equal
* percentage of the download process, unless one hasn't been active for its minimum display
* time when the next should be shown. In that case, it's left up until its been there for its
* minimum display time and then the next one gets to come up.
*/
public RotatingBackgrounds (String[] backgrounds, ImageLoader loader)
{
percentages = new int[backgrounds.length];
minDisplayTime = new int[backgrounds.length];
images = new Image[backgrounds.length];
for (int ii = 0; ii < backgrounds.length; ii++) {
String[] pieces = backgrounds[ii].split(";");
if (pieces.length != 2) {
Log.warning("Unable to parse background image '" + backgrounds[ii] + "'");
makeEmpty();
return;
}
images[ii] = loader.loadImage(pieces[0]);
try {
minDisplayTime[ii] = Integer.parseInt(pieces[1]);
} catch (NumberFormatException e) {
Log.warning("Unable to parse background image display time '"
+ backgrounds[ii] + "'");
makeEmpty();
return;
}
percentages[ii] = (int)((ii/(float)backgrounds.length) * 100);
}
}
/**
* @return the image to display at the given progress or null if there aren't any.
*/
public Image getImage (int progress)
{
if (images.length == 0) {
return null;
}
long now = System.currentTimeMillis();
if (current != images.length - 1
&& (current == -1 || (progress >= percentages[current + 1] &&
(now - currentDisplayStart) / 1000 > minDisplayTime[current]))) {
current++;
currentDisplayStart = now;
}
return images[current];
}
protected void makeEmpty ()
{
percentages = new int[] {};
minDisplayTime = new int[] {};
images = new Image[] {};
}
/** Time at which the currently displayed image was first displayed in millis. */
protected long currentDisplayStart;
/** The index of the currently displayed image or -1 if we haven't displayed any. */
protected int current = -1;
protected Image[] images;
/** Percentage at which each image should be displayed. */
protected int[] percentages;
/** Time to show each image in seconds. */
protected int[] minDisplayTime;
}
@@ -22,23 +22,21 @@ package com.threerings.getdown.launcher;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.swing.JComponent;
import com.samskivert.swing.Label;
import com.samskivert.swing.util.SwingUtil;
import com.samskivert.text.MessageUtil;
import com.samskivert.util.StringUtil;
import com.samskivert.util.Throttle;
import com.threerings.getdown.Log;
import com.threerings.getdown.data.Application.UpdateInterface;
@@ -52,16 +50,17 @@ public class StatusPanel extends JComponent
_msgs = msgs;
}
public void init (UpdateInterface ifc, Image bgimg, Image barimg)
public void init (UpdateInterface ifc, RotatingBackgrounds bg, Image barimg)
{
_ifc = ifc;
_bgimg = bgimg;
if (bgimg == null) {
_bg = bg;
Image img = _bg.getImage(_progress);
if (img == null) {
Rectangle bounds = ifc.progress.union(ifc.status);
bounds.grow(5, 5);
_psize = bounds.getSize();
} else {
_psize = new Dimension(bgimg.getWidth(null), bgimg.getHeight(null));
_psize = new Dimension(img.getWidth(null), img.getHeight(null));
}
_barimg = barimg;
}
@@ -132,8 +131,9 @@ public class StatusPanel extends JComponent
super.paintComponent(g);
Graphics2D gfx = (Graphics2D)g;
if (_bgimg != null) {
gfx.drawImage(_bgimg, 0, 0, null);
Image img = _bg.getImage(_progress);
if (img != null) {
gfx.drawImage(img, 0, 0, null);
} else {
gfx.setColor(getBackground());
gfx.fillRect(0, 0, getWidth(), getHeight());
@@ -256,7 +256,8 @@ public class StatusPanel extends JComponent
}
}
protected Image _bgimg, _barimg;
protected Image _barimg;
protected RotatingBackgrounds _bg;
protected Dimension _psize;
protected ResourceBundle _msgs;