001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.awt.Frame;
008import java.awt.GraphicsDevice;
009import java.awt.GraphicsEnvironment;
010import java.awt.Rectangle;
011import java.awt.Toolkit;
012import java.awt.Window;
013import java.awt.event.ActionEvent;
014import java.awt.event.KeyEvent;
015import java.util.ArrayList;
016import java.util.List;
017
018import javax.swing.JComponent;
019import javax.swing.JFrame;
020import javax.swing.KeyStroke;
021
022import org.openstreetmap.josm.Main;
023import org.openstreetmap.josm.tools.PlatformHookWindows;
024import org.openstreetmap.josm.tools.Shortcut;
025
026/**
027 * This class toggles the full-screen mode.
028 * @since 2533
029 */
030public class FullscreenToggleAction extends ToggleAction {
031    private GraphicsDevice gd;
032    private Rectangle prevBounds;
033
034    /**
035     * Constructs a new {@code FullscreenToggleAction}.
036     */
037    public FullscreenToggleAction() {
038        super(tr("Fullscreen view"),
039              null, /* no icon */
040              tr("Toggle fullscreen view"),
041              Shortcut.registerShortcut("menu:view:fullscreen", tr("Toggle fullscreen view"),KeyEvent.VK_F11, Shortcut.DIRECT),
042              false /* register */
043        );
044        putValue("help", ht("/Action/FullscreenView"));
045        putValue("toolbar", "fullscreen");
046        Main.toolbar.register(this);
047        gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
048        setSelected(Main.pref.getBoolean("draw.fullscreen", false));
049        notifySelectedState();
050    }
051
052    @Override
053    public void actionPerformed(ActionEvent e) {
054        toggleSelectedState(e);
055        Main.pref.put("draw.fullscreen", isSelected());
056        notifySelectedState();
057        setMode();
058    }
059
060    /**
061     * To call if this action must be initially run at JOSM startup.
062     */
063    public void initial() {
064        if (isSelected()) {
065            setMode();
066        }
067    }
068
069    protected void setMode() {
070        JFrame frame = (JFrame) Main.parent;
071
072        List<Window> visibleWindows = new ArrayList<Window>();
073        visibleWindows.add(frame);
074        for (Window w : Frame.getWindows()) {
075            if (w.isVisible() && w != frame) {
076                visibleWindows.add(w);
077            }
078        }
079        
080        boolean selected = isSelected();
081
082        frame.dispose();
083        frame.setUndecorated(selected);
084
085        if (selected) {
086            prevBounds = frame.getBounds();
087            frame.setBounds(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
088        }
089
090        // we cannot use hw-exclusive fullscreen mode in MS-Win, as long
091        // as josm throws out modal dialogs.
092        //
093        // the good thing is: fullscreen works without exclusive mode,
094        // since windows (or java?) draws the undecorated window full-
095        // screen by default (it's a simulated mode, but should be ok)
096        String exclusive = Main.pref.get("draw.fullscreen.exclusive-mode", "auto");
097        if ("true".equals(exclusive) || ("auto".equals(exclusive) && !(Main.platform instanceof PlatformHookWindows))) {
098            gd.setFullScreenWindow(selected ? frame : null);
099        }
100
101        if (!selected && prevBounds != null) {
102            frame.setBounds(prevBounds);
103        }
104
105        for (Window wind : visibleWindows) {
106            wind.setVisible(true);
107        }
108
109        // Free F10 key to allow it to be used by plugins, even after full screen (see #7502)
110        frame.getJMenuBar().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0), "none");
111    }
112}