From 07525f101e9325980da10ea18b4c2312aa5f6e0e Mon Sep 17 00:00:00 2001 From: Luis Uguina Date: Thu, 19 Mar 2020 23:48:06 +0100 Subject: [PATCH] Feature: Show progress bar in systray icon --- resources/icon-sprites.png | Bin 0 -> 11561 bytes resources/icon.png | Bin 10118 -> 0 bytes src/com/sheepit/client/Gui.java | 4 +- src/com/sheepit/client/Job.java | 51 +++++++++++++- .../sheepit/client/standalone/GuiSwing.java | 65 +++++++++++++++--- .../sheepit/client/standalone/GuiText.java | 6 +- .../client/standalone/GuiTextOneLine.java | 6 +- 7 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 resources/icon-sprites.png delete mode 100644 resources/icon.png diff --git a/resources/icon-sprites.png b/resources/icon-sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a9522279500c3cdfb31e3f8708280286514baf GIT binary patch literal 11561 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 literal 0 HcmV?d00001 diff --git a/resources/icon.png b/resources/icon.png deleted file mode 100644 index 88a9d5e85cebcbb50947c480a380b213c700998b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10118 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 diff --git a/src/com/sheepit/client/Gui.java b/src/com/sheepit/client/Gui.java index 2e4882f..c82ae9b 100644 --- a/src/com/sheepit/client/Gui.java +++ b/src/com/sheepit/client/Gui.java @@ -25,7 +25,9 @@ public interface Gui { public void stop(); public void status(String msg_); - + + public void updateTrayIcon(Integer percentage_); + public void setRenderingProjectName(String name_); public void setRemainingTime(String time_); diff --git a/src/com/sheepit/client/Job.java b/src/com/sheepit/client/Job.java index 9f6cd6b..cfdb2a6 100644 --- a/src/com/sheepit/client/Job.java +++ b/src/com/sheepit/client/Job.java @@ -40,6 +40,8 @@ import java.util.Observer; import java.util.TimeZone; import java.util.Timer; import java.util.TimerTask; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import com.sheepit.client.Configuration.ComputeType; import com.sheepit.client.Error.Type; @@ -54,7 +56,9 @@ public class Job { public static final String UPDATE_METHOD_BY_REMAINING_TIME = "remainingtime"; public static final String UPDATE_METHOD_BLENDER_INTERNAL_BY_PART = "blenderinternal"; public static final String UPDATE_METHOD_BY_TILE = "by_tile"; - + + public static final int SHOW_BASE_ICON = -1; + private String frameNumber; private String sceneMD5; private String rendererMD5; @@ -271,9 +275,18 @@ public class Job { log.debug("renderer output"); try { + int progress = -1; + + Pattern tilePattern = Pattern.compile(" ([0-9]+)\\s?\\/\\s?([0-9]+) "); + + // Initialise the progress bar in the icon (0% completed at this time) + gui.updateTrayIcon(0); + while ((line = input.readLine()) != null) { log.debug(line); - + + progress = computeRenderingProgress(line, tilePattern, progress); + updateRenderingMemoryPeak(line); if (configuration.getMaxMemory() != -1 && process.getMemoryUsed() > configuration.getMaxMemory()) { log.debug("Blocking render because process ram used (" + process.getMemoryUsed() + "k) is over user setting (" + configuration.getMaxMemory() + "k)"); @@ -282,6 +295,11 @@ public class Job { if (script_file != null) { script_file.delete(); } + + // Once the process is finished (either finished successfully or with an error) move back to + // base icon (isolated S with no progress bar) + gui.updateTrayIcon(Job.SHOW_BASE_ICON); + return Error.Type.RENDERER_OUT_OF_MEMORY; } @@ -291,6 +309,10 @@ public class Job { if (script_file != null) { script_file.delete(); } + + // Put back base icon + gui.updateTrayIcon(Job.SHOW_BASE_ICON); + return error; } @@ -304,6 +326,10 @@ public class Job { // most likely The handle is invalid log.error("Job::render exception(B) (silent error) " + err1); } + + // Put back base icon + gui.updateTrayIcon(Job.SHOW_BASE_ICON); + log.debug("end of rendering"); } catch (Exception err) { @@ -397,7 +423,26 @@ public class Job { return Error.Type.OK; } - + + private int computeRenderingProgress(String line, Pattern tilePattern, int currentProgress) { + Matcher standardTileInfo = tilePattern.matcher(line); + int newProgress = currentProgress; + + if (standardTileInfo.find()) { + int tileJustProcessed = Integer.parseInt(standardTileInfo.group(1)); + int totalTilesInJob = Integer.parseInt(standardTileInfo.group(2)); + + newProgress = Math.abs((tileJustProcessed * 100) / totalTilesInJob); + } + + // Only update the tray icon if percentage has changed + if (newProgress != currentProgress) { + gui.updateTrayIcon(newProgress); + } + + return newProgress; + } + private void updateRenderingStatus(String line) { if (getUpdateRenderingStatusMethod() != null && getUpdateRenderingStatusMethod().equals(Job.UPDATE_METHOD_BLENDER_INTERNAL_BY_PART)) { String search = " Part "; diff --git a/src/com/sheepit/client/standalone/GuiSwing.java b/src/com/sheepit/client/standalone/GuiSwing.java index 3d518fe..355185f 100644 --- a/src/com/sheepit/client/standalone/GuiSwing.java +++ b/src/com/sheepit/client/standalone/GuiSwing.java @@ -31,16 +31,21 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowStateListener; +import java.awt.image.BufferedImage; import java.net.URL; +import java.nio.Buffer; import java.util.Timer; import java.util.TimerTask; +import java.io.IOException; + import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; +import javax.imageio.ImageIO; import com.sheepit.client.Client; import com.sheepit.client.Configuration; @@ -72,6 +77,9 @@ public class GuiSwing extends JFrame implements Gui { private boolean waitingForAuthentication; private Client client; + private BufferedImage iconSprites; + private BufferedImage[] trayIconSprites; + @Getter @Setter private SettingsLoader settingsLoader; @@ -120,13 +128,21 @@ public class GuiSwing extends JFrame implements Gui { sysTray = null; } } - - URL iconUrl = getClass().getResource("/icon.png"); - if (iconUrl != null) { - ImageIcon img = new ImageIcon(iconUrl); - setIconImage(img.getImage()); + + // load the images sprite and split into individual images + URL spriteSequenceUrl = getClass().getResource("/icon-sprites.png"); + + if (spriteSequenceUrl != null) { + try { + iconSprites = ImageIO.read(spriteSequenceUrl); + trayIconSprites = new BufferedImage[101 * 1]; // sprite sheet has 101 images in 1 column + + setIconImage(extractImageFromSprite(-1)); // sprite 0 is standard Sheep It! icon + } catch (IOException e) { + e.printStackTrace(); + } } - + setTitle(title); setSize(520, 760); @@ -303,9 +319,9 @@ public class GuiSwing extends JFrame implements Gui { public TrayIcon getTrayIcon() { final PopupMenu trayMenu = new PopupMenu(); - - URL iconUrl = getClass().getResource("/icon.png"); - Image img = Toolkit.getDefaultToolkit().getImage(iconUrl); + + // on start, show the base icon + Image img = extractImageFromSprite(-1); final TrayIcon icon = new TrayIcon(img); MenuItem exit = new MenuItem("Exit"); @@ -350,7 +366,36 @@ public class GuiSwing extends JFrame implements Gui { return icon; } - + + private Image extractImageFromSprite(int spriteNumber) { + // Sprite structure + // Image 0: base sprite + // Images 1-101: progress bar percentage from 0 to 100 + // + // Always add +1 to the icon requested. + // -1 turns into 0 (base sprite with no progress bar) + // 0 to 101 turns into 1 to 101 (progress sequence starts in sprite 1 and ends on sprite 101) + ImageIcon img = new ImageIcon(iconSprites.getSubimage(0, (spriteNumber + 1) * 114, 114, 114)); + + return img.getImage(); + } + + @Override + public void updateTrayIcon(Integer percentage) { + // update the app icon on the app bar + Image img = extractImageFromSprite(percentage); + setIconImage(img); + + // if the app supports the system tray, update as well + if (sysTray != null && SystemTray.isSupported()) { + if (trayIcon != null) { + trayIcon.setImage(img); + trayIcon.setImageAutoSize(true); // use this method to ensure that icon is refreshed when on + // the tray + } + } + } + public class ThreadClient extends Thread { @Override public void run() { diff --git a/src/com/sheepit/client/standalone/GuiText.java b/src/com/sheepit/client/standalone/GuiText.java index 814559e..00896c7 100644 --- a/src/com/sheepit/client/standalone/GuiText.java +++ b/src/com/sheepit/client/standalone/GuiText.java @@ -88,7 +88,11 @@ public class GuiText implements Gui { public void stop() { Runtime.getRuntime().halt(0); } - + + @Override + public void updateTrayIcon(Integer percentage) { + } + @Override public void status(String msg_) { System.out.println(msg_); diff --git a/src/com/sheepit/client/standalone/GuiTextOneLine.java b/src/com/sheepit/client/standalone/GuiTextOneLine.java index 04cddd1..4ac551f 100644 --- a/src/com/sheepit/client/standalone/GuiTextOneLine.java +++ b/src/com/sheepit/client/standalone/GuiTextOneLine.java @@ -94,7 +94,11 @@ public class GuiTextOneLine implements Gui { public void stop() { Runtime.getRuntime().halt(0); } - + + @Override + public void updateTrayIcon(Integer percentage) { + } + @Override public void status(String msg_) { status = msg_;