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 }