blob: 396e1dd8efed5d09485e0f8a062d3709a5fa5aa6 [file] [log] [blame]
package org.eclipse.swt.widgets;
/*
* Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
* This file is made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*/
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.internal.carbon.*;
public class Menu extends Widget {
int handle;
short id, lastIndex;
int x, y;
boolean hasLocation;
MenuItem cascade, defaultItem;
Decorations parent;
public Menu (Control parent) {
this (checkNull (parent).getShell (), SWT.POP_UP);
}
public Menu (Decorations parent, int style) {
super (parent, checkStyle (style));
this.parent = parent;
createWidget ();
}
public Menu (Menu parentMenu) {
this (checkNull (parentMenu).parent, SWT.DROP_DOWN);
}
public Menu (MenuItem parentItem) {
this (checkNull (parentItem).parent);
}
static Control checkNull (Control control) {
if (control == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
return control;
}
static Menu checkNull (Menu menu) {
if (menu == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
return menu;
}
static MenuItem checkNull (MenuItem item) {
if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
return item;
}
static int checkStyle (int style) {
return checkBits (style, SWT.POP_UP, SWT.BAR, SWT.DROP_DOWN, 0, 0, 0);
}
public void _setVisible (boolean visible) {
if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
if (!visible) return;
int left = x, top = y;
if (!hasLocation) {
org.eclipse.swt.internal.carbon.Point where = new org.eclipse.swt.internal.carbon.Point ();
OS.GetGlobalMouse (where);
left = where.h; top = where.v;
}
int index = defaultItem != null ? indexOf (defaultItem) + 1 : lastIndex;
int result = OS.PopUpMenuSelect (handle, (short)top, (short)left, (short)(index));
lastIndex = OS.LoWord (result);
}
public void addHelpListener (HelpListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Help, typedListener);
}
public void addMenuListener (MenuListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Hide,typedListener);
addListener (SWT.Show,typedListener);
}
void createHandle () {
Display display = getDisplay ();
int menuProc = display.menuProc;
display.addMenu (this);
int outMenuRef [] = new int [1];
OS.CreateNewMenu (id, 0, outMenuRef);
if (outMenuRef [0] == 0) {
display.removeMenu (this);
error (SWT.ERROR_NO_HANDLES);
}
handle = outMenuRef [0];
}
void createItem (MenuItem item, int index) {
checkWidget ();
int count = OS.CountMenuItems (handle);
if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE);
Display display = getDisplay ();
display.addMenuItem (item);
int attributes = 0;
if ((item.style & SWT.SEPARATOR) != 0) attributes = OS.kMenuItemAttrSeparator;
int result = OS.InsertMenuItemTextWithCFString (handle, 0, (short) index, attributes, item.id);
if (result != OS.noErr) {
display.removeMenuItem (item);
error (SWT.ERROR_ITEM_NOT_ADDED);
}
if ((style & SWT.BAR) != 0) {
// Display display = getDisplay ();
// short menuID = display.nextMenuId ();
// int outMenuRef [] = new int [1];
// if (OS.CreateNewMenu (menuID, 0, outMenuRef) != OS.noErr) {
// error (SWT.ERROR_NO_HANDLES);
// }
// OS.SetMenuItemHierarchicalMenu (handle, (short) (index + 1), outMenuRef [0]);
}
}
void destroyItem (MenuItem item) {
short [] outIndex = new short [1];
if (OS.GetIndMenuItemWithCommandID (handle, item.id, 1, null, outIndex) != OS.noErr) {
error (SWT.ERROR_ITEM_NOT_REMOVED);
}
if ((style & SWT.BAR) != 0) {
// int [] outMenuRef = new int [1];
// OS.GetMenuItemHierarchicalMenu (handle, outIndex [0], outMenuRef);
// if (outMenuRef [0] != 0) {
// OS.DeleteMenu (OS.GetMenuID (outMenuRef [0]));
// OS.DisposeMenu (outMenuRef [0]);
// }
}
OS.DeleteMenuItem (handle, outIndex [0]);
}
void destroyWidget () {
int theMenu = handle;
releaseHandle ();
if (theMenu != 0) {
OS.DeleteMenu (OS.GetMenuID (theMenu));
OS.DisposeMenu (theMenu);
}
}
public MenuItem getDefaultItem () {
checkWidget();
return defaultItem;
}
public Display getDisplay () {
Decorations parent = this.parent;
if (parent == null) error (SWT.ERROR_WIDGET_DISPOSED);
return parent.getDisplay ();
}
public boolean getEnabled () {
checkWidget();
return (state & DISABLED) == 0;
}
public MenuItem getItem (int index) {
checkWidget ();
int [] outCommandID= new int [1];
if (OS.GetMenuItemCommandID (handle, (short)(index+1), outCommandID) != OS.noErr) {
error (SWT.ERROR_INVALID_RANGE);
}
Display display = getDisplay ();
return display.findMenuItem (outCommandID[0]);
}
public int getItemCount () {
checkWidget ();
return OS.CountMenuItems (handle);
}
public MenuItem [] getItems () {
checkWidget ();
Display display = getDisplay ();
int length = OS.CountMenuItems (handle);
MenuItem [] items = new MenuItem [length];
int [] outCommandID= new int [1];
for (int i=0; i<items.length; i++) {
if (OS.GetMenuItemCommandID (handle, (short)(i+1), outCommandID) != OS.noErr) {
error (SWT.ERROR_CANNOT_GET_ITEM);
}
items [i] = display.findMenuItem (outCommandID [0]);
}
return items;
}
String getNameText () {
String result = "";
MenuItem [] items = getItems ();
int length = items.length;
if (length > 0) {
for (int i=0; i<length-1; i++) {
result = result + items [i].getNameText() + ", ";
}
result = result + items [length-1].getNameText ();
}
return result;
}
public Decorations getParent () {
checkWidget ();
return parent;
}
public MenuItem getParentItem () {
checkWidget ();
return cascade;
}
public Menu getParentMenu () {
checkWidget ();
if (cascade != null) return cascade.parent;
return null;
}
public Shell getShell () {
checkWidget ();
return parent.getShell ();
}
public boolean getVisible () {
checkWidget ();
if ((style & SWT.BAR) != 0) {
return this == parent.menuShell ().menuBar;
}
if ((style & SWT.POP_UP) != 0) {
Display display = getDisplay ();
Menu [] popups = display.popups;
if (popups == null) return false;
for (int i=0; i<popups.length; i++) {
if (popups [i] == this) return true;
}
}
MenuTrackingData outData = new MenuTrackingData ();
return OS.GetMenuTrackingData (handle, outData) == OS.noErr;
}
void hookEvents () {
super.hookEvents ();
Display display = getDisplay ();
int menuProc = display.menuProc;
int [] mask = new int [] {
OS.kEventClassMenu, OS.kEventMenuOpening,
OS.kEventClassMenu, OS.kEventMenuClosed,
};
int menuTarget = OS.GetMenuEventTarget (handle);
OS.InstallEventHandler (menuTarget, menuProc, mask.length / 2, mask, 0, null);
}
int kEventMenuClosed (int nextHandler, int theEvent, int userData) {
sendEvent (SWT.Hide);
return OS.eventNotHandledErr;
}
int kEventMenuOpening (int nextHandler, int theEvent, int userData) {
sendEvent (SWT.Show);
return OS.eventNotHandledErr;
}
public int indexOf (MenuItem item) {
checkWidget ();
if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
int [] outMenu = new int [1];
short [] outIndex = new short [1];
if (OS.GetIndMenuItemWithCommandID (handle, item.id, 1, outMenu, outIndex) == OS.noErr) {
return handle == outMenu [0] ? outIndex [0] - 1 : 0;
}
return -1;
}
public boolean isEnabled () {
checkWidget ();
Menu parentMenu = getParentMenu ();
if (parentMenu == null) return getEnabled ();
return getEnabled () && parentMenu.isEnabled ();
}
public boolean isVisible () {
checkWidget ();
return getVisible ();
}
void releaseChild () {
super.releaseChild ();
if (cascade != null) cascade.setMenu (null);
if ((style & SWT.BAR) != 0 && this == parent.menuBar) {
parent.setMenuBar (null);
}
}
void releaseWidget () {
MenuItem [] items = getItems ();
for (int i=0; i<items.length; i++) {
MenuItem item = items [i];
if (!item.isDisposed ()) item.releaseResources ();
}
super.releaseWidget ();
Display display = getDisplay ();
display.removeMenu (this);
parent = null;
cascade = null;
}
public void removeHelpListener (HelpListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Help, listener);
}
public void removeMenuListener (MenuListener listener) {
checkWidget ();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Hide, listener);
eventTable.unhook (SWT.Show, listener);
}
public void setDefaultItem (MenuItem item) {
checkWidget();
if (item != null && item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
defaultItem = item;
}
public void setEnabled (boolean enabled) {
checkWidget();
if (enabled) {
state &= ~DISABLED;
OS.EnableMenuItem (handle, (short)0);
} else {
state |= DISABLED;
OS.DisableMenuItem (handle, (short)0);
}
}
public void setLocation (int x, int y) {
checkWidget ();
this.x = x;
this.y = y;
hasLocation = true;
}
public void setVisible (boolean visible) {
checkWidget ();
if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
Display display = getDisplay ();
if (visible) {
display.addPopup (this);
} else {
display.removePopup (this);
_setVisible (false);
}
}
}