/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import io.bitsquare.BitsquareException;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.util.Utilities;
import io.bitsquare.gui.util.GUIUtil;
import io.bitsquare.gui.util.ImageUtil;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* There is no JavaFX support yet, so we need to use AWT.
*/
public class SystemTray {
private static final Logger log = LoggerFactory.getLogger(SystemTray.class);
private static final String ICON_HI_RES = "/images/system_tray_icon@2x.png";
private static final String ICON_LO_RES = "/images/system_tray_icon.png";
private static final String ICON_WINDOWS = "/images/system_tray_icon_windows.png";
private static final String ICON_LINUX = "/images/system_tray_icon_linux.png";
private static final String SHOW_WINDOW_LABEL = "Show exchange window";
private static final String HIDE_WINDOW_LABEL = "Hide exchange window";
private static SystemTray systemTray;
private final Stage stage;
private final Runnable onExit;
private final MenuItem toggleShowHideItem = new MenuItem(HIDE_WINDOW_LABEL);
public static SystemTray create(Stage stage, Runnable onExit) {
systemTray = new SystemTray(stage, onExit);
return systemTray;
}
private SystemTray(Stage stage, Runnable onExit) {
this.stage = stage;
this.onExit = onExit;
init();
}
private void init() {
if (!java.awt.SystemTray.isSupported()) {
log.error("System tray is not supported.");
return;
}
// prevent exiting the app when the last window gets closed
// For now we allow to close the app by closing the window.
// Later we only let it close via the system trays exit.
Platform.setImplicitExit(false);
MenuItem aboutItem = new MenuItem("Info about Bitsquare");
MenuItem exitItem = new MenuItem("Exit");
PopupMenu popupMenu = new PopupMenu();
popupMenu.add(aboutItem);
popupMenu.addSeparator();
popupMenu.add(toggleShowHideItem);
popupMenu.addSeparator();
popupMenu.add(exitItem);
String path;
if (Utilities.isOSX())
path = ImageUtil.isRetina() ? ICON_HI_RES : ICON_LO_RES;
else if (Utilities.isWindows())
path = ICON_WINDOWS;
else
path = ICON_LINUX;
try {
BufferedImage trayIconImage = ImageIO.read(getClass().getResource(path));
TrayIcon trayIcon = new TrayIcon(trayIconImage);
// On Windows and Linux the icon needs to be scaled
// On OSX we get the correct size from the provided image
if (!Utilities.isOSX()) {
int trayIconWidth = trayIcon.getSize().width;
trayIcon = new TrayIcon(trayIconImage.getScaledInstance(trayIconWidth, -1, Image.SCALE_SMOOTH));
}
trayIcon.setPopupMenu(popupMenu);
trayIcon.setToolTip("Bitsquare: The decentralized bitcoin exchange");
java.awt.SystemTray.getSystemTray().add(trayIcon);
} catch (AWTException e1) {
log.error("Icon could not be added to system tray.", e1);
} catch (IOException e2) {
throw new BitsquareException(e2);
}
toggleShowHideItem.addActionListener(e -> {
if (stage.isShowing()) {
toggleShowHideItem.setLabel(SHOW_WINDOW_LABEL);
UserThread.execute(stage::hide);
} else {
toggleShowHideItem.setLabel(HIDE_WINDOW_LABEL);
UserThread.execute(stage::show);
}
});
aboutItem.addActionListener(e -> {
try {
GUIUtil.openWebPage("https://bitsquare.io");
} catch (Exception e1) {
e1.printStackTrace();
}
});
exitItem.addActionListener(e -> UserThread.execute(onExit::run));
}
public void hideStage() {
stage.hide();
toggleShowHideItem.setLabel(SHOW_WINDOW_LABEL);
}
}