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

Source Code of com.google.gdt.eclipse.designer.model.widgets.WidgetTopBoundsSupport

/*******************************************************************************
* 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.model.widgets;

import com.google.common.collect.Maps;
import com.google.gdt.eclipse.designer.hosted.IBrowserShell;

import org.eclipse.wb.draw2d.geometry.Dimension;
import org.eclipse.wb.internal.core.model.JavaInfoEvaluationHelper;
import org.eclipse.wb.internal.core.model.JavaInfoUtils;
import org.eclipse.wb.internal.core.model.TopBoundsSupport;
import org.eclipse.wb.internal.core.utils.ast.AstEditor;
import org.eclipse.wb.internal.core.utils.ast.DomGenerics;

import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodInvocation;

import java.util.List;
import java.util.Map;

/**
* Implementation of {@link TopBoundsSupport} for any {@link WidgetInfo} except
* <code>RootPanel</code>.
*
* @author scheglov_ke
* @coverage gwt.model.top
*/
public class WidgetTopBoundsSupport extends TopBoundsSupport {
  private final WidgetInfo m_widget;

  ////////////////////////////////////////////////////////////////////////////
  //
  // Constructor
  //
  ////////////////////////////////////////////////////////////////////////////
  public WidgetTopBoundsSupport(WidgetInfo widget) {
    super(widget);
    m_widget = widget;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // TopBoundsSupport
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * This constant is using to expand size of {@link IBrowserShell} relative to size of widget. We
   * need to do this because (for unknown reason) in other case GWT DialogBox and PopupPanel do
   * wrapping after changing {@link IBrowserShell} size, so change size of image to take.
   */
  private static final int SIZE_EXPAND = 50;

  @Override
  public void apply() throws Exception {
    m_widget.getBroadcast(WidgetAttachAfterConstructor.class).invoke();
    // remove borders
    dontUseBorderForRootPanel();
    // ensure attached
    invokeAttachScript();
    // apply size to get actual widget size
    Dimension resourceSize = getResourceSize();
    doApply(resourceSize);
    // get the real "size" to include full widget
    Dimension size = getExpandedSize();
    // correct size to fit into top-level root panel
    Dimension correctedSize = new Dimension(resourceSize);
    correctedSize.width -= size.width - resourceSize.width;
    correctedSize.height -= size.height - resourceSize.height;
    // apply corrected size to the widget
    if (correctedSize.width > 0 && correctedSize.height > 0) {
      doApply(correctedSize);
    }
    afterApply();
    // set Shell size
    IBrowserShell shell = m_widget.getState().getShell();
    shell.prepare();
    org.eclipse.swt.graphics.Rectangle shellBounds =
        shell.computeTrim(0, 0, size.width, size.height);
    shell.setSize(shellBounds.width + SIZE_EXPAND, shellBounds.height + SIZE_EXPAND);
  }

  private void doApply(Dimension resourceSize) throws Exception {
    if (!isSizeAlreadySet()) {
      applySizeUsingScript(resourceSize);
    }
  }

  protected void afterApply() throws Exception {
  }

  protected boolean isSizeAlreadySet() throws Exception {
    boolean hasSize =
        hasMethodInvocations(new String[]{"setSize(int,int)", "setWidth(int)", "setHeight(int)"});
    // process "xxx%" size specification
    if (!hasSize) {
      {
        MethodInvocation invocation =
            m_component.getMethodInvocation("setSize(java.lang.String,java.lang.String)");
        if (invocation != null) {
          List<Expression> arguments = DomGenerics.arguments(invocation);
          String width = (String) JavaInfoEvaluationHelper.getValue(arguments.get(0));
          String height = (String) JavaInfoEvaluationHelper.getValue(arguments.get(1));
          if (width.endsWith("%") || height.endsWith("%")) {
            // size is not set at actual value
            return false;
          }
          hasSize = true;
        }
      }
      {
        MethodInvocation invocation = m_component.getMethodInvocation("setWidth(java.lang.String)");
        if (invocation != null) {
          List<Expression> arguments = DomGenerics.arguments(invocation);
          String width = (String) JavaInfoEvaluationHelper.getValue(arguments.get(0));
          if (width.endsWith("%")) {
            // size is not set at actual value
            return false;
          }
          hasSize = true;
        }
      }
      {
        MethodInvocation invocation =
            m_component.getMethodInvocation("setHeight(java.lang.String)");
        if (invocation != null) {
          List<Expression> arguments = DomGenerics.arguments(invocation);
          String height = (String) JavaInfoEvaluationHelper.getValue(arguments.get(0));
          if (height.endsWith("%")) {
            // size is not set at actual value
            return false;
          }
          hasSize = true;
        }
      }
    }
    return hasSize;
  }

  protected Dimension getExpandedSize() throws Exception {
    return m_widget.getState().getAbsoluteBounds(m_widget.getElement()).getSize();
  }

  private void dontUseBorderForRootPanel() throws Exception {
    m_widget.getUIObjectUtils().executeScript(
        "DOM.setStyleAttribute(rootPanel.getElement(), 'border', '0');");
  }

  @Override
  public void setSize(int width, int height) throws Exception {
    setSizeUsingScript(width, height);
    setResourceSize(width, height);
    {
      setSizeInt("setSize(int,int)", 0, width);
      setSizeString("setSize(java.lang.String,java.lang.String)", 0, width);
      setSizeInt("setWidth(int)", 0, width);
      setSizeString("setWidth(java.lang.String)", 0, width);
    }
    {
      setSizeInt("setSize(int,int)", 1, height);
      setSizeString("setSize(java.lang.String,java.lang.String)", 1, height);
      setSizeInt("setHeight(int)", 0, height);
      setSizeString("setHeight(java.lang.String)", 0, height);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Script utils
  //
  ////////////////////////////////////////////////////////////////////////////
  private void applySizeUsingScript(Dimension size) throws Exception {
    invokeSizeScript("applyTopBoundsScript", size);
  }

  private void setSizeUsingScript(int width, int height) throws Exception {
    invokeSizeScript("setTopBoundsScript", new Dimension(width, height));
  }

  private void invokeSizeScript(String scriptName, Dimension size) throws Exception {
    String script = JavaInfoUtils.getParameter(m_widget, scriptName);
    if (script != null) {
      Map<String, Object> variables = Maps.newTreeMap();
      variables.put("model", m_widget);
      variables.put("widget", m_widget.getObject());
      variables.put("size", size);
      m_widget.getUIObjectUtils().executeScript(script, variables);
    }
  }

  private void invokeAttachScript() throws Exception {
    String script = JavaInfoUtils.getParameter(m_widget, "attachTopBoundsScript");
    if (script != null) {
      Map<String, Object> variables = Maps.newTreeMap();
      variables.put("model", m_widget);
      variables.put("widget", m_widget.getObject());
      m_widget.getUIObjectUtils().executeScript(script, variables);
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Apply size in source
  //
  ////////////////////////////////////////////////////////////////////////////
  protected final boolean setSizeInt(String signature, int index, int value) throws Exception {
    String expression = Integer.toString(value);
    return setSizeExpression(signature, index, expression);
  }

  protected final boolean setSizeString(String signature, int index, int value) throws Exception {
    String expression = "\"" + Integer.toString(value) + "px\"";
    return setSizeExpression(signature, index, expression);
  }

  private boolean setSizeExpression(String signature, int index, String expression)
      throws Exception {
    MethodInvocation invocation = m_widget.getMethodInvocation(signature);
    if (invocation != null) {
      AstEditor editor = m_widget.getEditor();
      editor.replaceInvocationArgument(invocation, index, expression);
      return true;
    }
    return false;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Show
  //
  ////////////////////////////////////////////////////////////////////////////
  @Override
  public boolean show() throws Exception {
    m_widget.getState().showShell();
    return true;
  }
}
TOP

Related Classes of com.google.gdt.eclipse.designer.model.widgets.WidgetTopBoundsSupport

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.