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