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