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