Package com.google.gdt.eclipse.designer.uibinder.model.widgets.menu

Source Code of com.google.gdt.eclipse.designer.uibinder.model.widgets.menu.MenuBarInfo$MenuAbstractImpl

/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.google.gdt.eclipse.designer.uibinder.model.widgets.menu;

import com.google.common.collect.Lists;
import com.google.gdt.eclipse.designer.model.widgets.support.GwtState;
import com.google.gdt.eclipse.designer.model.widgets.support.UIObjectUtils;
import com.google.gdt.eclipse.designer.uibinder.model.widgets.UIObjectInfo;
import com.google.gdt.eclipse.designer.uibinder.model.widgets.WidgetInfo;

import org.eclipse.wb.core.model.ObjectInfo;
import org.eclipse.wb.draw2d.geometry.Dimension;
import org.eclipse.wb.draw2d.geometry.Rectangle;
import org.eclipse.wb.internal.core.model.menu.IMenuInfo;
import org.eclipse.wb.internal.core.model.menu.IMenuItemInfo;
import org.eclipse.wb.internal.core.model.menu.IMenuObjectInfo;
import org.eclipse.wb.internal.core.model.menu.IMenuPolicy;
import org.eclipse.wb.internal.core.model.menu.MenuObjectInfoUtils;
import org.eclipse.wb.internal.core.utils.IAdaptable;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.utils.ui.UiUtils;
import org.eclipse.wb.internal.core.xml.model.EditorContext;
import org.eclipse.wb.internal.core.xml.model.XmlMenuMenuObject;
import org.eclipse.wb.internal.core.xml.model.creation.CreationSupport;
import org.eclipse.wb.internal.core.xml.model.description.ComponentDescription;

import org.eclipse.swt.graphics.Image;

import java.util.List;

/**
* Model for <code>com.google.gwt.user.client.ui.MenuBar</code> in GWT UiBinder.
*
* @author scheglov_ke
* @coverage GWT.UiBinder.model
*/
public final class MenuBarInfo extends WidgetInfo implements IAdaptable {
  private final MenuBarInfo m_this = this;

