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