com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor.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

package com.google.appinventor.client.editor.youngandroid.properties;

import static com.google.appinventor.client.Ode.MESSAGES;
import com.google.appinventor.client.editor.simple.components.MockVisibleComponent;
import com.google.appinventor.client.widgets.properties.AdditionalChoicePropertyEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Property editor for length properties (i.e. width and height).
 *
 */
public class YoungAndroidLengthPropertyEditor extends AdditionalChoicePropertyEditor {
    public static final String CONST_AUTOMATIC = "" + MockVisibleComponent.LENGTH_PREFERRED;
    public static final String CONST_FILL_PARENT = "" + MockVisibleComponent.LENGTH_FILL_PARENT;

    private static int uniqueIdSeed = 0;

    private final RadioButton automaticRadioButton;
    private final RadioButton fillParentRadioButton;
    private final RadioButton customLengthRadioButton;
    private final RadioButton percentfillRadioButton;
    private final TextBox customLengthField;
    private final TextBox percentLengthField;

    public YoungAndroidLengthPropertyEditor() {
        this(true);
    }

    /**
     * Creates a new length property editor.
     *
     * @param includePercent  whether to include percent of screen option
     */
    public YoungAndroidLengthPropertyEditor(boolean includePercent) {
        // The radio button group cannot be shared across all instances, so we append a unique id.
        int uniqueId = ++uniqueIdSeed;
        String radioButtonGroup = "LengthType-" + uniqueId;
        automaticRadioButton = new RadioButton(radioButtonGroup, MESSAGES.automaticCaption());
        fillParentRadioButton = new RadioButton(radioButtonGroup, MESSAGES.fillParentCaption());
        percentfillRadioButton = new RadioButton(radioButtonGroup);
        customLengthRadioButton = new RadioButton(radioButtonGroup);
        customLengthField = new TextBox();
        customLengthField.setVisibleLength(4);
        customLengthField.setMaxLength(4);
        percentLengthField = new TextBox();
        percentLengthField.setVisibleLength(4);
        percentLengthField.setMaxLength(4);

        Panel customRow = new HorizontalPanel();
        customRow.add(customLengthRadioButton);
        customRow.add(customLengthField);
        Label pixels = new Label(MESSAGES.pixelsCaption());
        pixels.setStylePrimaryName("ode-PixelsLabel");
        customRow.add(pixels);

        Panel percentRow = new HorizontalPanel();
        percentRow.add(percentfillRadioButton);
        percentRow.add(percentLengthField);
        Label percent = new Label(MESSAGES.percentCaption());
        percent.setStylePrimaryName("ode-PixelsLabel"); // recycle css definition
        percentRow.add(percent);

        Panel panel = new VerticalPanel();
        panel.add(automaticRadioButton);
        panel.add(fillParentRadioButton);
        panel.add(customRow);

        if (includePercent) {
            panel.add(percentRow);
        }

        automaticRadioButton.addValueChangeHandler(new ValueChangeHandler() {
            @Override
            public void onValueChange(ValueChangeEvent event) {
                // Clear the custom and percent length fields.
                customLengthField.setText("");
                percentLengthField.setText("");
            }
        });
        fillParentRadioButton.addValueChangeHandler(new ValueChangeHandler() {
            @Override
            public void onValueChange(ValueChangeEvent event) {
                // Clear the custom and percent length fields.
                customLengthField.setText("");
                percentLengthField.setText("");
            }
        });
        customLengthField.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                // If the user clicks on the custom length field, but the radio button for a custom length
                // is not checked, check it.
                if (!customLengthRadioButton.isChecked()) {
                    customLengthRadioButton.setChecked(true);
                    percentLengthField.setText("");
                }
            }
        });

        percentLengthField.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                // If the user clicks on the percent length field, but the radio button for a custom length
                // is not checked, check it.
                if (!percentfillRadioButton.isChecked()) {
                    percentfillRadioButton.setChecked(true);
                    customLengthField.setText("");
                }
            }
        });

        initAdditionalChoicePanel(panel);
    }

    @Override
    protected void updateValue() {
        super.updateValue();

        String propertyValue = property.getValue();
        if (propertyValue.equals(CONST_AUTOMATIC)) {
            automaticRadioButton.setChecked(true);
        } else if (propertyValue.equals(CONST_FILL_PARENT)) {
            fillParentRadioButton.setChecked(true);
        } else {
            int v = Integer.parseInt(propertyValue);
            if (v <= MockVisibleComponent.LENGTH_PERCENT_TAG) {
                v = (-v) + MockVisibleComponent.LENGTH_PERCENT_TAG;
                percentfillRadioButton.setChecked(true);
                percentLengthField.setText("" + v);
            } else {
                customLengthRadioButton.setChecked(true);
                customLengthField.setText(propertyValue);
            }
        }
    }

    @Override
    protected String getPropertyValueSummary() {
        String lengthHint = property.getValue();
        if (lengthHint.equals(CONST_AUTOMATIC)) {
            return MESSAGES.automaticCaption();
        } else if (lengthHint.equals(CONST_FILL_PARENT)) {
            return MESSAGES.fillParentCaption();
        } else {
            int v = Integer.parseInt(lengthHint);
            if (v <= MockVisibleComponent.LENGTH_PERCENT_TAG) {
                v = (-v) + MockVisibleComponent.LENGTH_PERCENT_TAG;
                return MESSAGES.percentSummary("" + v);
            } else {
                return MESSAGES.pixelsSummary(lengthHint);
            }
        }
    }

    @Override
    protected boolean okAction() {
        if (automaticRadioButton.isChecked()) {
            property.setValue(CONST_AUTOMATIC);
        } else if (fillParentRadioButton.isChecked()) {
            property.setValue(CONST_FILL_PARENT);
        } else if (customLengthRadioButton.isChecked()) {
            // Custom length
            String text = customLengthField.getText();
            // Make sure it's a non-negative number.  It is important
            // that this check stay within the custom length case because
            // CONST_AUTOMATIC and CONST_FILL_PARENT are deliberately negative.
            boolean success = false;
            try {
                if (Integer.parseInt(text) >= 0) {
                    success = true;
                }
            } catch (NumberFormatException e) {
                // fall through with success == false
            }
            if (!success) {
                Window.alert(MESSAGES.nonnumericInputError());
                return false;
            }
            property.setValue(text);
        } else { // Percent field!
            String text = percentLengthField.getText();
            boolean success = false;
            try {
                int v = Integer.parseInt(text);
                if (v > 0 && v <= 100) {
                    success = true;
                    property.setValue("" + (-v + MockVisibleComponent.LENGTH_PERCENT_TAG));
                }
            } catch (NumberFormatException e) {
                // fall through with success == false
            }
            if (!success) {
                Window.alert(MESSAGES.nonvalidPercentValue());
                return false;
            }
        }
        return true;
    }
}