1 /* 2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.webkit.theme; 27 28 import com.sun.javafx.logging.PlatformLogger; 29 import com.sun.javafx.logging.PlatformLogger.Level; 30 31 import javafx.scene.control.ContextMenu; 32 import javafx.scene.control.MenuItem; 33 import javafx.scene.web.WebView; 34 35 import com.sun.webkit.Invoker; 36 import com.sun.webkit.graphics.WCFont; 37 import com.sun.webkit.graphics.WCPoint; 38 import com.sun.webkit.WebPage; 39 import com.sun.webkit.WebPageClient; 40 41 public final class PopupMenuImpl extends com.sun.webkit.PopupMenu { 42 43 private final static PlatformLogger log = PlatformLogger.getLogger(PopupMenuImpl.class.getName()); 44 45 private final ContextMenu popupMenu; 46 47 public PopupMenuImpl() { 48 popupMenu = new ContextMenu(); 49 50 popupMenu.setOnHidden(t1 -> { 51 log.finer("onHidden"); 52 // Postpone notification. This is to let webkit 53 // to process a mouse event first (in case the 54 // event is the trigger of the closing). Otherwise, 55 // if this is a click in a drop down list, webkit 56 // will reopen the popup assuming it is hidden. 57 Invoker.getInvoker().postOnEventThread(() -> { 58 log.finer("onHidden: notifying"); 59 notifyPopupClosed(); 60 }); 61 }); 62 popupMenu.setOnAction(t -> { 63 MenuItem item = (MenuItem) t.getTarget(); 64 log.fine("onAction: item={0}", item); 65 notifySelectionCommited(popupMenu.getItems().indexOf(item)); 66 }); 67 } 68 69 @Override protected void show(WebPage page, final int x, final int y, final int width) { 70 if (log.isLoggable(Level.FINE)) { 71 log.fine("show at [{0}, {1}], width={2}", new Object[] {x, y, width}); 72 } 73 // TODO: doesn't work 74 popupMenu.setPrefWidth(width); 75 popupMenu.setPrefHeight(popupMenu.getHeight()); 76 doShow(popupMenu, page, x, y); 77 } 78 79 @Override protected void hide() { 80 log.fine("hiding"); 81 popupMenu.hide(); 82 } 83 84 @Override protected void appendItem(String itemText, boolean isLabel, 85 boolean isSeparator, boolean isEnabled, 86 int bgColor, int fgColor, WCFont font) 87 { 88 if (log.isLoggable(Level.FINEST)) { 89 log.finest("itemText={0}, isLabel={1}, isSeparator={2}, isEnabled={3}, " + 90 "bgColor={4}, fgColor={5}, font={6}", new Object[] {itemText, isLabel, 91 isSeparator, isEnabled, bgColor, fgColor, font}); 92 } 93 MenuItem item; 94 95 if (isSeparator) { 96 item = new ContextMenuImpl.SeparatorImpl(null); 97 } else { 98 item = new MenuItem(itemText); 99 item.setDisable(!isEnabled); 100 // TODO: set the rest of properties 101 } 102 103 item.setMnemonicParsing(false); 104 popupMenu.getItems().add(item); 105 } 106 107 @Override protected void setSelectedItem(int index) { 108 log.finest("index={0}", index); 109 // TODO requestFocus is not supported currently 110 //popupMenu.getItems().get(index).requestFocus(); 111 } 112 113 static void doShow(final ContextMenu popup, WebPage page, int anchorX, int anchorY) { 114 WebPageClient<WebView> client = page.getPageClient(); 115 assert (client != null); 116 WCPoint pt = client.windowToScreen(new WCPoint(anchorX, anchorY)); 117 popup.show(client.getContainer().getScene().getWindow(), pt.getX(), pt.getY()); 118 } 119 }