1/*
2 * Copyright (c) 2011, 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 */
25
26package sun.lwawt.macosx;
27
28import java.awt.Menu;
29import java.awt.MenuBar;
30import java.awt.MenuItem;
31import java.awt.peer.MenuItemPeer;
32import java.awt.peer.MenuPeer;
33
34public class CMenu extends CMenuItem implements MenuPeer {
35
36    public CMenu(Menu target) {
37        super(target);
38    }
39
40    // This way we avoiding invocation of the setters twice
41    @Override
42    protected final void initialize(MenuItem target) {
43        setLabel(target.getLabel());
44        setEnabled(target.isEnabled());
45    }
46
47    @Override
48    public final void setEnabled(final boolean b) {
49        super.setEnabled(b);
50        final Menu target = (Menu) getTarget();
51        final int count = target.getItemCount();
52        for (int i = 0; i < count; ++i) {
53            MenuItem item = target.getItem(i);
54            MenuItemPeer p = (MenuItemPeer) LWCToolkit.targetToPeer(item);
55            if (p != null) {
56                p.setEnabled(b && item.isEnabled());
57            }
58        }
59    }
60
61    @Override
62    long createModel() {
63        CMenuComponent parent = (CMenuComponent)
64            LWCToolkit.targetToPeer(getTarget().getParent());
65
66        if (parent instanceof CMenu) {
67            return parent.executeGet(this::nativeCreateSubMenu);
68        }
69        if (parent instanceof CMenuBar) {
70            MenuBar parentContainer = (MenuBar)getTarget().getParent();
71            boolean isHelpMenu = parentContainer.getHelpMenu() == getTarget();
72            int insertionLocation = ((CMenuBar)parent).getNextInsertionIndex();
73            return parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu,
74                                                             insertionLocation));
75        }
76        throw new InternalError("Parent must be CMenu or CMenuBar");
77    }
78
79    @Override
80    public final void addItem(MenuItem item) {
81        // Nothing to do here -- we added it when we created the
82        // menu item's peer.
83    }
84
85    @Override
86    public final void delItem(final int index) {
87        execute(ptr -> nativeDeleteItem(ptr, index));
88    }
89
90    @Override
91    public final void setLabel(final String label) {
92        execute(ptr->nativeSetMenuTitle(ptr, label));
93        super.setLabel(label);
94    }
95
96    // Note that addSeparator is never called directly from java.awt.Menu,
97    // though it is required in the MenuPeer interface.
98    @Override
99    public final void addSeparator() {
100        execute(this::nativeAddSeparator);
101    }
102
103    // Used by ScreenMenuBar to get to the native menu for event handling.
104    public final long getNativeMenu() {
105        return executeGet(this::nativeGetNSMenu);
106    }
107
108    private native long nativeCreateMenu(long parentMenuPtr,
109                                         boolean isHelpMenu,
110                                         int insertionLocation);
111    private native long nativeCreateSubMenu(long parentMenuPtr);
112    private native void nativeSetMenuTitle(long menuPtr, String title);
113    private native void nativeAddSeparator(long menuPtr);
114    private native void nativeDeleteItem(long menuPtr, int index);
115
116    // Returns a retained NSMenu object! We have to explicitly
117    // release at some point!
118    private native long nativeGetNSMenu(long menuPtr);
119}
120