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