com.google.appinventor.client.editor.simple.components.MockImageBase.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.client.editor.simple.components.MockImageBase.java

Source

// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
// TODO(user): reconsider visibilities of the abstract base classes in this package

package com.google.appinventor.client.editor.simple.components;

import com.google.appinventor.client.editor.simple.SimpleEditor;
import com.google.appinventor.client.output.OdeLog;
import com.google.common.primitives.Ints;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.SimplePanel;

/**
 * Abstract superclass for MockImage and MockImageSprite.
 *
 * @author lizlooney@google.com (Liz Looney)
 */
abstract class MockImageBase extends MockVisibleComponent {
    // Property names
    private static final String PROPERTY_NAME_PICTURE = "Picture";
    private static final String PROPERTY_SCALE_PICTURE_TO_FIT = "ScalePictureToFit";
    private static final String PROPERTY_SCALING = "Scaling";

    // Widget for showing the image.
    private final Image image;
    private String picturePropValue;
    private String scalingMode = "0"; // corresponds to Scale proportionally

    MockImageBase(SimpleEditor editor, String type, ImageResource icon) {
        super(editor, type, icon);

        image = new Image();
        image.addErrorHandler(new ErrorHandler() {
            @Override
            public void onError(ErrorEvent event) {
                if (picturePropValue != null && !picturePropValue.isEmpty()) {
                    OdeLog.elog("Error occurred while loading image " + picturePropValue);
                }
                refreshForm();
            }
        });
        image.addLoadHandler(new LoadHandler() {
            @Override
            public void onLoad(LoadEvent event) {
                refreshForm();
                resizeImage(); // resize after the new image occupies the form
            }
        });

        SimplePanel simplePanel = new SimplePanel();
        simplePanel.setStylePrimaryName("ode-SimpleMockComponent");
        simplePanel.addStyleName("imageComponentCenterPanel");
        simplePanel.setWidget(image);
        initComponent(simplePanel);
    }

    /*
     * Sets the image's url to a new value.
     */
    private void setPictureProperty(String text) {
        picturePropValue = text;
        String url = convertImagePropertyValueToUrl(text);
        if (url == null) {
            // text was not recognized as an asset. Just display the icon for this type of component.
            image.setUrl(getIconImage().getUrl());
        } else {
            image.setUrl(url);
        }
    }

    @Override
    public int getPreferredWidth() {
        // The superclass uses getOffsetWidth, which won't work for us.
        // Hide away the current 100% size so we can get at the actual size, otherwise automatic size doesn't work
        String[] style = MockComponentsUtil.clearSizeStyle(image);
        int width = image.getWidth();
        MockComponentsUtil.restoreSizeStyle(image, style);
        return width;
    }

    @Override
    public int getPreferredHeight() {
        // The superclass uses getOffsetHeight, which won't work for us.
        // Hide away the current 100% size so we can get at the actual size, otherwise automatic size doesn't work
        String[] style = MockComponentsUtil.clearSizeStyle(image);
        int height = image.getHeight();
        MockComponentsUtil.restoreSizeStyle(image, style);
        return height;
    }

    /**
     * This resizes the picture according to
     * 1. height and width value of the div tag enclosing the img tag
     * 2. scaling mode. 0 - Scale proportionally, 1 - Scale to fit
     *    which correspond to the choices in ScalingChoicePropertyEditor
     *
     * This should be called whenever a property affecting the size is changed
     */
    private void resizeImage() {
        if (image.getUrl().equals(getIconImage().getUrl())) {
            unclipImage();
            return;
        }

        String width = getElement().getStyle().getWidth();
        String height = getElement().getStyle().getHeight();

        // the situation right after refreshing the page
        if (width.isEmpty() || height.isEmpty()) {
            return;
        }

        int frameWidth = Ints.tryParse(width.substring(0, width.indexOf("px")));
        int frameHeight = Ints.tryParse(height.substring(0, height.indexOf("px")));

        if (scalingMode.equals("0")) {
            float ratio = Math.min(frameWidth / (float) getPreferredWidth(),
                    frameHeight / (float) getPreferredHeight());
            int scaledWidth = Double.valueOf(getPreferredWidth() * ratio).intValue();
            int scaledHeight = Double.valueOf(getPreferredHeight() * ratio).intValue();
            image.setSize(scaledWidth + "px", scaledHeight + "px");

        } else if (scalingMode.equals("1")) {
            image.setSize("100%", "100%");

        } else {
            throw new IllegalStateException("Illegal scaling mode: " + scalingMode);
        }
    }

    private void unclipImage() {
        Style style = image.getElement().getStyle();
        style.clearLeft();
        style.clearTop();
        style.clearWidth();
        style.clearHeight();
    }

    // PropertyChangeListener implementation

    @Override
    public void onPropertyChange(String propertyName, String newValue) {
        super.onPropertyChange(propertyName, newValue);

        if (propertyName.equals(PROPERTY_NAME_PICTURE)) {
            setPictureProperty(newValue); // setUrl() triggers onLoad
        } else if (propertyName.equals(PROPERTY_NAME_WIDTH)) {
            resizeImage();
            refreshForm();
        } else if (propertyName.equals(PROPERTY_NAME_HEIGHT)) {
            resizeImage();
            refreshForm();
        } else if (propertyName.equals(PROPERTY_SCALING)) {
            scalingMode = newValue;
            resizeImage();
            refreshForm();
        } else if (propertyName.equals(PROPERTY_SCALE_PICTURE_TO_FIT)) {
            boolean scaleIt = Boolean.parseBoolean(newValue);
            if (scaleIt) {
                scalingMode = "1";
            } else {
                scalingMode = "0";
            }
            resizeImage();
            refreshForm();
        }
    }
}