package magic.ui;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import magic.data.GeneralConfig;
@SuppressWarnings("serial")
class MagicStickyFrame extends JFrame {
private static final Dimension MIN_SIZE = new Dimension(GeneralConfig.DEFAULT_FRAME_WIDTH, GeneralConfig.DEFAULT_FRAME_HEIGHT);
protected final GeneralConfig config = GeneralConfig.getInstance();
private boolean ignoreWindowDeactivate;
private int normalFrameState;
private Rectangle normalFrameRect;
MagicStickyFrame() {
addWindowListeners();
restoreSavedFrameState();
}
private void addWindowListeners() {
addWindowStateListener(new WindowAdapter() {
@Override
public void windowStateChanged(WindowEvent e) {
if (!isUndecorated()) {
normalFrameState = e.getNewState();
}
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowDeactivated(final WindowEvent ev) {
if (isFullScreen() && ev.getOppositeWindow() == null && !ignoreWindowDeactivate) {
try {
setState(Frame.ICONIFIED);
} catch (Exception ex) {
// see issue #130: Crashes when there is a change in focus? On Mac.
System.err.println("setState(Frame.ICONIFIED) failed\n" + ex);
}
}
ignoreWindowDeactivate = false;
}
});
}
private boolean isFullScreen() {
return getExtendedState() == JFrame.MAXIMIZED_BOTH && this.isUndecorated();
}
private void saveNormalFrameSizePos() {
normalFrameState = getExtendedState();
setExtendedState(Frame.NORMAL);
normalFrameRect = new Rectangle(getLocation(), getSize());
}
private void setFrameFullScreenState() {
setUndecorated(true);
setExtendedState(JFrame.MAXIMIZED_BOTH);
}
private void setFrameNormalState() {
setExtendedState(normalFrameState);
setSize(normalFrameRect.width, normalFrameRect.height);
setLocation(normalFrameRect.x, normalFrameRect.y);
setUndecorated(false);
}
private void setFullScreenMode(final boolean isFullScreen) {
if (isFullScreen) {
saveNormalFrameSizePos();
this.dispose();
setFrameFullScreenState();
} else {
this.dispose();
setFrameNormalState();
}
setVisible(true);
ignoreWindowDeactivate = true;
}
public void toggleFullScreenMode() {
setFullScreenMode(!isFullScreen());
}
private void setSizableFrameState() {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle rect = config.getSizableFrameBounds();
Point p1 = new Point(rect.x, rect.y);
Point p2 = new Point(p1.x + rect.width, p1.y + rect.height);
if (p1.x >= 0 && p1.y >= 0 && p2.x <= screen.width && p2.y <= screen.height) {
setSize(rect.width, rect.height);
setLocation(rect.x, rect.y);
} else {
// saved frame overlaps screen bounds so position
// in center of screen at minimum size.
setSize(MIN_SIZE);
setLocationRelativeTo(null);
}
}
private void restoreSavedFrameState() {
setMinimumSize(MIN_SIZE);
setSizableFrameState();
if (config.isMaximized()) {
setExtendedState(JFrame.MAXIMIZED_BOTH);
}
normalFrameState = getExtendedState();
if (config.isFullScreen()) {
setFullScreenMode(true);
}
}
protected void saveSizeAndPosition() {
config.setMaximized(normalFrameState == Frame.MAXIMIZED_BOTH);
config.setFullScreen(isFullScreen());
if (getExtendedState() == Frame.NORMAL) {
config.setSizableFrameBounds(getLocation(), getSize());
} else if (getExtendedState() == Frame.MAXIMIZED_BOTH && !isFullScreen()) {
setExtendedState(Frame.NORMAL);
config.setSizableFrameBounds(getLocation(), getSize());
} else if (isFullScreen()) {
config.setSizableFrameBounds(normalFrameRect);
}
config.save();
}
}