Feature: Show progress bar in systray icon
This commit is contained in:
committed by
Laurent Clouet
parent
cffd34708f
commit
07525f101e
BIN
resources/icon-sprites.png
Normal file
BIN
resources/icon-sprites.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.9 KiB |
@@ -26,6 +26,8 @@ public interface Gui {
|
||||
|
||||
public void status(String msg_);
|
||||
|
||||
public void updateTrayIcon(Integer percentage_);
|
||||
|
||||
public void setRenderingProjectName(String name_);
|
||||
|
||||
public void setRemainingTime(String time_);
|
||||
|
||||
@@ -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;
|
||||
@@ -55,6 +57,8 @@ public class Job {
|
||||
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) {
|
||||
@@ -398,6 +424,25 @@ 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 ";
|
||||
|
||||
@@ -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;
|
||||
@@ -121,10 +129,18 @@ public class GuiSwing extends JFrame implements Gui {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -304,8 +320,8 @@ 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");
|
||||
@@ -351,6 +367,35 @@ public class GuiSwing extends JFrame implements Gui {
|
||||
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@@ -89,6 +89,10 @@ public class GuiText implements Gui {
|
||||
Runtime.getRuntime().halt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTrayIcon(Integer percentage) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void status(String msg_) {
|
||||
System.out.println(msg_);
|
||||
|
||||
@@ -95,6 +95,10 @@ public class GuiTextOneLine implements Gui {
|
||||
Runtime.getRuntime().halt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTrayIcon(Integer percentage) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void status(String msg_) {
|
||||
status = msg_;
|
||||
|
||||
Reference in New Issue
Block a user