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