• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.menubar;
18 
19 import org.eclipse.jface.action.IAction;
20 import org.eclipse.jface.action.IMenuManager;
21 import org.eclipse.jface.action.Separator;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.widgets.Display;
26 import org.eclipse.swt.widgets.Menu;
27 import org.eclipse.swt.widgets.MenuItem;
28 
29 
30 /**
31  * On Mac, {@link MenuBarEnhancer#setupMenu} plugs a listener on the About and the
32  * Preferences menu items of the standard "application" menu in the menu bar.
33  * On Windows or Linux, it adds relevant items to a given {@link Menu} linked to
34  * the same listeners.
35  */
36 public final class MenuBarEnhancer {
37 
MenuBarEnhancer()38     private MenuBarEnhancer() {
39     }
40 
41     /**
42      * Creates an instance of {@link IMenuBarEnhancer} specific to the current platform
43      * and invoke its {@link IMenuBarEnhancer#setupMenu} to updates the menu bar.
44      * <p/>
45      * Depending on the platform, this will either hook into the existing About menu item
46      * and a Preferences or Options menu item or add new ones to the given {@code swtMenu}.
47      * Depending on the platform, the menu items might be decorated with the
48      * given {@code appName}.
49      * <p/>
50      * Potential errors are reported through {@link IMenuBarCallback}.
51      *
52      * @param appName Name used for the About menu item and similar. Must not be null.
53      * @param swtMenu For non-mac platform this is the menu where the "About" and
54      *          the "Options" menu items are created. Typically the menu might be
55      *          called "Tools". Must not be null.
56      * @param callbacks Callbacks called when "About" and "Preferences" menu items are invoked.
57      *          Must not be null.
58      * @return A actual {@link IMenuBarEnhancer} implementation. Never null.
59      *          This is currently not of any use for the caller but is left in case
60      *          we want to expand the functionality later.
61      */
setupMenu( String appName, final Menu swtMenu, IMenuBarCallback callbacks)62     public static IMenuBarEnhancer setupMenu(
63             String appName,
64             final Menu swtMenu,
65             IMenuBarCallback callbacks) {
66 
67         IMenuBarEnhancer enhancer = getEnhancer(callbacks);
68 
69         // Default implementation for generic platforms
70         if (enhancer == null) {
71             enhancer = new IMenuBarEnhancer() {
72 
73                 public MenuBarMode getMenuBarMode() {
74                     return MenuBarMode.GENERIC;
75                 }
76 
77                 public void setupMenu(
78                         String appName,
79                         Display display,
80                         final IMenuBarCallback callbacks) {
81                     if (swtMenu.getItemCount() > 0) {
82                         new MenuItem(swtMenu, SWT.SEPARATOR);
83                     }
84 
85                     // Note: we use "Preferences" on Mac and "Options" on Windows/Linux.
86                     final MenuItem pref = new MenuItem(swtMenu, SWT.NONE);
87                     pref.setText("&Options...");
88 
89                     final MenuItem about = new MenuItem(swtMenu, SWT.NONE);
90                     about.setText("&About...");
91 
92                     pref.addSelectionListener(new SelectionAdapter() {
93                         @Override
94                         public void widgetSelected(SelectionEvent e) {
95                             try {
96                                 pref.setEnabled(false);
97                                 callbacks.onPreferencesMenuSelected();
98                                 super.widgetSelected(e);
99                             } finally {
100                                 pref.setEnabled(true);
101                             }
102                         }
103                     });
104 
105                     about.addSelectionListener(new SelectionAdapter() {
106                         @Override
107                         public void widgetSelected(SelectionEvent e) {
108                             try {
109                                 about.setEnabled(false);
110                                 callbacks.onAboutMenuSelected();
111                                 super.widgetSelected(e);
112                             } finally {
113                                 about.setEnabled(true);
114                             }
115                         }
116                     });
117                 }
118             };
119         }
120 
121         enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks);
122         return enhancer;
123     }
124 
125 
setupMenuManager( String appName, Display display, final IMenuManager menuManager, final IAction aboutAction, final IAction preferencesAction, final IAction quitAction)126     public static IMenuBarEnhancer setupMenuManager(
127             String appName,
128             Display display,
129             final IMenuManager menuManager,
130             final IAction aboutAction,
131             final IAction preferencesAction,
132             final IAction quitAction) {
133 
134         IMenuBarCallback callbacks = new IMenuBarCallback() {
135             public void printError(String format, Object... args) {
136                 System.err.println(String.format(format, args));
137             }
138 
139             public void onPreferencesMenuSelected() {
140                 if (preferencesAction != null) {
141                     preferencesAction.run();
142                 }
143             }
144 
145             public void onAboutMenuSelected() {
146                 if (aboutAction != null) {
147                     aboutAction.run();
148                 }
149             }
150         };
151 
152         IMenuBarEnhancer enhancer = getEnhancer(callbacks);
153 
154         // Default implementation for generic platforms
155         if (enhancer == null) {
156             enhancer = new IMenuBarEnhancer() {
157 
158                 public MenuBarMode getMenuBarMode() {
159                     return MenuBarMode.GENERIC;
160                 }
161 
162                 public void setupMenu(
163                         String appName,
164                         Display display,
165                         final IMenuBarCallback callbacks) {
166                     if (!menuManager.isEmpty()) {
167                         menuManager.add(new Separator());
168                     }
169 
170                     if (aboutAction != null) {
171                         menuManager.add(aboutAction);
172                     }
173                     if (preferencesAction != null) {
174                         menuManager.add(preferencesAction);
175                     }
176                     if (quitAction != null) {
177                         if (aboutAction != null || preferencesAction != null) {
178                             menuManager.add(new Separator());
179                         }
180                         menuManager.add(quitAction);
181                     }
182                 }
183             };
184         }
185 
186         enhancer.setupMenu(appName, display, callbacks);
187         return enhancer;
188     }
189 
getEnhancer(IMenuBarCallback callbacks)190     private static IMenuBarEnhancer getEnhancer(IMenuBarCallback callbacks) {
191         IMenuBarEnhancer enhancer = null;
192         String p = SWT.getPlatform();
193         String className = null;
194         if ("cocoa".equals(p)) {                                                  //$NON-NLS-1$
195             className = "com.android.menubar.internal.MenuBarEnhancerCocoa";      //$NON-NLS-1$
196         }
197 
198         if (System.getenv("DEBUG_SWTMENUBAR") != null) {
199             callbacks.printError("DEBUG SwtMenuBar: SWT=%1$s, class=%2$s", p, className);
200         }
201 
202         if (className != null) {
203             try {
204                 Class<?> clazz = Class.forName(className);
205                 enhancer = (IMenuBarEnhancer) clazz.newInstance();
206             } catch (Exception e) {
207                 // Log an error and fallback on the default implementation.
208                 callbacks.printError(
209                         "Failed to instantiate %1$s: %2$s",                       //$NON-NLS-1$
210                         className,
211                         e.toString());
212             }
213         }
214         return enhancer;
215     }
216 }
217