Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.widgets;
import java.util.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.gtk3.*;
import org.eclipse.swt.internal.gtk4.*;
/**
* Instances of this class are user interface objects that contain
* menu items.
*
*
Styles:
*
BAR, DROP_DOWN, POP_UP, NO_RADIO_GROUP
*
LEFT_TO_RIGHT, RIGHT_TO_LEFT
*
Events:
*
Help, Hide, Show
*
*
* Note: Only one of BAR, DROP_DOWN and POP_UP may be specified.
* Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
*
* IMPORTANT: This class is not intended to be subclassed.
*
*
* @see Menu snippets
* @see SWT Example: ControlExample
* @see Sample code and further information
* @noextend This class is not intended to be subclassed by clients.
*/
public class Menu extends Widget {
int x, y;
boolean hasLocation;
MenuItem cascade, selectedItem;
Decorations parent;
ImageList imageList;
int poppedUpCount;
long menuHandle;
/** GTK4 only fields */
long modelHandle, actionGroup, shortcutController;
class Section {
LinkedList or SWT.RIGHT_TO_LEFT.
*
* @return the orientation style
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 3.7
*/
public int getOrientation () {
checkWidget();
return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
}
/**
* Returns the receiver's parent, which must be a Decorations.
*
* @return the receiver's parent
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public Decorations getParent () {
checkWidget();
return parent;
}
/**
* Returns the receiver's parent item, which must be a
* MenuItem or null when the receiver is a
* root.
*
* @return the receiver's parent item
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public MenuItem getParentItem () {
checkWidget();
return cascade;
}
/**
* Returns the receiver's parent item, which must be a
* Menu or null when the receiver is a
* root.
*
* @return the receiver's parent item
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public Menu getParentMenu () {
checkWidget();
if (cascade == null) return null;
return cascade.getParent ();
}
/**
* Returns the receiver's shell. For all controls other than
* shells, this simply returns the control's nearest ancestor
* shell. Shells return themselves, even if they are children
* of other shells. Returns null if receiver or its ancestor
* is the application menubar.
*
* @return the receiver's shell or null
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #getParent
*/
public Shell getShell () {
checkWidget();
return parent.getShell ();
}
/**
* Returns true if the receiver is visible, and
* false otherwise.
*
* If one of the receiver's ancestors is not visible or some
* other condition makes the receiver not visible, this method
* may still indicate that it is considered visible even though
* it may not actually be showing.
*
*
* @return the receiver's visibility state
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getVisible () {
checkWidget();
if ((style & SWT.POP_UP) != 0) {
Menu [] popups = display.popups;
if (popups != null) {
for (int i=0; i
*
ERROR_NULL_ARGUMENT - if the item is null
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int indexOf (MenuItem item) {
checkWidget();
if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
MenuItem [] items = getItems ();
for (int i=0; itrue if the receiver is enabled and all
* of the receiver's ancestors are enabled, and false
* otherwise. A disabled menu is typically not selectable from the
* user interface and draws with an inactive or "grayed" look.
*
* @return the receiver's enabled state
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #getEnabled
*/
public boolean isEnabled () {
checkWidget();
Menu parentMenu = getParentMenu ();
if (parentMenu == null) {
return getEnabled () && parent.isEnabled ();
}
return getEnabled () && parentMenu.isEnabled ();
}
/**
* Returns true if the receiver is visible and all
* of the receiver's ancestors are visible and false
* otherwise.
*
* @return the receiver's visibility state
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see MenuListener
* @see #addMenuListener
*/
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);
}
void removeAccelerators (long accelGroup) {
MenuItem [] items = getItems ();
for (int i = 0; i < items.length; i++) {
MenuItem item = items[i];
item.removeAccelerators (accelGroup);
}
}
/**
* Removes the listener from the collection of listeners who will
* be notified when the help events are generated for the control.
*
* @param listener the listener which should no longer be notified
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see HelpListener
* @see #addHelpListener
*/
public void removeHelpListener (HelpListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Help, listener);
}
@Override
void reskinChildren (int flags) {
MenuItem [] items = getItems ();
for (int i=0; inull.
*
* @param item the default menu item or null
*
* @exception IllegalArgumentException
*
ERROR_INVALID_ARGUMENT - if the menu item has been disposed
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setDefaultItem (MenuItem item) {
checkWidget();
}
/**
* Enables the receiver if the argument is true,
* and disables it otherwise. A disabled menu is typically
* not selectable from the user interface and draws with an
* inactive or "grayed" look.
*
* @param enabled the new enabled state
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setEnabled(boolean enabled) {
checkWidget();
if (GTK.GTK4) {
if ((style & SWT.DROP_DOWN) != 0) {
/*
* In GTK4, SWT.DROP_DOWN acts solely as a wrapper
* of the GMenu menu model. See getEnabled for more info.
*/
return;
} else {
GTK.gtk_widget_set_sensitive(handle, enabled);
}
} else {
GTK.gtk_widget_set_sensitive(handle, enabled);
}
}
/**
* Sets the location of the receiver, which must be a popup,
* to the point specified by the arguments which are relative
* to the display.
*
* Note that this is different from most widgets where the
* location of the widget is relative to the parent.
*
* Also note that the actual location of the menu is dependent
* on platform specific behavior. For example: on Linux with
* Wayland this operation is a hint due to lack of global
* coordinates.
*
*
* @param x the new x coordinate for the receiver
* @param y the new y coordinate for the receiver
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setLocation (int x, int y) {
checkWidget ();
setLocation (new Point (x, y));
}
void setLocationInPixels (int x, int y) {
checkWidget();
if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
this.x = x;
this.y = y;
hasLocation = true;
}
/**
* Sets the location of the receiver, which must be a popup,
* to the point specified by the argument which is relative
* to the display.
*
* Note that this is different from most widgets where the
* location of the widget is relative to the parent.
*
* Note that the platform window manager ultimately has control
* over the location of popup menus.
*
*
* @param location the new location for the receiver
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the point is null
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1
*/
public void setLocation (Point location) {
checkWidget ();
setLocationInPixels (DPIUtil.autoScaleUp (location));
}
void setLocationInPixels (Point location) {
checkWidget();
if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
setLocationInPixels (location.x, location.y);
}
/**
* Sets the orientation of the receiver, which must be one
* of the constants SWT.LEFT_TO_RIGHT or SWT.RIGHT_TO_LEFT.
*
* @param orientation new orientation style
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 3.7
*/
public void setOrientation (int orientation) {
checkWidget ();
if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
_setOrientation (orientation);
}
void _setOrientation (int orientation) {
int flags = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT;
if ((orientation & flags) == 0 || (orientation & flags) == flags) return;
style &= ~flags;
style |= orientation & flags;
setOrientation (false);
}
@Override
void setOrientation (boolean create) {
if ((style & SWT.RIGHT_TO_LEFT) != 0 || !create) {
int dir = (style & SWT.RIGHT_TO_LEFT) != 0 ? GTK.GTK_TEXT_DIR_RTL : GTK.GTK_TEXT_DIR_LTR;
if (handle != 0) GTK.gtk_widget_set_direction (handle, dir);
MenuItem [] items = getItems ();
for (int i = 0; i < items.length; i++) {
items [i].setOrientation (create);
}
}
}
/**
* Lack of absolute coordinates make Wayland event windows inaccurate.
* Currently the best approach is to the use the GdkWindow of the mouse
* pointer. See bug 530059 and 532074.
*
* @param eventPtr a pointer to the GdkEvent
*/
void adjustParentWindowWayland (long eventPtr) {
if (OS.isWayland()) {
long display = GDK.gdk_display_get_default ();
long pointer = GDK.gdk_get_pointer(display);
long deviceResource;
if (GTK.GTK4) {
deviceResource = GDK.gdk_device_get_surface_at_position(pointer, null, null);
} else {
deviceResource = GDK.gdk_device_get_window_at_position(pointer, null, null);
}
OS.g_object_ref(deviceResource);
int eventType = GDK.gdk_event_get_event_type(eventPtr);
eventType = Control.fixGdkEventTypeValues(eventType);
switch (eventType) {
case GDK.GDK_BUTTON_PRESS:
GdkEventButton eventButton = new GdkEventButton();
GTK3.memmove (eventButton, eventPtr, GdkEventButton.sizeof);
eventButton.window = deviceResource;
GTK3.memmove(eventPtr, eventButton, GdkEventButton.sizeof);
break;
case GDK.GDK_KEY_PRESS:
GdkEventKey eventKey = new GdkEventKey();
GTK3.memmove (eventKey, eventPtr, GdkEventKey.sizeof);
eventKey.window = deviceResource;
GTK3.memmove(eventPtr, eventKey, GdkEventKey.sizeof);
break;
}
}
return;
}
/**
* Feature in GTK3 on X11: context menus in SWT are populated
* dynamically, sometimes asynchronously outside of SWT
* (i.e. in Platform UI). This means that items are added and
* removed just before the menu is shown. This method of
* changing the menu content can sometimes cause sizing issues
* internally in GTK, specifically with the height of the
* toplevel GdkWindow.
*
* The fix is to cache the number of items popped up previously,
* and if the number of items in the current menu (to be popped up)
* is different, then:
*
get the preferred height of the menu
*
set the toplevel GdkWindow to that height
*
* @param itemCount the current number of items in the menu, just
* before it's about to be shown/popped-up
*/
void verifyMenuPosition (int itemCount) {
if (OS.isX11()) {
if (itemCount != poppedUpCount && poppedUpCount != 0) {
int [] naturalHeight = new int [1];
/*
* We need to "show" the menu before fetching the preferred height.
* Note, this does not actually pop-up the menu.
*/
GTK.gtk_widget_show(handle);
/*
* Menus are height-for-width only: use gtk_widget_get_preferred_height()
* instead of gtk_widget_get_preferred_size().
*/
GTK3.gtk_widget_get_preferred_height(handle, null, naturalHeight);
if (naturalHeight[0] > 0) {
if (GTK.GTK4) {
/* TODO: GTK4 gdk_surface_resize/move no longer exist & have been replaced with
* gdk_toplevel_begin_resize & gdk_toplevel_begin_move. These functions might change the
* design of resizing and moving in GTK4 */
} else {
long topLevelWidget = GTK3.gtk_widget_get_toplevel(handle);
long topLevelWindow = GTK3.gtk_widget_get_window(topLevelWidget);
int width = GDK.gdk_window_get_width(topLevelWindow);
GDK.gdk_window_resize(topLevelWindow, width, naturalHeight[0]);
}
}
}
}
}
/**
* Marks the receiver as visible if the argument is true,
* and marks it invisible otherwise.
*
* If one of the receiver's ancestors is not visible or some
* other condition makes the receiver not visible, marking
* it visible may not actually cause it to be displayed.
*
*
* @param visible the new visibility state
*
* @exception SWTException
*
ERROR_WIDGET_DISPOSED - if the receiver has been disposed
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver