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

Source Code of com.google.gdt.eclipse.designer.uibinder.model.widgets.UIObjectInfo

/*******************************************************************************
* 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;

import com.google.gdt.eclipse.designer.model.widgets.IUIObjectInfo;
import com.google.gdt.eclipse.designer.model.widgets.IUIObjectSizeSupport;
import com.google.gdt.eclipse.designer.model.widgets.support.DOMUtils;
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.util.NameProperty;
import com.google.gdt.eclipse.designer.uibinder.parser.UiBinderContext;
import com.google.gdt.eclipse.designer.uibinder.parser.UiBinderRenderer;

import org.eclipse.wb.draw2d.geometry.Insets;
import org.eclipse.wb.draw2d.geometry.Rectangle;
import org.eclipse.wb.draw2d.geometry.Translatable;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils;
import org.eclipse.wb.internal.core.utils.execution.RunnableEx;
import org.eclipse.wb.internal.core.utils.execution.RunnableObjectEx;
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.AbstractComponentInfo;
import org.eclipse.wb.internal.core.xml.model.EditorContext;
import org.eclipse.wb.internal.core.xml.model.creation.CreationSupport;
import org.eclipse.wb.internal.core.xml.model.description.ComponentDescription;
import org.eclipse.wb.internal.core.xml.model.utils.XmlObjectUtils;

import org.eclipse.swt.graphics.Image;

import org.apache.commons.lang.StringUtils;

import java.util.List;

/**
* Model for <code>UiObject</code> in GWT UiBinder.
*
* @author scheglov_ke
* @coverage GWT.UiBinder.model
*/
public class UIObjectInfo extends AbstractComponentInfo implements IUIObjectInfo {
  private final Property m_variableProperty = new NameProperty(this);

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

  ////////////////////////////////////////////////////////////////////////////
  //
  // Access
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  public UiBinderContext getContext() {
    return (UiBinderContext) super.getContext();
  }

  public final GwtState getState() {
    return getContext().getState();
  }

  /**
   * @return the {@link UIObjectUtils} to work with <code>UIObject</code>.
   */
  public final UIObjectUtils getUIObjectUtils() {
    return getState().getUIObjectUtils();
  }

  /**
   * @return the {@link DOMUtils} to work with <code>Element</code>.
   */
  public final DOMUtils getDOM() {
    return getState().getDomUtils();
  }

  @Override
  public Rectangle getAbsoluteBounds() {
    return m_absoluteBounds;
  }

  /**
   * @return the DOM margins.
   */
  public final Insets getMargins() {
    return m_margins;
  }

  /**
   * @return the DOM borders.
   */
  public final Insets getBorders() {
    return m_borders;
  }

  /**
   * @return the DOM paddings.
   */
  public final Insets getPaddings() {
    return m_paddings;
  }

  /**
   * @return the underlying DOM <code>Element</code>.
   */
  public Object getDOMElement() throws Exception {
    return getState().getUIObjectUtils().getElement(getObject());
  }

  /**
   * @return <code>true</code> if this {@link UIObjectInfo} has no visible border, so artificial
   *         border should be drawn.
   */
  @Override
  public boolean shouldDrawDotsBorder() {
    return ExecutionUtils.runObjectIgnore(new RunnableObjectEx<Boolean>() {
      public Boolean runObject() throws Exception {
        String script = XmlObjectUtils.getParameter(UIObjectInfo.this, "shouldDrawBorder");
        if (!StringUtils.isEmpty(script)) {
          return (Boolean) XmlObjectUtils.executeScript(UIObjectInfo.this, script);
        }
        return false;
      }
    }, false);
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Size
  //
  ////////////////////////////////////////////////////////////////////////////
  private final UIObjectSizeSupport m_sizeSupport = new UIObjectSizeSupport(this);

  public final IUIObjectSizeSupport getSizeSupport() {
    return m_sizeSupport;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Life cycle
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  protected final void saveEdit() throws Exception {
    super.saveEdit();
    getContext().saveFormEditor();
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Properties
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  protected List<Property> getPropertyList() throws Exception {
    List<Property> properties = super.getPropertyList();
    properties.add(m_sizeSupport.getSizeProperty());
    properties.add(m_variableProperty);
    return properties;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Refresh
  //
  ////////////////////////////////////////////////////////////////////////////
  private List<Object> m_liveProcessHiddenWidgets;

  @Override
  public void refresh_dispose() throws Exception {
    // GWT does not allow any operation after disposing GWTState
    if (getState().isDisposed()) {
      return;
    }
    // clear RootPanel
    if (isRoot()) {
      getUIObjectUtils().clearRootPanel();
    }
    // dispose children
    super.refresh_dispose();
  }

  @Override
  public void refresh_beforeCreate() throws Exception {
    call_Impl_enter();
    super.refresh_beforeCreate();
  }

  @Override
  protected void refresh_create() throws Exception {
    UiBinderRenderer renderer = new UiBinderRenderer(this);
    renderer.render();
  }

  @Override
  protected void refresh_afterCreate() throws Exception {
    super.refresh_afterCreate();
    if (isRoot()) {
      UIObjectUtils utils = getUIObjectUtils();
      Object liveWidget = utils.getLiveWidget();
      if (liveWidget != null) {
        m_liveProcessHiddenWidgets = utils.hideRootPanelWidgets(liveWidget);
      }
    }
  }

  @Override
  protected void refresh_afterCreate2() throws Exception {
    super.refresh_afterCreate2();
    call_Impl_exit();
  }

  @Override
  protected void refresh_finish() throws Exception {
    super.refresh_finish();
    if (isRoot()) {
      if (m_liveProcessHiddenWidgets != null) {
        UIObjectUtils.showWidgets(m_liveProcessHiddenWidgets);
        m_liveProcessHiddenWidgets = null;
      }
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Impl life cycle
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Call enter() as if this UI was create as result of call from JavaScript.
   */
  private void call_Impl_enter() {
    if (isRoot()) {
      ExecutionUtils.runIgnore(new RunnableEx() {
        public void run() throws Exception {
          ClassLoader classLoader = getContext().getClassLoader();
          Class<?> class_Impl = classLoader.loadClass("com.google.gwt.core.client.impl.Impl");
          ReflectionUtils.invokeMethod(class_Impl, "enter()");
        }
      });
    }
  }

  /**
   * Call exit() as if this UI was create as result of call from JavaScript.
   */
  private void call_Impl_exit() {
    if (isRoot()) {
      ExecutionUtils.runIgnore(new RunnableEx() {
        public void run() throws Exception {
          ClassLoader classLoader = getContext().getClassLoader();
          Class<?> class_Impl = classLoader.loadClass("com.google.gwt.core.client.impl.Impl");
          ReflectionUtils.invokeMethod(class_Impl, "exit(boolean)", true);
        }
      });
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Refresh: fetch
  //
  ////////////////////////////////////////////////////////////////////////////
  private Rectangle m_absoluteBounds;
  protected Insets m_margins;
  protected Insets m_borders;
  protected Insets m_paddings;

  @Override
  protected void refresh_fetch() throws Exception {
    Object element = getDOMElement();
    // check for messages loop
    if (isRoot()) {
      if (requiresMessagesLoop()) {
        for (int i = 0; i < 5; i++) {
          getState().runMessagesLoop();
          Thread.sleep(1);
        }
      }
    }
    // prepare bounds
    fetchBounds(element);
    // prepare image
    if (isRoot()) {
      fetchImage(element);
    }
    // prepare parent-relative bounds
    {
      Rectangle parentBounds = new Rectangle(m_absoluteBounds);
      if (getParent() instanceof AbstractComponentInfo) {
        AbstractComponentInfo parent = (AbstractComponentInfo) getParent();
        Rectangle parentAbsoluteBounds = parent.getAbsoluteBounds();
        parentBounds.x -= parentAbsoluteBounds.x;
        parentBounds.y -= parentAbsoluteBounds.y;
      } else {
        parentBounds.x = parentBounds.y = 0;
      }
      setBounds(parentBounds);
    }
    // borders/margins/paddings
    fetchSpacing();
    // continue for children
    super.refresh_fetch();
  }

  protected void fetchBounds(Object element) throws Exception {
    m_absoluteBounds = fetchAbsoluteBounds(element);
    {
      Rectangle bounds = m_absoluteBounds.getCopy();
      if (getParent() instanceof AbstractComponentInfo) {
        AbstractComponentInfo parent = (AbstractComponentInfo) getParent();
        Rectangle parentAbsoluteBounds = parent.getAbsoluteBounds();
        bounds.x -= parentAbsoluteBounds.x;
        bounds.y -= parentAbsoluteBounds.y;
        bounds.translate(parent.getClientAreaInsets().getNegated());
      }
      setModelBounds(bounds);
    }
  }

  protected Rectangle fetchModelBounds(Object element) {
    return getState().getModelBounds(element);
  }

  protected Rectangle fetchAbsoluteBounds(Object element) {
    Rectangle absoluteBounds = getState().getAbsoluteBounds(element);
    // Case 43858: https://fogbugz.instantiations.com/default.php?43858
    if (isRoot()) {
      if (absoluteBounds.x < 0) {
        absoluteBounds.x = 0;
      }
      if (absoluteBounds.y < 0) {
        absoluteBounds.y = 0;
      }
    }
    return absoluteBounds;
  }

  protected void fetchImage(Object element) throws Exception {
    GwtState state = getState();
    Image browserScreenshot = state.createBrowserScreenshot();
    // prepare bounds of image
    Rectangle imageBounds = m_absoluteBounds;
    if (state.isStrictMode() && state.isBrowserExplorer()) {
      imageBounds = imageBounds.getTranslated(2, 2);
    }
    // set image
    Image objectImage = UiUtils.getCroppedImage(browserScreenshot, imageBounds.getSwtRectangle());
    setImage(objectImage);
  }

  /**
   * @return <code>true</code> if this {@link UIObjectInfo} or one of its children require running
   *         messages loop before {@link #refresh_fetch()}, to finalize rendering.
   */
  private boolean requiresMessagesLoop() {
    for (UIObjectInfo child : getChildren(UIObjectInfo.class)) {
      if (child.requiresMessagesLoop()) {
        return true;
      }
    }
    {
      String script = XmlObjectUtils.getParameter(this, "GWT.requiresMessagesLoop");
      return getUIObjectUtils().evaluateScriptBoolean(script);
    }
  }

  /**
   * Fetch spacing of UI Object.
   */
  protected void fetchSpacing() throws Exception {
    GwtState state = getState();
    Object element = getDOMElement();
    m_margins = state.getMargins(element);
    m_borders = state.getBorders(element);
    m_paddings = state.getPaddings(element);
    // prepare "clientAreaInsets"
    if (!getState().isBody(element)) {
      fetchClientAreaInsets();
    }
  }

  /**
   * Fetches "client area insets". Usually "margins + borders", but complex components may require
   * special handling.
   */
  protected void fetchClientAreaInsets() throws Exception {
    Insets insets = new Insets();
    insets.add(m_margins);
    insets.add(m_borders);
    setClientAreaInsets(insets);
  }

  /**
   * Transforms given absolute {@link Translatable} into this {@link UIObjectInfo} relative.
   */
  public final void absoluteToRelative(Translatable translatable) {
    translatable.translate(-m_absoluteBounds.x, -m_absoluteBounds.y);
  }

  /**
   * Transforms given absolute {@link Translatable} into this {@link UIObjectInfo} model.
   */
  public final void absoluteToModel(Translatable translatable) {
    absoluteToRelative(translatable);
    {
      Insets clientAreaInsets = getClientAreaInsets();
      translatable.translate(-clientAreaInsets.left, -clientAreaInsets.top);
    }
  }
}
TOP

Related Classes of com.google.gdt.eclipse.designer.uibinder.model.widgets.UIObjectInfo

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.