org.catrobat.catroid.ui.dialogs.NewSpriteDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.catrobat.catroid.ui.dialogs.NewSpriteDialog.java

Source

/*
 * Catroid: An on-device visual programming system for Android devices
 * Copyright (C) 2010-2015 The Catrobat Team
 * (<http://developer.catrobat.org/credits>)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * An additional term exception under section 7 of the GNU Affero
 * General Public License, version 3, is available at
 * http://developer.catrobat.org/license_additional_term
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.catrobat.catroid.ui.dialogs;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.DialogFragment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;

import com.google.common.io.Files;

import org.catrobat.catroid.ProjectManager;
import org.catrobat.catroid.R;
import org.catrobat.catroid.common.Constants;
import org.catrobat.catroid.common.LookData;
import org.catrobat.catroid.content.Sprite;
import org.catrobat.catroid.content.bricks.PointToBrick.SpinnerAdapterWrapper;
import org.catrobat.catroid.io.StorageHandler;
import org.catrobat.catroid.ui.ProgramMenuActivity;
import org.catrobat.catroid.ui.ScriptActivity;
import org.catrobat.catroid.ui.WebViewActivity;
import org.catrobat.catroid.ui.controller.LookController;
import org.catrobat.catroid.ui.fragment.SpritesListFragment;
import org.catrobat.catroid.utils.ImageEditing;
import org.catrobat.catroid.utils.UtilCamera;
import org.catrobat.catroid.utils.Utils;

import java.io.File;
import java.io.IOException;

public class NewSpriteDialog extends DialogFragment {

    public static final String DIALOG_FRAGMENT_TAG = "dialog_new_sprite";
    public static final String TAG = NewSpriteDialog.class.getSimpleName();

    private static final int REQUEST_SELECT_IMAGE = 0;
    private static final int REQUEST_CREATE_POCKET_PAINT_IMAGE = 1;
    private static final int REQUEST_TAKE_PICTURE = 2;
    private static final int REQUEST_MEDIA_LIBRARY = 3;
    private final ActionAfterFinished requestedAction;
    private final DialogWizardStep wizardStep;
    private Uri lookUri;
    private View dialogView;
    private String newObjectName = null;
    private SpinnerAdapterWrapper spinnerAdapter;

    public NewSpriteDialog() {
        this.requestedAction = ActionAfterFinished.ACTION_FORWARD_TO_NEW_OBJECT;
        this.wizardStep = DialogWizardStep.STEP_1;
    }

    public NewSpriteDialog(SpinnerAdapterWrapper spinnerAdapter) {
        this.requestedAction = ActionAfterFinished.ACTION_UPDATE_SPINNER;
        this.spinnerAdapter = spinnerAdapter;
        this.wizardStep = DialogWizardStep.STEP_1;
    }

    private NewSpriteDialog(DialogWizardStep wizardStep, Uri lookUri, String newObjectName,
            ActionAfterFinished requestedAction, SpinnerAdapterWrapper spinnerAdapter) {
        this.requestedAction = requestedAction;
        this.wizardStep = wizardStep;
        this.lookUri = lookUri;
        this.newObjectName = newObjectName;
        this.spinnerAdapter = spinnerAdapter;
    }

    static NewSpriteDialog newInstance() {
        NewSpriteDialog newSpriteDialog = new NewSpriteDialog();

        Bundle arguments = new Bundle();
        arguments.putInt(ActionAfterFinished.KEY, ActionAfterFinished.ACTION_FORWARD_TO_NEW_OBJECT.ordinal());
        arguments.putInt(DialogWizardStep.KEY, DialogWizardStep.STEP_1.ordinal());
        newSpriteDialog.setArguments(arguments);
        return newSpriteDialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_new_object, null);
        setupPaintroidButton(dialogView);
        setupGalleryButton(dialogView);
        setupCameraButton(dialogView);
        setupMediaLibraryButton(dialogView);

        AlertDialog dialog = null;
        AlertDialog.Builder dialogBuilder = new CustomAlertDialogBuilder(getActivity()).setView(dialogView)
                .setTitle(R.string.new_sprite_dialog_title);
        if (wizardStep == DialogWizardStep.STEP_1) {
            dialog = createDialogStepOne(dialogBuilder);
        } else if (wizardStep == DialogWizardStep.STEP_2) {
            dialog = createDialogStepTwo(dialogBuilder);
        }
        dialog.setOnShowListener(new DialogInterface.OnShowListener() {

            @Override
            public void onShow(final DialogInterface dialog) {
                Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
                button.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {
                        if (handleOkButton()) {
                            dialog.dismiss();
                        }
                    }
                });
            }
        });
        dialog.setCanceledOnTouchOutside(true);
        dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        return dialog;
    }

    private AlertDialog createDialogStepOne(AlertDialog.Builder dialogBuilder) {
        AlertDialog dialog = dialogBuilder.create();
        dialogView.findViewById(R.id.dialog_new_object_step_2_layout).setVisibility(View.GONE);
        return dialog;
    }

    private AlertDialog createDialogStepTwo(AlertDialog.Builder dialogBuilder) {
        AlertDialog dialog = dialogBuilder.setPositiveButton(R.string.ok, null)
                .setNegativeButton(R.string.cancel_button, null).create();

        dialogView.findViewById(R.id.dialog_new_object_step_1_layout).setVisibility(View.GONE);
        dialogView.findViewById(R.id.dialog_new_object_second_row).setVisibility(View.GONE);

        ImageView imageView = (ImageView) dialogView.findViewById(R.id.dialog_new_object_look_preview);
        if (newObjectName == null) {
            newObjectName = getString(R.string.new_sprite_dialog_default_sprite_name);
        }
        newObjectName = Utils.getUniqueObjectName(newObjectName);

        DisplayMetrics metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

        int[] imageDimensions = ImageEditing.getImageDimensions(lookUri.getPath());

        while (metrics.widthPixels < imageDimensions[0] && metrics.heightPixels < imageDimensions[1]) {
            imageDimensions[0] = imageDimensions[0] / 2;
            imageDimensions[1] = imageDimensions[1] / 2;
        }

        imageView.setImageBitmap(ImageEditing.getScaledBitmapFromPath(lookUri.getPath(), imageDimensions[0],
                imageDimensions[1], ImageEditing.ResizeType.STAY_IN_RECTANGLE_WITH_SAME_ASPECT_RATIO, true));

        EditText editTextNewObject = (EditText) dialogView.findViewById(R.id.dialog_new_object_name_edit_text);
        editTextNewObject.setHint(newObjectName);
        return dialog;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (lookUri == null) {
                lookUri = UtilCamera.getDefaultLookFromCameraUri(getString(R.string.default_look_name));
            }

            try {
                switch (requestCode) {
                case REQUEST_CREATE_POCKET_PAINT_IMAGE:
                    lookUri = Uri.parse(data.getExtras().getString(Constants.EXTRA_PICTURE_PATH_POCKET_PAINT));
                    break;
                case REQUEST_SELECT_IMAGE:
                    lookUri = decodeUri(data.getData());
                    newObjectName = new File(lookUri.toString()).getName();
                    break;
                case REQUEST_TAKE_PICTURE:
                    lookUri = UtilCamera.rotatePictureIfNecessary(lookUri, getString(R.string.default_look_name));
                    break;
                case REQUEST_MEDIA_LIBRARY:
                    lookUri = Uri.parse(data.getStringExtra(WebViewActivity.MEDIA_FILE_PATH));
                    newObjectName = Files.getNameWithoutExtension(lookUri.toString());
                    break;
                default:
                    return;
                }

                NewSpriteDialog dialog = new NewSpriteDialog(DialogWizardStep.STEP_2, lookUri, newObjectName,
                        requestedAction, spinnerAdapter);
                dialog.show(getActivity().getSupportFragmentManager(), NewSpriteDialog.DIALOG_FRAGMENT_TAG);
                dismiss();
            } catch (NullPointerException e) {
                Utils.showErrorDialog(getActivity(), R.string.error_load_image);
                Log.e(TAG, Log.getStackTraceString(e));
            }
        } else {
            dismiss();
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (spinnerAdapter != null) {
            spinnerAdapter.updateSpinner();
        }
    }

    private Uri decodeUri(Uri uri) throws NullPointerException {
        String[] filePathColumn = { MediaStore.Images.Media.DATA };
        Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndexOrThrow(filePathColumn[0]);
        Uri decodedUri = Uri.parse(cursor.getString(columnIndex));
        cursor.close();

        return decodedUri;
    }

    private void setupPaintroidButton(View parentView) {
        View paintroidButton = parentView.findViewById(R.id.dialog_new_object_paintroid);

        final Intent intent = new Intent("android.intent.action.MAIN");
        intent.setComponent(new ComponentName(Constants.POCKET_PAINT_PACKAGE_NAME,
                Constants.POCKET_PAINT_INTENT_ACTIVITY_NAME));

        paintroidButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (LookController.getInstance().checkIfPocketPaintIsInstalled(intent, getActivity())) {
                    Intent intent = new Intent("android.intent.action.MAIN");
                    intent.setComponent(new ComponentName(Constants.POCKET_PAINT_PACKAGE_NAME,
                            Constants.POCKET_PAINT_INTENT_ACTIVITY_NAME));

                    Bundle bundleForPocketPaint = new Bundle();
                    bundleForPocketPaint.putString(Constants.EXTRA_PICTURE_PATH_POCKET_PAINT, "");
                    bundleForPocketPaint.putString(Constants.EXTRA_PICTURE_NAME_POCKET_PAINT,
                            getString(R.string.default_look_name));
                    intent.putExtras(bundleForPocketPaint);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, lookUri);

                    intent.addCategory("android.intent.category.LAUNCHER");
                    startActivityForResult(intent, REQUEST_CREATE_POCKET_PAINT_IMAGE);
                }
            }
        });
    }

    private void setupGalleryButton(View parentView) {
        View galleryButton = parentView.findViewById(R.id.dialog_new_object_gallery);

        galleryButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, lookUri);
                startActivityForResult(intent, REQUEST_SELECT_IMAGE);
            }
        });
    }

    private void setupCameraButton(View parentView) {
        View cameraButton = parentView.findViewById(R.id.dialog_new_object_camera);

        cameraButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                lookUri = UtilCamera.getDefaultLookFromCameraUri(getString(R.string.default_look_name));

                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, lookUri);
                startActivityForResult(intent, REQUEST_TAKE_PICTURE);
            }
        });
    }

    private void setupMediaLibraryButton(View parentView) {
        View mediaButton = parentView.findViewById(R.id.dialog_new_object_library);

        mediaButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getActivity(), WebViewActivity.class);
                String url = Constants.LIBRARY_LOOKS_URL;
                intent.putExtra(WebViewActivity.INTENT_PARAMETER_URL, url);
                intent.putExtra(WebViewActivity.CALLING_ACTIVITY, SpritesListFragment.TAG);
                startActivityForResult(intent, REQUEST_MEDIA_LIBRARY);
            }
        });
    }

    private boolean handleOkButton() {
        EditText editText = (EditText) dialogView.findViewById(R.id.dialog_new_object_name_edit_text);
        String newSpriteName;
        if (editText.length() == 0) {
            newSpriteName = editText.getHint().toString();
        } else {
            newSpriteName = editText.getText().toString().trim();
        }
        if (newSpriteName.contains(".")) {
            int fileExtensionPosition = newSpriteName.indexOf('.');
            newSpriteName = newSpriteName.substring(0, fileExtensionPosition);
        }

        ProjectManager projectManager = ProjectManager.getInstance();

        if (newSpriteName.equalsIgnoreCase("")) {
            Utils.showErrorDialog(getActivity(), R.string.no_name, R.string.no_spritename_entered);
            return false;
        }

        if (projectManager.spriteExists(newSpriteName)) {
            Utils.showErrorDialog(getActivity(), R.string.name_exists, R.string.spritename_already_exists);
            return false;
        }

        Sprite sprite = new Sprite(newSpriteName);
        projectManager.addSprite(sprite);

        LookData lookData;
        try {
            File newLookFile = StorageHandler.getInstance().copyImage(projectManager.getCurrentProject().getName(),
                    lookUri.getPath(), null);
            if (lookUri.getPath().contains(Constants.TMP_LOOKS_PATH)) {
                File oldFile = new File(lookUri.getPath());
                oldFile.delete();
            }
            String imageFileName = newLookFile.getName();
            Utils.rewriteImageFileForStage(getActivity(), newLookFile);

            lookData = new LookData();
            lookData.setLookFilename(imageFileName);
            lookData.setLookName(newSpriteName);
        } catch (IOException ioException) {
            Utils.showErrorDialog(getActivity(), R.string.error_load_image);
            Log.e(TAG, Log.getStackTraceString(ioException));
            return false;
        } catch (NullPointerException e) {
            Utils.showErrorDialog(getActivity(), R.string.error_load_image);
            Log.e(TAG, "somebody might have selected an image and deleted it before it was added");
            Log.e(TAG, Log.getStackTraceString(e));
            return false;
        }

        sprite.getLookDataList().add(lookData);

        if (requestedAction == ActionAfterFinished.ACTION_UPDATE_SPINNER && spinnerAdapter != null) {
            Intent broadcastIntent;
            broadcastIntent = new Intent(ScriptActivity.ACTION_BRICK_LIST_CHANGED);
            getActivity().sendBroadcast(broadcastIntent);
            spinnerAdapter.refreshSpinnerAfterNewSprite(getActivity(), newSpriteName);
        } else {
            Intent broadcastIntent;
            broadcastIntent = new Intent(ScriptActivity.ACTION_SPRITES_LIST_CHANGED);
            getActivity().sendBroadcast(broadcastIntent);
        }

        if (requestedAction == ActionAfterFinished.ACTION_FORWARD_TO_NEW_OBJECT) {
            projectManager.setCurrentSprite(sprite);

            Intent intent = new Intent(getActivity(), ProgramMenuActivity.class);
            intent.putExtra(ProgramMenuActivity.FORWARD_TO_SCRIPT_ACTIVITY, ScriptActivity.FRAGMENT_SCRIPTS);
            startActivity(intent);
        }
        dismiss();
        return true;
    }

    public enum ActionAfterFinished {
        ACTION_FORWARD_TO_NEW_OBJECT, ACTION_UPDATE_SPINNER;
        static final String KEY = "action";
    }

    public enum DialogWizardStep {
        STEP_1, STEP_2;
        static final String KEY = "step";
    }
}