/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.ui.ridgets.swt; import java.util.List; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.riena.internal.ui.ridgets.swt.ContextMenuDelegate; import org.eclipse.riena.ui.core.marker.HiddenMarker; import org.eclipse.riena.ui.ridgets.IMenuItemRidget; import org.eclipse.riena.ui.swt.utils.SwtUtilities; import org.eclipse.riena.ui.swt.utils.UIControlsFactory; /** * Ridget for an SWT control. */ public abstract class AbstractSWTRidget extends AbstractSWTWidgetRidget { /** * The key of the SWT data property that identifies the (top) composite of a sub-module view. */ private static final String IS_SUB_MODULE_VIEW_COMPOSITE = "isSubModuleViewComposite"; //$NON-NLS-1$ private final FocusManager focusManager; private boolean focusable; private final ContextMenuDelegate contextMenuDelegate; /** * @since 3.0 */ public FocusManager getFocusManager() { return focusManager; } public AbstractSWTRidget() { focusManager = new FocusManager(this); focusable = true; contextMenuDelegate = new ContextMenuDelegate(); } @Override public Control getUIControl() { return (Control) super.getUIControl(); } @Override public final void requestFocus() { if (isFocusable()) { if (getUIControl() != null) { final Control control = getUIControl(); // if setFocus() fails because e.g. the parent is disabled // the state has to be saved, so it can be restored in submoduleController.unblockView() setRetryRequestFocus(!control.setFocus()); } } } @Override public boolean hasFocus() { final Control control = getUIControl(); if (!SwtUtilities.isDisposed(control)) { return control.isFocusControl(); } return false; } @Override public final boolean isFocusable() { return focusable; } @Override public final void setFocusable(final boolean focusable) { if (this.focusable != focusable) { this.focusable = focusable; } } public boolean isVisible() { // check for "hidden.marker". This marker overrules any other visibility rule if (!getMarkersOfType(HiddenMarker.class).isEmpty()) { return false; } if (!SwtUtilities.isDisposed(getUIControl())) { // the swt control is bound if (isChildOfSubModuleView(getUIControl())) { return isControlVisible(getUIControl()); } else { return getUIControl().isVisible(); } } // control is not bound return savedVisibleState; } /** * Returns whether the given control is the (top) composite of a sub-module view. * * @param uiControl * UI control * @return {@code true} if control is composite of a sub-module; otherwise {@code false} */ private boolean isSubModuleViewComposite(final Control uiControl) { if (!(uiControl instanceof Composite)) { return false; } if (uiControl.getData(IS_SUB_MODULE_VIEW_COMPOSITE) instanceof Boolean) { if (((Boolean) uiControl.getData(IS_SUB_MODULE_VIEW_COMPOSITE))) { return true; } } return false; } /** * Returns whether the given control is a child of the (top) composite of a sub-module view. * * @param uiControl * UI control * @return {@code true} if control is child of a sub-module; otherwise {@code false} */ private boolean isChildOfSubModuleView(final Control uiControl) { if (uiControl.getVisible()) { final Composite parent = uiControl.getParent(); if (parent == null) { return false; } if (isSubModuleViewComposite(parent)) { return true; } return isChildOfSubModuleView(parent); } else { return false; } } /** * Returns whether the given control is visible or invisible. * <p> * Similar to the SWT method isVisible of the class {@link Control} this method also checks if the parent composite are also visible. But this checks end at * the top composite of a sub-module view. * * @param uiControl * UI control * @return {@code true} if control is visible; otherwise {@code false} */ private boolean isControlVisible(final Control uiControl) { if (uiControl.getVisible()) { final Composite parent = uiControl.getParent(); if (parent == null) { return true; } if (isSubModuleViewComposite(parent)) { return true; } return isControlVisible(parent); } else { return false; } } @Override protected void unbindUIControl() { // save the state savedVisibleState = isVisible(); } // helping methods // //////////////// /** * Adds listeners to the <tt>uiControl</tt> after it was bound to the ridget. */ @Override protected final void installListeners() { super.installListeners(); final Control control = getUIControl(); if (!SwtUtilities.isDisposed(control)) { focusManager.addListeners(control); } } /** * Removes listeners from the <tt>uiControl</tt> when it is about to be unbound from the ridget. */ @Override protected final void uninstallListeners() { final Control control = getUIControl(); if (!SwtUtilities.isDisposed(control)) { focusManager.removeListeners(control); } super.uninstallListeners(); } @Override protected void updateEnabled() { if (!SwtUtilities.isDisposed(getUIControl())) { getUIControl().setEnabled(isEnabled()); } } @Override protected final void updateToolTip() { if (!SwtUtilities.isDisposed(getUIControl())) { getUIControl().setToolTipText(getToolTipText()); } } @Override public final void setUIControl(final Object uiControl) { super.setUIControl(uiControl); updateContextMenu(); } private void updateContextMenu() { if (SwtUtilities.isDisposed(getUIControl())) { return; } final List<IMenuItemRidget> menuItems = contextMenuDelegate.getMenuItems(); if (menuItems != null && !menuItems.isEmpty()) { Menu menu = getUIControl().getMenu(); if (menu != null) { getUIControl().setMenu(null); menu.dispose(); } menu = UIControlsFactory.createMenu(getUIControl()); getUIControl().setMenu(menu); for (final IMenuItemRidget item : menuItems) { final MenuItem uiItem = UIControlsFactory.createMenuItem(menu, item.getText(), item.getText()); item.setUIControl(uiItem); } } } @Override public IMenuItemRidget addMenuItem(final String itemText) { return addMenuItem(itemText, null); } @Override public IMenuItemRidget addMenuItem(final String itemText, final String iconName) { final IMenuItemRidget item = contextMenuDelegate.addMenuItem(itemText, iconName); updateContextMenu(); return item; } @Override public void removeMenuItem(final String menuItemText) { contextMenuDelegate.removeMenuItem(menuItemText); updateContextMenu(); } @Override public void removeMenuItem(final IMenuItemRidget menuItemRidget) { contextMenuDelegate.removeMenuItem(menuItemRidget); updateContextMenu(); } @Override public IMenuItemRidget getMenuItem(final int index) { return contextMenuDelegate.getMenuItem(index); } @Override public int getMenuItemCount() { return contextMenuDelegate.getMenuItemCount(); } }