| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Eclipse Public License, Version 1.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.eclipse.org/org/documents/epl-v10.php |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.menubar; |
| |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| |
| |
| /** |
| * On Mac, {@link MenuBarEnhancer#setupMenu} plugs a listener on the About and the |
| * Preferences menu items of the standard "application" menu in the menu bar. |
| * On Windows or Linux, it adds relevant items to a given {@link Menu} linked to |
| * the same listeners. |
| */ |
| public final class MenuBarEnhancer { |
| |
| private MenuBarEnhancer() { |
| } |
| |
| /** |
| * Creates an instance of {@link IMenuBarEnhancer} specific to the current platform |
| * and invoke its {@link IMenuBarEnhancer#setupMenu} to updates the menu bar. |
| * <p/> |
| * Depending on the platform, this will either hook into the existing About menu item |
| * and a Preferences or Options menu item or add new ones to the given {@code swtMenu}. |
| * Depending on the platform, the menu items might be decorated with the |
| * given {@code appName}. |
| * <p/> |
| * Potential errors are reported through {@link IMenuBarCallback}. |
| * |
| * @param appName Name used for the About menu item and similar. Must not be null. |
| * @param swtMenu For non-mac platform this is the menu where the "About" and |
| * the "Options" menu items are created. Typically the menu might be |
| * called "Tools". Must not be null. |
| * @param callbacks Callbacks called when "About" and "Preferences" menu items are invoked. |
| * Must not be null. |
| * @return A actual {@link IMenuBarEnhancer} implementation. Never null. |
| * This is currently not of any use for the caller but is left in case |
| * we want to expand the functionality later. |
| */ |
| public static IMenuBarEnhancer setupMenu( |
| String appName, |
| final Menu swtMenu, |
| IMenuBarCallback callbacks) { |
| |
| IMenuBarEnhancer enhancer = getEnhancer(callbacks); |
| |
| // Default implementation for generic platforms |
| if (enhancer == null) { |
| enhancer = new IMenuBarEnhancer() { |
| |
| public MenuBarMode getMenuBarMode() { |
| return MenuBarMode.GENERIC; |
| } |
| |
| public void setupMenu( |
| String appName, |
| Display display, |
| final IMenuBarCallback callbacks) { |
| if (swtMenu.getItemCount() > 0) { |
| new MenuItem(swtMenu, SWT.SEPARATOR); |
| } |
| |
| // Note: we use "Preferences" on Mac and "Options" on Windows/Linux. |
| final MenuItem pref = new MenuItem(swtMenu, SWT.NONE); |
| pref.setText("&Options..."); |
| |
| final MenuItem about = new MenuItem(swtMenu, SWT.NONE); |
| about.setText("&About..."); |
| |
| pref.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| try { |
| pref.setEnabled(false); |
| callbacks.onPreferencesMenuSelected(); |
| super.widgetSelected(e); |
| } finally { |
| pref.setEnabled(true); |
| } |
| } |
| }); |
| |
| about.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| try { |
| about.setEnabled(false); |
| callbacks.onAboutMenuSelected(); |
| super.widgetSelected(e); |
| } finally { |
| about.setEnabled(true); |
| } |
| } |
| }); |
| } |
| }; |
| } |
| |
| enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks); |
| return enhancer; |
| } |
| |
| |
| public static IMenuBarEnhancer setupMenuManager( |
| String appName, |
| Display display, |
| final IMenuManager menuManager, |
| final IAction aboutAction, |
| final IAction preferencesAction, |
| final IAction quitAction) { |
| |
| IMenuBarCallback callbacks = new IMenuBarCallback() { |
| public void printError(String format, Object... args) { |
| System.err.println(String.format(format, args)); |
| } |
| |
| public void onPreferencesMenuSelected() { |
| if (preferencesAction != null) { |
| preferencesAction.run(); |
| } |
| } |
| |
| public void onAboutMenuSelected() { |
| if (aboutAction != null) { |
| aboutAction.run(); |
| } |
| } |
| }; |
| |
| IMenuBarEnhancer enhancer = getEnhancer(callbacks); |
| |
| // Default implementation for generic platforms |
| if (enhancer == null) { |
| enhancer = new IMenuBarEnhancer() { |
| |
| public MenuBarMode getMenuBarMode() { |
| return MenuBarMode.GENERIC; |
| } |
| |
| public void setupMenu( |
| String appName, |
| Display display, |
| final IMenuBarCallback callbacks) { |
| if (!menuManager.isEmpty()) { |
| menuManager.add(new Separator()); |
| } |
| |
| if (aboutAction != null) { |
| menuManager.add(aboutAction); |
| } |
| if (preferencesAction != null) { |
| menuManager.add(preferencesAction); |
| } |
| if (quitAction != null) { |
| if (aboutAction != null || preferencesAction != null) { |
| menuManager.add(new Separator()); |
| } |
| menuManager.add(quitAction); |
| } |
| } |
| }; |
| } |
| |
| enhancer.setupMenu(appName, display, callbacks); |
| return enhancer; |
| } |
| |
| private static IMenuBarEnhancer getEnhancer(IMenuBarCallback callbacks) { |
| IMenuBarEnhancer enhancer = null; |
| String p = SWT.getPlatform(); |
| String className = null; |
| if ("cocoa".equals(p)) { //$NON-NLS-1$ |
| className = "com.android.menubar.internal.MenuBarEnhancerCocoa"; //$NON-NLS-1$ |
| } |
| |
| if (System.getenv("DEBUG_SWTMENUBAR") != null) { |
| callbacks.printError("DEBUG SwtMenuBar: SWT=%1$s, class=%2$s", p, className); |
| } |
| |
| if (className != null) { |
| try { |
| Class<?> clazz = Class.forName(className); |
| enhancer = (IMenuBarEnhancer) clazz.newInstance(); |
| } catch (Exception e) { |
| // Log an error and fallback on the default implementation. |
| callbacks.printError( |
| "Failed to instantiate %1$s: %2$s", //$NON-NLS-1$ |
| className, |
| e.toString()); |
| } |
| } |
| return enhancer; |
| } |
| } |