1/*
2 * Copyright (c) 1996, 2016, 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 */
25package sun.awt.windows;
26
27import java.awt.*;
28import java.awt.peer.*;
29
30import sun.awt.AWTAccessor;
31
32final class WPopupMenuPeer extends WMenuPeer implements PopupMenuPeer {
33    // We can't use target.getParent() for TrayIcon popup
34    // because this method should return null for the TrayIcon
35    // popup regardless of that whether it has parent or not.
36
37    WPopupMenuPeer(PopupMenu target) {
38        this.target = target;
39        MenuContainer parent = null;
40
41        // We can't use target.getParent() for TrayIcon popup
42        // because this method should return null for the TrayIcon
43        // popup regardless of that whether it has parent or not.
44        boolean isTrayIconPopup = AWTAccessor.getPopupMenuAccessor().isTrayIconPopup(target);
45        if (isTrayIconPopup) {
46            parent = AWTAccessor.getMenuComponentAccessor().getParent(target);
47        } else {
48            parent = target.getParent();
49        }
50
51        if (parent instanceof Component) {
52            WComponentPeer parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
53            if (parentPeer == null) {
54                // because the menu isn't a component (sigh) we first have to wait
55                // for a failure to map the peer which should only happen for a
56                // lightweight container, then find the actual native parent from
57                // that component.
58                parent = WToolkit.getNativeContainer((Component)parent);
59                parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
60            }
61            parentPeer.addChildPeer(this);
62            createMenu(parentPeer);
63            // fix for 5088782: check if menu object is created successfully
64            checkMenuCreation();
65        } else {
66            throw new IllegalArgumentException(
67                "illegal popup menu container class");
68        }
69    }
70
71    private native void createMenu(WComponentPeer parent);
72
73    @SuppressWarnings("deprecation")
74    public void show(Event e) {
75        Component origin = (Component)e.target;
76        WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin);
77        if (peer == null) {
78            // A failure to map the peer should only happen for a
79            // lightweight component, then find the actual native parent from
80            // that component.  The event coorinates are going to have to be
81            // remapped as well.
82            Component nativeOrigin = WToolkit.getNativeContainer(origin);
83            e.target = nativeOrigin;
84
85            // remove the event coordinates
86            for (Component c = origin; c != nativeOrigin; c = c.getParent()) {
87                Point p = c.getLocation();
88                e.x += p.x;
89                e.y += p.y;
90            }
91        }
92        _show(e);
93    }
94
95    /*
96     * This overloaded method is for TrayIcon.
97     * Its popup has special parent.
98     */
99    void show(Component origin, Point p) {
100        WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin);
101        @SuppressWarnings("deprecation")
102        Event e = new Event(origin, 0, Event.MOUSE_DOWN, p.x, p.y, 0, 0);
103        if (peer == null) {
104            Component nativeOrigin = WToolkit.getNativeContainer(origin);
105            e.target = nativeOrigin;
106        }
107        e.x = p.x;
108        e.y = p.y;
109        _show(e);
110    }
111
112    @SuppressWarnings("deprecation")
113    private native void _show(Event e);
114}
115