Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2008 Esmertec AG.
      3  * Copyright (C) 2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.ui;
     19 
     20 import com.android.mms.R;
     21 import android.drm.mobile1.DrmException;
     22 import com.android.mms.model.AudioModel;
     23 import com.android.mms.model.ImageModel;
     24 import com.android.mms.model.LayoutModel;
     25 import com.android.mms.model.MediaModel;
     26 import com.android.mms.model.Model;
     27 import com.android.mms.model.RegionMediaModel;
     28 import com.android.mms.model.RegionModel;
     29 import com.android.mms.model.SlideModel;
     30 import com.android.mms.model.SlideshowModel;
     31 import com.android.mms.model.TextModel;
     32 import com.android.mms.model.VideoModel;
     33 import com.android.mms.model.MediaModel.MediaAction;
     34 import com.android.mms.ui.AdaptableSlideViewInterface.OnSizeChangedListener;
     35 import com.android.mms.util.ItemLoadedCallback;
     36 
     37 import android.content.Context;
     38 import android.os.Handler;
     39 import android.util.Log;
     40 import android.widget.Toast;
     41 
     42 /**
     43  * A basic presenter of slides.
     44  */
     45 public class SlideshowPresenter extends Presenter {
     46     private static final String TAG = "SlideshowPresenter";
     47     private static final boolean DEBUG = false;
     48     private static final boolean LOCAL_LOGV = false;
     49 
     50     protected int mLocation;
     51     protected final int mSlideNumber;
     52 
     53     protected float mWidthTransformRatio = 1.0f;
     54     protected float mHeightTransformRatio = 1.0f;
     55 
     56     // Since only the original thread that created a view hierarchy can touch
     57     // its views, we have to use Handler to manage the views in the some
     58     // callbacks such as onModelChanged().
     59     protected final Handler mHandler = new Handler();
     60 
     61     public SlideshowPresenter(Context context, ViewInterface view, Model model) {
     62         super(context, view, model);
     63         mLocation = 0;
     64         mSlideNumber = ((SlideshowModel) mModel).size();
     65 
     66         if (view instanceof AdaptableSlideViewInterface) {
     67             ((AdaptableSlideViewInterface) view).setOnSizeChangedListener(
     68                     mViewSizeChangedListener);
     69         }
     70     }
     71 
     72     private final OnSizeChangedListener mViewSizeChangedListener =
     73         new OnSizeChangedListener() {
     74         public void onSizeChanged(int width, int height) {
     75             LayoutModel layout = ((SlideshowModel) mModel).getLayout();
     76             mWidthTransformRatio = getWidthTransformRatio(
     77                     width, layout.getLayoutWidth());
     78             mHeightTransformRatio = getHeightTransformRatio(
     79                     height, layout.getLayoutHeight());
     80             // The ratio indicates how to reduce the source to match the View,
     81             // so the larger one should be used.
     82             float ratio = mWidthTransformRatio > mHeightTransformRatio ?
     83                     mWidthTransformRatio : mHeightTransformRatio;
     84             mWidthTransformRatio = ratio;
     85             mHeightTransformRatio = ratio;
     86             if (LOCAL_LOGV) {
     87                 Log.v(TAG, "ratio_w = " + mWidthTransformRatio
     88                         + ", ratio_h = " + mHeightTransformRatio);
     89             }
     90         }
     91     };
     92 
     93     private float getWidthTransformRatio(int width, int layoutWidth) {
     94         if (width > 0) {
     95             return (float) layoutWidth / (float) width;
     96         }
     97         return 1.0f;
     98     }
     99 
    100     private float getHeightTransformRatio(int height, int layoutHeight) {
    101         if (height > 0) {
    102             return (float) layoutHeight / (float) height;
    103         }
    104         return 1.0f;
    105     }
    106 
    107     private int transformWidth(int width) {
    108         return (int) (width / mWidthTransformRatio);
    109     }
    110 
    111     private int transformHeight(int height) {
    112         return (int) (height / mHeightTransformRatio);
    113     }
    114 
    115     @Override
    116     public void present(ItemLoadedCallback callback) {
    117         // This is called to show a full-screen slideshow. Presently, all parts of
    118         // a slideshow (images, sounds, etc.) are loaded and displayed on the UI thread.
    119         presentSlide((SlideViewInterface) mView, ((SlideshowModel) mModel).get(mLocation));
    120     }
    121 
    122     /**
    123      * @param view
    124      * @param model
    125      */
    126     protected void presentSlide(SlideViewInterface view, SlideModel model) {
    127         view.reset();
    128 
    129         for (MediaModel media : model) {
    130             if (media instanceof RegionMediaModel) {
    131                 presentRegionMedia(view, (RegionMediaModel) media, true);
    132             } else if (media.isAudio()) {
    133                 presentAudio(view, (AudioModel) media, true);
    134             }
    135         }
    136     }
    137 
    138     /**
    139      * @param view
    140      */
    141     protected void presentRegionMedia(SlideViewInterface view,
    142             RegionMediaModel rMedia, boolean dataChanged) {
    143         RegionModel r = (rMedia).getRegion();
    144         if (rMedia.isText()) {
    145             presentText(view, (TextModel) rMedia, r, dataChanged);
    146         } else if (rMedia.isImage()) {
    147             presentImage(view, (ImageModel) rMedia, r, dataChanged);
    148         } else if (rMedia.isVideo()) {
    149             presentVideo(view, (VideoModel) rMedia, r, dataChanged);
    150         }
    151     }
    152 
    153     protected void presentAudio(SlideViewInterface view, AudioModel audio,
    154             boolean dataChanged) {
    155         // Set audio only when data changed.
    156         if (dataChanged) {
    157             view.setAudio(audio.getUri(), audio.getSrc(), audio.getExtras());
    158         }
    159 
    160         MediaAction action = audio.getCurrentAction();
    161         if (action == MediaAction.START) {
    162             view.startAudio();
    163         } else if (action == MediaAction.PAUSE) {
    164             view.pauseAudio();
    165         } else if (action == MediaAction.STOP) {
    166             view.stopAudio();
    167         } else if (action == MediaAction.SEEK) {
    168             view.seekAudio(audio.getSeekTo());
    169         }
    170     }
    171 
    172     protected void presentText(SlideViewInterface view, TextModel text,
    173             RegionModel r, boolean dataChanged) {
    174         if (dataChanged) {
    175             view.setText(text.getSrc(), text.getText());
    176         }
    177 
    178         if (view instanceof AdaptableSlideViewInterface) {
    179             ((AdaptableSlideViewInterface) view).setTextRegion(
    180                     transformWidth(r.getLeft()),
    181                     transformHeight(r.getTop()),
    182                     transformWidth(r.getWidth()),
    183                     transformHeight(r.getHeight()));
    184         }
    185         view.setTextVisibility(text.isVisible());
    186     }
    187 
    188     /**
    189      * @param view
    190      * @param image
    191      * @param r
    192      */
    193     protected void presentImage(SlideViewInterface view, ImageModel image,
    194             RegionModel r, boolean dataChanged) {
    195         int transformedWidth = transformWidth(r.getWidth());
    196         int transformedHeight = transformWidth(r.getHeight());
    197 
    198         if (LOCAL_LOGV) {
    199             Log.v(TAG, "presentImage r.getWidth: " + r.getWidth()
    200                     + ", r.getHeight: " + r.getHeight() +
    201                     " transformedWidth: " + transformedWidth +
    202                     " transformedHeight: " + transformedHeight);
    203         }
    204 
    205         if (dataChanged) {
    206             view.setImage(image.getSrc(), image.getBitmap(r.getWidth(), r.getHeight()));
    207         }
    208 
    209         if (view instanceof AdaptableSlideViewInterface) {
    210             ((AdaptableSlideViewInterface) view).setImageRegion(
    211                     transformWidth(r.getLeft()),
    212                     transformHeight(r.getTop()),
    213                     transformedWidth,
    214                     transformedHeight);
    215         }
    216         view.setImageRegionFit(r.getFit());
    217         view.setImageVisibility(image.isVisible());
    218     }
    219 
    220     /**
    221      * @param view
    222      * @param video
    223      * @param r
    224      */
    225     protected void presentVideo(SlideViewInterface view, VideoModel video,
    226             RegionModel r, boolean dataChanged) {
    227         if (dataChanged) {
    228             view.setVideo(video.getSrc(), video.getUri());
    229         }
    230 
    231             if (view instanceof AdaptableSlideViewInterface) {
    232             ((AdaptableSlideViewInterface) view).setVideoRegion(
    233                     transformWidth(r.getLeft()),
    234                     transformHeight(r.getTop()),
    235                     transformWidth(r.getWidth()),
    236                     transformHeight(r.getHeight()));
    237         }
    238         view.setVideoVisibility(video.isVisible());
    239 
    240         MediaAction action = video.getCurrentAction();
    241         if (action == MediaAction.START) {
    242             view.startVideo();
    243         } else if (action == MediaAction.PAUSE) {
    244             view.pauseVideo();
    245         } else if (action == MediaAction.STOP) {
    246             view.stopVideo();
    247         } else if (action == MediaAction.SEEK) {
    248             view.seekVideo(video.getSeekTo());
    249         }
    250     }
    251 
    252     public void setLocation(int location) {
    253         mLocation = location;
    254     }
    255 
    256     public int getLocation() {
    257         return mLocation;
    258     }
    259 
    260     public void goBackward() {
    261         if (mLocation > 0) {
    262             mLocation--;
    263         }
    264     }
    265 
    266     public void goForward() {
    267         if (mLocation < (mSlideNumber - 1)) {
    268             mLocation++;
    269         }
    270     }
    271 
    272     public void onModelChanged(final Model model, final boolean dataChanged) {
    273         final SlideViewInterface view = (SlideViewInterface) mView;
    274 
    275         // FIXME: Should be optimized.
    276         if (model instanceof SlideshowModel) {
    277             // TODO:
    278         } else if (model instanceof SlideModel) {
    279             if (((SlideModel) model).isVisible()) {
    280                 mHandler.post(new Runnable() {
    281                     public void run() {
    282                         presentSlide(view, (SlideModel) model);
    283                     }
    284                 });
    285             } else {
    286                 mHandler.post(new Runnable() {
    287                     public void run() {
    288                         goForward();
    289                     }
    290                 });
    291             }
    292         } else if (model instanceof MediaModel) {
    293             if (model instanceof RegionMediaModel) {
    294                 mHandler.post(new Runnable() {
    295                     public void run() {
    296                         presentRegionMedia(view, (RegionMediaModel) model, dataChanged);
    297                     }
    298                 });
    299             } else if (((MediaModel) model).isAudio()) {
    300                 mHandler.post(new Runnable() {
    301                     public void run() {
    302                         presentAudio(view, (AudioModel) model, dataChanged);
    303                     }
    304                 });
    305             }
    306         } else if (model instanceof RegionModel) {
    307             // TODO:
    308         }
    309     }
    310 
    311     @Override
    312     public void cancelBackgroundLoading() {
    313         // For now, the SlideshowPresenter does no background loading so there is nothing to cancel.
    314     }
    315 }
    316