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 org.apache.commons.io.IOUtils;
import com.threerings.getdown.Log; import com.threerings.getdown.Log;
import com.threerings.getdown.launcher.RotatingBackgrounds;
import com.threerings.getdown.util.ConfigUtil; import com.threerings.getdown.util.ConfigUtil;
import com.threerings.getdown.util.FileUtil; import com.threerings.getdown.util.FileUtil;
import com.threerings.getdown.util.LaunchUtil; import com.threerings.getdown.util.LaunchUtil;
@@ -97,7 +98,10 @@ public class Application
/** The human readable name of this application. */ /** The human readable name of this application. */
public String name; 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; public String backgroundImage;
/** The path (relative to the appdir) to the progress bar image. */ /** 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.backgroundImage = (String)cdata.get("ui.background");
} }
ui.progressImage = (String)cdata.get("ui.progress_image"); ui.progressImage = (String)cdata.get("ui.progress_image");
ui.rotatingBackgrounds = ConfigUtil.getMultiValue(cdata, "ui.rotating_background");
_dockIconPath = (String)cdata.get("ui.mac_dock_icon"); _dockIconPath = (String)cdata.get("ui.mac_dock_icon");
if (_dockIconPath == null) { if (_dockIconPath == null) {
_dockIconPath = "../desktop.icns"; // use a sensible default _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. * Manages the main control for the Getdown application updater and deployment system.
*/ */
public abstract class Getdown extends Thread public abstract class Getdown extends Thread
implements Application.StatusDisplay implements Application.StatusDisplay, ImageLoader
{ {
public static void main (String[] args) public static void main (String[] args)
{ {
@@ -717,23 +717,35 @@ public abstract class Getdown extends Thread
} }
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run () { public void run () {
if (_status == null) { if (_status == null) {
_container = createContainer(); _container = createContainer();
_status = new StatusPanel(_msgs); _status = new StatusPanel(_msgs);
_container.add(_status, BorderLayout.CENTER); _container.add(_status, BorderLayout.CENTER);
_background = getBackground();
} }
_status.init(_ifc, getBackgroundImage(), getProgressImage()); _status.init(_ifc, _background, getProgressImage());
showContainer(); 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 () protected Image getProgressImage ()
{ {
return loadImage(_ifc.progressImage); 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 * we will look to see if we can find a localized version by sticking a
* _<language> in front of the "." in the filename. * _<language> in front of the "." in the filename.
*/ */
protected BufferedImage loadImage (String path) public BufferedImage loadImage (String path)
{ {
String localeStr = Locale.getDefault().getLanguage(); String localeStr = Locale.getDefault().getLanguage();
@@ -926,6 +938,7 @@ public abstract class Getdown extends Thread
protected Container _container; protected Container _container;
protected StatusPanel _status; protected StatusPanel _status;
protected AbortPanel _abort; protected AbortPanel _abort;
protected RotatingBackgrounds _background;
protected boolean _dead; protected boolean _dead;
protected boolean _silent; protected boolean _silent;
@@ -22,19 +22,18 @@ package com.threerings.getdown.launcher;
import java.awt.Container; import java.awt.Container;
import java.awt.Image; 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 java.net.URL;
import javax.swing.JApplet; import javax.swing.JApplet;
import javax.swing.JPanel; 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.RunAnywhere;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.threerings.getdown.Log; import com.threerings.getdown.Log;
/** /**
@@ -42,6 +41,7 @@ import com.threerings.getdown.Log;
* given privileges). * given privileges).
*/ */
public class GetdownApplet extends JApplet public class GetdownApplet extends JApplet
implements ImageLoader
{ {
@Override // documentation inherited @Override // documentation inherited
public void init () public void init ()
@@ -50,16 +50,22 @@ public class GetdownApplet extends JApplet
// signer // signer
String appbase = getParameter("appbase"); String appbase = getParameter("appbase");
String appname = getParameter("appname"); String appname = getParameter("appname");
String imgpath = getParameter("bgimage"); String imgpath = getParameter("bgimage");;
if (appbase == null) { if (appbase == null) {
appbase = ""; appbase = "";
} }
if (appname == null) { if (appname == null) {
appname = ""; appname = "";
} }
if (imgpath == null) { final RotatingBackgrounds bgimages;
imgpath = ""; 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 Base: " + appbase);
Log.info("App Name: " + appname); Log.info("App Name: " + appname);
@@ -68,16 +74,6 @@ public class GetdownApplet extends JApplet
try { try {
appdir = initGetdown(appbase, appname, imgpath); 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 // record a few things for posterity
Log.info("------------------ VM Info ------------------"); Log.info("------------------ VM Info ------------------");
Log.info("-- OS Name: " + System.getProperty("os.name")); Log.info("-- OS Name: " + System.getProperty("os.name"));
@@ -103,6 +99,9 @@ public class GetdownApplet extends JApplet
getContentPane().removeAll(); getContentPane().removeAll();
return getContentPane(); return getContentPane();
} }
protected RotatingBackgrounds getBackground () {
return bgimages;
}
protected void showContainer () { protected void showContainer () {
((JPanel)getContentPane()).revalidate(); ((JPanel)getContentPane()).revalidate();
} }
@@ -115,10 +114,6 @@ public class GetdownApplet extends JApplet
protected JApplet getApplet () { protected JApplet getApplet () {
return GetdownApplet.this; return GetdownApplet.this;
} }
protected Image getBackgroundImage () {
return _bgimage == null ?
super.getBackgroundImage() : _bgimage;
}
protected void exit (int exitCode) { protected void exit (int exitCode) {
// don't exit as we're in an applet // 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 @Override // documentation inherited
public void start () public void start ()
{ {
@@ -257,9 +263,6 @@ public class GetdownApplet extends JApplet
/** Handles all the actual getting down. */ /** Handles all the actual getting down. */
protected Getdown _getdown; protected Getdown _getdown;
/** A background image drawn to make things look purdy. */
protected Image _bgimage;
/** An error encountered during initialization. */ /** An error encountered during initialization. */
protected String _errmsg; 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.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.Rectangle; import java.awt.Rectangle;
import javax.swing.JComponent;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javax.swing.JComponent;
import com.samskivert.swing.Label; import com.samskivert.swing.Label;
import com.samskivert.swing.util.SwingUtil; import com.samskivert.swing.util.SwingUtil;
import com.samskivert.text.MessageUtil; import com.samskivert.text.MessageUtil;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.samskivert.util.Throttle; import com.samskivert.util.Throttle;
import com.threerings.getdown.Log; import com.threerings.getdown.Log;
import com.threerings.getdown.data.Application.UpdateInterface; import com.threerings.getdown.data.Application.UpdateInterface;
@@ -52,16 +50,17 @@ public class StatusPanel extends JComponent
_msgs = msgs; _msgs = msgs;
} }
public void init (UpdateInterface ifc, Image bgimg, Image barimg) public void init (UpdateInterface ifc, RotatingBackgrounds bg, Image barimg)
{ {
_ifc = ifc; _ifc = ifc;
_bgimg = bgimg; _bg = bg;
if (bgimg == null) { Image img = _bg.getImage(_progress);
if (img == null) {
Rectangle bounds = ifc.progress.union(ifc.status); Rectangle bounds = ifc.progress.union(ifc.status);
bounds.grow(5, 5); bounds.grow(5, 5);
_psize = bounds.getSize(); _psize = bounds.getSize();
} else { } else {
_psize = new Dimension(bgimg.getWidth(null), bgimg.getHeight(null)); _psize = new Dimension(img.getWidth(null), img.getHeight(null));
} }
_barimg = barimg; _barimg = barimg;
} }
@@ -132,8 +131,9 @@ public class StatusPanel extends JComponent
super.paintComponent(g); super.paintComponent(g);
Graphics2D gfx = (Graphics2D)g; Graphics2D gfx = (Graphics2D)g;
if (_bgimg != null) { Image img = _bg.getImage(_progress);
gfx.drawImage(_bgimg, 0, 0, null); if (img != null) {
gfx.drawImage(img, 0, 0, null);
} else { } else {
gfx.setColor(getBackground()); gfx.setColor(getBackground());
gfx.fillRect(0, 0, getWidth(), getHeight()); 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 Dimension _psize;
protected ResourceBundle _msgs; protected ResourceBundle _msgs;