Home | History | Annotate | Download | only in videoeditor
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.videoeditor;
     18 
     19 import android.app.ActionBar;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.os.Bundle;
     25 import android.text.InputType;
     26 import android.util.DisplayMetrics;
     27 import android.util.Log;
     28 import android.view.Menu;
     29 import android.view.MenuItem;
     30 import android.view.View;
     31 import android.widget.AdapterView;
     32 import android.widget.Button;
     33 import android.widget.GridView;
     34 import android.widget.PopupMenu;
     35 import android.widget.TextView;
     36 import android.widget.Toast;
     37 
     38 import com.android.videoeditor.service.ApiService;
     39 import com.android.videoeditor.service.ApiServiceListener;
     40 import com.android.videoeditor.service.VideoEditorProject;
     41 import com.android.videoeditor.util.FileUtils;
     42 
     43 import java.util.List;
     44 
     45 /**
     46  * Activity that lets user pick a project or create a new one.
     47  */
     48 public class ProjectsActivity extends NoSearchActivity {
     49     private static final String LOG_TAG = "ProjectsActivity";
     50 
     51     private static final int REQUEST_CODE_OPEN_PROJECT = 1;
     52     private static final int REQUEST_CODE_CREATE_PROJECT = 2;
     53 
     54     // The project path returned by the picker
     55     public static final String PARAM_OPEN_PROJECT_PATH = "path";
     56     public static final String PARAM_CREATE_PROJECT_NAME = "name";
     57 
     58     // Menu ids
     59     private static final int MENU_NEW_PROJECT_ID = 1;
     60 
     61     // Dialog ids
     62     private static final int DIALOG_NEW_PROJECT_ID = 1;
     63     private static final int DIALOG_REMOVE_PROJECT_ID = 2;
     64 
     65     // Dialog parameters
     66     private static final String PARAM_DIALOG_PATH_ID = "path";
     67 
     68     // Threshold in width dip for showing title in action bar
     69     private static final int SHOW_TITLE_THRESHOLD_WIDTH_DIP = 1000;
     70 
     71     private GridView mGridView;
     72     private List<VideoEditorProject> mProjects;
     73     private ProjectPickerAdapter mAdapter;
     74 
     75     // Listener that responds to the event when projects are loaded. It populates the grid view with
     76     // project thumbnail and information.
     77     private final ApiServiceListener mProjectsLoadedListener = new ApiServiceListener() {
     78         @Override
     79         public void onProjectsLoaded(List<VideoEditorProject> projects, Exception exception) {
     80             if (projects != null && exception == null) {
     81                 mProjects = projects;
     82                 // Initialize adapter with project list and populate data in the grid view.
     83                 mAdapter = new ProjectPickerAdapter(ProjectsActivity.this, getLayoutInflater(), projects);
     84                 mGridView.setAdapter(mAdapter);
     85             }
     86         }
     87     };
     88 
     89     @Override
     90     public void onCreate(Bundle savedInstanceState) {
     91         super.onCreate(savedInstanceState);
     92         setContentView(R.layout.project_picker);
     93 
     94         // Show action bar title only on large screens.
     95         final ActionBar actionBar = getActionBar();
     96         final DisplayMetrics displayMetrics = new DisplayMetrics();
     97         getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
     98         final int widthDip = (int) (displayMetrics.widthPixels / displayMetrics.scaledDensity);
     99         // Only show title on large screens (width >= 1000 dip).
    100         if (widthDip >= SHOW_TITLE_THRESHOLD_WIDTH_DIP) {
    101             actionBar.setDisplayOptions(actionBar.getDisplayOptions() |
    102                     ActionBar.DISPLAY_SHOW_TITLE);
    103             actionBar.setTitle(R.string.full_app_name);
    104         }
    105 
    106         mGridView = (GridView) findViewById(R.id.projects);
    107         mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    108             @Override
    109             public void onItemClick(AdapterView<?> parent, View view,
    110                                     int position, long id) {
    111                 // If user clicks on the last item, then create a new project.
    112                 if (position == mProjects.size()) {
    113                     showDialog(DIALOG_NEW_PROJECT_ID);
    114                 } else {
    115                     openProject(mProjects.get(position).getPath());
    116                 }
    117             }
    118         });
    119         // Upon long press, pop up a menu with a removal option.
    120         mGridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    121             @Override
    122             public boolean onItemLongClick(AdapterView<?> parent, View view,
    123                                            final int position, long id) {
    124                 // Open new project dialog when user clicks on the "create new project" card.
    125                 if (position == mProjects.size()) {
    126                     showDialog(DIALOG_NEW_PROJECT_ID);
    127                     return true;
    128                 }
    129                 // Otherwise, pop up a menu with a project removal option.
    130                 final PopupMenu popupMenu = new PopupMenu(ProjectsActivity.this, view);
    131                 popupMenu.getMenuInflater().inflate(R.menu.project_menu, popupMenu.getMenu());
    132                 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    133                     @Override
    134                     public boolean onMenuItemClick(MenuItem menuItem) {
    135                         switch (menuItem.getItemId()) {
    136                             case R.id.action_remove_project:
    137                                 final Bundle bundle = new Bundle();
    138                                 bundle.putString(PARAM_DIALOG_PATH_ID,
    139                                         mProjects.get(position).getPath());
    140                                 showDialog(DIALOG_REMOVE_PROJECT_ID, bundle);
    141                                 break;
    142                             default:
    143                                 break;
    144                         }
    145                         return true;
    146                     }
    147                 });
    148                 popupMenu.show();
    149                 return true;
    150             }});
    151     }
    152 
    153     @Override
    154     public void onResume() {
    155         super.onResume();
    156         ApiService.registerListener(mProjectsLoadedListener);
    157         ApiService.loadProjects(this);
    158     }
    159 
    160     @Override
    161     public void onPause() {
    162         super.onPause();
    163         ApiService.unregisterListener(mProjectsLoadedListener);
    164         mAdapter = null;
    165         mGridView.setAdapter(null);
    166     }
    167 
    168     @Override
    169     public boolean onCreateOptionsMenu(Menu menu) {
    170         menu.add(Menu.NONE, MENU_NEW_PROJECT_ID, Menu.NONE, R.string.projects_new_project)
    171                 .setIcon(R.drawable.ic_menu_add_video)
    172                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
    173         return true;
    174     }
    175 
    176     @Override
    177     public boolean onOptionsItemSelected(MenuItem item) {
    178         switch (item.getItemId()) {
    179             case MENU_NEW_PROJECT_ID: {
    180                 showDialog(DIALOG_NEW_PROJECT_ID);
    181                 return true;
    182             }
    183 
    184             default: {
    185                 return false;
    186             }
    187         }
    188     }
    189 
    190     @Override
    191     public Dialog onCreateDialog(int id, final Bundle bundle) {
    192         switch (id) {
    193             case DIALOG_NEW_PROJECT_ID: {
    194                 return AlertDialogs.createEditDialog(
    195                         this,
    196                         null,  // No title
    197                         null,  // No text in the edit box
    198                         getString(android.R.string.ok),
    199                         new DialogInterface.OnClickListener() {
    200                             @Override
    201                             public void onClick(DialogInterface dialog, int which) {
    202                                 final TextView tv =
    203                                     (TextView)((AlertDialog)dialog).findViewById(R.id.text_1);
    204                                 final String projectName = tv.getText().toString();
    205                                 removeDialog(DIALOG_NEW_PROJECT_ID);
    206                                 createProject(projectName);
    207                             }
    208                         },
    209                         getString(android.R.string.cancel),
    210                         new DialogInterface.OnClickListener() {
    211                             @Override
    212                             public void onClick(DialogInterface dialog, int which) {
    213                                 removeDialog(DIALOG_NEW_PROJECT_ID);
    214                             }
    215                         },
    216                         new DialogInterface.OnCancelListener() {
    217                             @Override
    218                             public void onCancel(DialogInterface dialog) {
    219                                 removeDialog(DIALOG_NEW_PROJECT_ID);
    220                             }
    221                         },
    222                         InputType.TYPE_NULL,
    223                         32,
    224                         getString(R.string.projects_project_name));
    225             }
    226 
    227             case DIALOG_REMOVE_PROJECT_ID: {
    228                 final String projectPath = bundle.getString(PARAM_DIALOG_PATH_ID);
    229                 return AlertDialogs.createAlert(
    230                         this,
    231                         getString(R.string.editor_delete_project),
    232                         0,  // no icons for this dialog.
    233                         getString(R.string.editor_delete_project_question),
    234                         getString(R.string.yes),
    235                         new DialogInterface.OnClickListener() {
    236                             @Override
    237                             public void onClick(DialogInterface dialog, int which) {
    238                                 removeDialog(DIALOG_REMOVE_PROJECT_ID);
    239                                 deleteProject(projectPath);
    240                             }
    241                         },
    242                         getString(R.string.no),
    243                         new DialogInterface.OnClickListener() {
    244                             @Override
    245                             public void onClick(DialogInterface dialog, int which) {
    246                                 removeDialog(DIALOG_REMOVE_PROJECT_ID);
    247                             }
    248                         },
    249                         new DialogInterface.OnCancelListener() {
    250                             @Override
    251                             public void onCancel(DialogInterface dialog) {
    252                                 removeDialog(DIALOG_REMOVE_PROJECT_ID);
    253                             }
    254                         },
    255                         true);
    256             }
    257 
    258             default: {
    259                 return null;
    260             }
    261         }
    262     }
    263 
    264     @Override
    265     protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
    266         switch (id) {
    267             // A workaround to handle the OK button. We can't access the button with getButton()
    268             // when building the dialog in AlertDialogs, hence we postpone the enabling/disabling
    269             // of the positive button until the dialog is to be shown here.
    270             case DIALOG_NEW_PROJECT_ID:
    271                 final AlertDialog newProjectDialog = (AlertDialog) dialog;
    272                 Button positiveButton = newProjectDialog.getButton(AlertDialog.BUTTON_POSITIVE);
    273                 final TextView inputField =
    274                         (TextView) newProjectDialog.findViewById(R.id.text_1);
    275                 positiveButton.setEnabled(inputField.getText().toString().trim().length() > 0);
    276             default:
    277                 return;
    278         }
    279     }
    280 
    281     private void deleteProject(final String projectPath) {
    282         ApiService.deleteProject(ProjectsActivity.this, projectPath);
    283         mAdapter.remove(projectPath);
    284     }
    285 
    286     private void createProject(String projectName) {
    287         try {
    288             final Intent intent = new Intent(this, VideoEditorActivity.class);
    289             intent.setAction(Intent.ACTION_INSERT);
    290             intent.putExtra(PARAM_CREATE_PROJECT_NAME, projectName);
    291             final String projectPath = FileUtils.createNewProjectPath(this);
    292             intent.putExtra(PARAM_OPEN_PROJECT_PATH, projectPath);
    293             startActivityForResult(intent, REQUEST_CODE_CREATE_PROJECT);
    294         } catch (Exception ex) {
    295             ex.printStackTrace();
    296             Toast.makeText(this, R.string.editor_storage_not_available,
    297                     Toast.LENGTH_LONG).show();
    298         }
    299     }
    300 
    301     private void openProject(String projectPath) {
    302         final Intent intent = new Intent(this, VideoEditorActivity.class);
    303         intent.setAction(Intent.ACTION_EDIT);
    304         intent.putExtra(PARAM_OPEN_PROJECT_PATH, projectPath);
    305         startActivityForResult(intent, REQUEST_CODE_OPEN_PROJECT);
    306     }
    307 
    308     private static void logd(String message) {
    309         if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
    310             Log.d(LOG_TAG, message);
    311         }
    312     }
    313 }
    314