Java tutorial
/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2014 The Catrobat Team * (<http://developer.fyp14017.hku/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.fyp14017.hku/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.hku/licenses/>. */ package hku.fyp14017.blencode.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 hku.fyp14017.blencode.ProjectManager; import hku.fyp14017.blencode.R; import hku.fyp14017.blencode.common.Constants; import hku.fyp14017.blencode.common.LookData; import hku.fyp14017.blencode.content.Sprite; import hku.fyp14017.blencode.content.bricks.PointToBrick.SpinnerAdapterWrapper; import hku.fyp14017.blencode.io.StorageHandler; import hku.fyp14017.blencode.ui.ProgramMenuActivity; import hku.fyp14017.blencode.ui.ScriptActivity; import hku.fyp14017.blencode.ui.controller.LookController; import hku.fyp14017.blencode.utils.ImageEditing; import hku.fyp14017.blencode.utils.UtilCamera; import hku.fyp14017.blencode.utils.Utils; import java.io.File; import java.io.IOException; import hku.fyp14017.blencode.ProjectManager; import hku.fyp14017.blencode.common.Constants; import hku.fyp14017.blencode.common.LookData; import hku.fyp14017.blencode.content.bricks.PointToBrick; import hku.fyp14017.blencode.ui.ProgramMenuActivity; import hku.fyp14017.blencode.ui.ScriptActivity; import hku.fyp14017.blencode.utils.ImageEditing; import hku.fyp14017.blencode.utils.UtilCamera; 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 final ActionAfterFinished requestedAction; private final DialogWizardStep wizardStep; private Uri lookUri; private View dialogView; private String newObjectName = null; private PointToBrick.SpinnerAdapterWrapper spinnerAdapter; public NewSpriteDialog() { this.requestedAction = ActionAfterFinished.ACTION_FORWARD_TO_NEW_OBJECT; this.wizardStep = DialogWizardStep.STEP_1; } public NewSpriteDialog(PointToBrick.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, PointToBrick.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(hku.fyp14017.blencode.R.layout.dialog_new_object, null); setupPaintroidButton(dialogView); setupGalleryButton(dialogView); setupCameraButton(dialogView); AlertDialog dialog = null; AlertDialog.Builder dialogBuilder = new CustomAlertDialogBuilder(getActivity()).setView(dialogView) .setTitle(hku.fyp14017.blencode.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(hku.fyp14017.blencode.R.id.dialog_new_object_step_2_layout) .setVisibility(View.GONE); return dialog; } private AlertDialog createDialogStepTwo(AlertDialog.Builder dialogBuilder) { AlertDialog dialog = dialogBuilder.setPositiveButton(hku.fyp14017.blencode.R.string.ok, null) .setNegativeButton(hku.fyp14017.blencode.R.string.cancel_button, null).create(); dialogView.findViewById(hku.fyp14017.blencode.R.id.dialog_new_object_step_1_layout) .setVisibility(View.GONE); ImageView imageView = (ImageView) dialogView .findViewById(hku.fyp14017.blencode.R.id.dialog_new_object_look_preview); if (newObjectName == null) { newObjectName = getString(hku.fyp14017.blencode.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(hku.fyp14017.blencode.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(hku.fyp14017.blencode.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(hku.fyp14017.blencode.R.string.default_look_name)); 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(), hku.fyp14017.blencode.R.string.error_load_image); Log.e(TAG, Log.getStackTraceString(e)); } } } @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(hku.fyp14017.blencode.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(hku.fyp14017.blencode.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(hku.fyp14017.blencode.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(hku.fyp14017.blencode.R.id.dialog_new_object_camera); cameraButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { lookUri = UtilCamera .getDefaultLookFromCameraUri(getString(hku.fyp14017.blencode.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 boolean handleOkButton() { EditText editText = (EditText) dialogView .findViewById(hku.fyp14017.blencode.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(), hku.fyp14017.blencode.R.string.spritename_invalid); return false; } if (projectManager.spriteExists(newSpriteName)) { Utils.showErrorDialog(getActivity(), hku.fyp14017.blencode.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); String imageFileName = newLookFile.getName(); Utils.rewriteImageFileForStage(getActivity(), newLookFile); lookData = new LookData(); lookData.setLookFilename(imageFileName); lookData.setLookName(newSpriteName); } catch (IOException ioException) { Utils.showErrorDialog(getActivity(), hku.fyp14017.blencode.R.string.error_load_image); Log.e(TAG, Log.getStackTraceString(ioException)); return false; } catch (NullPointerException e) { Utils.showErrorDialog(getActivity(), hku.fyp14017.blencode.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"; } }