  ////////////////////////////////////////////////////////////////////////////
  //
  // Constructor
  //
  ////////////////////////////////////////////////////////////////////////////
  public MenuBarInfo(EditorContext context,
      ComponentDescription description,
      CreationSupport creationSupport) throws Exception {
    super(context, description, creationSupport);
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Access
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * @return {@link MenuItemInfo} children.
   */
  public List<MenuItemInfo> getItems() {
    return getChildren(MenuItemInfo.class);
  }

  /**
   * @return {@link MenuItemInfo} or {@link MenuItemSeparatorInfo} children.
   */
  public List<UIObjectInfo> getAllItems() {
    List<UIObjectInfo> items = Lists.newArrayList();
    for (ObjectInfo child : getChildren()) {
      if (child instanceof MenuItemInfo || child instanceof MenuItemSeparatorInfo) {
        items.add((UIObjectInfo) child);
      }
    }
    return items;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Refresh
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  protected void refresh_fetch() throws Exception {
    super.refresh_fetch();
    fetchVisualData();
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // State
  //
  ////////////////////////////////////////////////////////////////////////////
  private boolean isTopLevel() {
    return !(getParent() instanceof MenuItemInfo);
  }

  private boolean isVertical() {
    return ReflectionUtils.getFieldBoolean(getObject(), "vertical");
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Visual data
  //
  ////////////////////////////////////////////////////////////////////////////
  private void fetchVisualData() throws Exception {
    if (isTopLevel()) {
      fetchAsTopMenu();
    } else {
      fetchAsSubMenu();
    }
  }

  private void fetchAsTopMenu() throws Exception {
    fetchItemBounds();
  }

  private void fetchAsSubMenu() throws Exception {
    Object popup = showThisMenuPopup();
    try {
      fetchFromMenuPopup(popup);
    } finally {
      callMenuBar_close(getObject());
    }
  }

  private Object showThisMenuPopup() throws Exception {
    Object parentItem = getParentXML().getObject();
    Object parentMenu = ReflectionUtils.invokeMethod(parentItem, "getParentMenu()");
    call_MenuBar_doItemAction(parentMenu, parentItem);
    //
    removeFirstItemSelection();
    return ReflectionUtils.getFieldObject(parentMenu, "popup");
  }

  private static void callMenuBar_close(Object menuBar) throws Exception {
    ReflectionUtils.invokeMethod(menuBar, "close(boolean)", false);
  }

  private static void call_MenuBar_doItemAction(Object menu, Object item) throws Exception {
    // GWT 2.0.1
    ReflectionUtils.invokeMethod(
        menu,
        "doItemAction(com.google.gwt.user.client.ui.MenuItem,boolean,boolean)",
        item,
        false,
        false);
  }

  private void removeFirstItemSelection() throws Exception {
    Object selectedItem = ReflectionUtils.getFieldObject(getObject(), "selectedItem");
    if (selectedItem != null) {
      ReflectionUtils.invokeMethod(selectedItem, "setSelectionStyle(boolean)", false);
    }
  }

  private void fetchFromMenuPopup(Object popup) throws Exception {
    fetchSubMenuBounds(popup);
    fetchItemBounds();
    setImage(getPopupImage(popup));
  }

  private void fetchSubMenuBounds(Object popup) throws Exception {
    Object menuElement = getState().getUIObjectUtils().getElement(popup);
    fetchBounds(menuElement);
  }

  private Image getPopupImage(Object popup) throws Exception {
    Rectangle popupBounds = getReasonablePopupBounds(popup);
    setPopupPosition(popup, popupBounds.x, popupBounds.y);
    // make shot of whole browser - we don't have other way to get screen shot of menu
    List<Object> hiddenWidgets = getUIObjectUtils().hideRootPanelWidgets(popup);
    try {
      Image browserImage = getState().getShell().createBrowserScreenshot();
      return UiUtils.getCroppedImage(browserImage, popupBounds.getSwtRectangle());
    } finally {
      UIObjectUtils.showWidgets(hiddenWidgets);
    }
  }

  private Rectangle getReasonablePopupBounds(Object popup) throws Exception {
    Dimension popupSize = getPopupSize(popup);
    return new Rectangle(50, 50, popupSize.width, popupSize.height);
  }

  private Dimension getPopupSize(Object popup) throws Exception {
    GwtState state = getState();
    Object popupElement = state.getUIObjectUtils().getElement(popup);
    return state.getAbsoluteBounds(popupElement).getSize();
  }

  private static void setPopupPosition(Object popup, int left, int top) throws Exception {
    ReflectionUtils.invokeMethod(popup, "setPopupPosition(int,int)", left, top);
  }

  private void fetchItemBounds() throws Exception {
    GwtState state = getState();
    for (UIObjectInfo item : getAllItems()) {
      Object itemElement = item.getDOMElement();
      Rectangle itemBounds = state.getAbsoluteBounds(itemElement);
      absoluteToRelative(itemBounds);
      item.setBounds(itemBounds);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // IAdaptable
  //
  ////////////////////////////////////////////////////////////////////////////
  private final IMenuInfo m_menuImpl = new MenuImpl();
  private final IMenuPolicy m_menuPolicyImpl = new MenuBarPolicyImpl(this);

  public <T> T getAdapter(Class<T> adapter) {
    if (adapter.isAssignableFrom(IMenuInfo.class)) {
      return adapter.cast(m_menuImpl);
    }
    return null;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // AbstractMenuImpl
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Abstract superclass for {@link IMenuObjectInfo} implementations.
   *
   * @author scheglov_ke
   */
  private abstract class MenuAbstractImpl extends XmlMenuMenuObject {
    public MenuAbstractImpl() {
      super(m_this);
    }
  }
  ////////////////////////////////////////////////////////////////////////////
  //
  // IMenuInfo
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Implementation of {@link IMenuInfo}.
   *
   * @author scheglov_ke
   */
  private final class MenuImpl extends MenuAbstractImpl implements IMenuInfo {
    ////////////////////////////////////////////////////////////////////////////
    //
    // Model
    //
    ////////////////////////////////////////////////////////////////////////////
    public Object getModel() {
      return m_this;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Presentation
    //
    ////////////////////////////////////////////////////////////////////////////
    public Image getImage() {
      return m_this.getImage();
    }

    public Rectangle getBounds() {
      return m_this.getBounds();
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Access
    //
    ////////////////////////////////////////////////////////////////////////////
    public boolean isHorizontal() {
      return !isVertical();
    }

    public List<IMenuItemInfo> getItems() {
      List<IMenuItemInfo> items = Lists.newArrayList();
      for (ObjectInfo object : getAllItems()) {
        IMenuItemInfo item = MenuObjectInfoUtils.getMenuItemInfo(object);
        items.add(item);
      }
      return items;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Policy
    //
    ////////////////////////////////////////////////////////////////////////////
    public IMenuPolicy getPolicy() {
      return m_menuPolicyImpl;
    }
  }
}
TOP

Related Classes of com.google.gdt.eclipse.designer.uibinder.model.widgets.menu.MenuBarInfo$MenuAbstractImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.