TopicView.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2013 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 /*
00018 copyright 2014 UNL Nimbus Lab 
00019 
00020   Licensed under the Apache License, Version 2.0 (the "License");
00021      you may not use this file except in compliance with the License.
00022     You may obtain a copy of the License at
00023   
00024         http://www.apache.org/licenses/LICENSE-2.0
00025   
00026     Unless required by applicable law or agreed to in writing, software
00027   distributed under the License is distributed on an "AS IS" BASIS,
00028    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00029    See the License for the specific language governing permissions and
00030   limitations under the License.
00031 */
00032 package edu.nimbus.glass;
00033 
00034 import java.io.File;
00035 
00036 import android.animation.Animator;
00037 import android.animation.AnimatorListenerAdapter;
00038 import android.animation.ValueAnimator;
00039 import android.animation.ValueAnimator.AnimatorUpdateListener;
00040 import android.content.Context;
00041 import android.graphics.Canvas;
00042 import android.graphics.Color;
00043 import android.graphics.Paint;
00044 import android.graphics.Typeface;
00045 import android.text.TextPaint;
00046 import android.util.AttributeSet;
00047 import android.view.View;
00048 import android.view.animation.LinearInterpolator;
00049 
00050 import edu.nimbus.glass.screens.AllTopics;
00051 import edu.nimbus.glass.screens.Screen;
00052 import edu.nimbus.glass.util.MathUtils;
00053 
00057 public class TopicView extends View {
00058 
00065         private static final float MIN_DISTANCE_TO_ANIMATE = 15.0f;
00066 
00068         private float mHeading;
00069 
00075         private float mAnimatedHeading;
00076 
00077         private TopicManager topicManager;
00078 
00079         private final TextPaint mTopicPaint;
00080         private final ValueAnimator mAnimator;
00081         
00082         private Screen currentScreen;
00083 
00084         public TopicView(Context context) {
00085                 this(context, null, 0);
00086         }
00087 
00088         public TopicView(Context context, AttributeSet attrs) {
00089                 this(context, attrs, 0);
00090         }
00091 
00092         public TopicView(Context context, AttributeSet attrs, int defStyle) {
00093                 super(context, attrs, defStyle);
00094 
00095 
00096                 mTopicPaint = new TextPaint();
00097                 mTopicPaint.setStyle(Paint.Style.FILL);
00098                 mTopicPaint.setAntiAlias(true);
00099                 mTopicPaint.setColor(Color.WHITE);
00100                 mTopicPaint.setTypeface(Typeface.createFromFile(new File("/system/glass_fonts",
00101                                 "Roboto-Light.ttf")));
00102 
00103 
00104         //Nan for the first time
00105                 mAnimatedHeading = Float.NaN;
00106 
00107                 mAnimator = new ValueAnimator();
00108                 setupAnimator();
00109                 
00110                 currentScreen = new AllTopics();
00111         }
00112 
00119         public void setTopicManager(TopicManager tManager) {
00120                 topicManager = tManager;
00121         }
00122 
00123 
00124         @Override
00125         protected void onDraw(Canvas canvas) {
00126                 //Draw the topic.
00127                 super.onDraw(canvas);
00128                 currentScreen.draw(topicManager, mTopicPaint, canvas, getWidth(), getHeight());
00129         }
00130 
00131 
00135         private void setupAnimator() {
00136                 mAnimator.setInterpolator(new LinearInterpolator());
00137                 mAnimator.setDuration(250);
00138 
00139                 // Notifies us at each frame of the animation so we can redraw the view.
00140                 mAnimator.addUpdateListener(new AnimatorUpdateListener() {
00141 
00142                         @Override
00143                         public void onAnimationUpdate(ValueAnimator animator) {
00144                                 mAnimatedHeading = MathUtils.mod((Float) mAnimator.getAnimatedValue(), 360.0f);
00145                                 invalidate();
00146                         }
00147                 });
00148 
00149                 // Notifies us when the animation is over. During an animation, the user's head may have
00150                 // continued to move to a different orientation than the original destination angle of the
00151                 // animation. Since we can't easily change the animation goal while it is running, we call
00152                 // animateTo() again, which will either redraw at the new orientation (if the difference is
00153                 // small enough), or start another animation to the new heading. This seems to produce
00154                 // fluid results.
00155                 mAnimator.addListener(new AnimatorListenerAdapter() {
00156 
00157                         @Override
00158                         public void onAnimationEnd(Animator animator) {
00159                                 animateTo(mHeading);
00160                         }
00161                 });
00162         }
00163 
00169         private void animateTo(float end) {
00170                 // I'm not sure if this method is needed anymore but I'm still including it here. 
00171                 
00172                 if (!mAnimator.isRunning()) {
00173                         float start = mAnimatedHeading;
00174                         float distance = Math.abs(end - start);
00175                         float reverseDistance = 360.0f - distance;
00176                         float shortest = Math.min(distance, reverseDistance);
00177 
00178                         if (Float.isNaN(mAnimatedHeading) || shortest < MIN_DISTANCE_TO_ANIMATE) {
00179 
00180                                 mAnimatedHeading = end;
00181                                 invalidate();
00182                         } else {
00183 
00184                                 float goal;
00185 
00186                                 if (distance < reverseDistance) {
00187                                         goal = end;
00188                                 } else if (end < start) {
00189                                         goal = end + 360.0f;
00190                                 } else {
00191                                         goal = end - 360.0f;
00192                                 }
00193 
00194                                 mAnimator.setFloatValues(start, goal);
00195                                 mAnimator.start();
00196                         }
00197                 }
00198         }
00199 
00200         public void switchScreen(Screen newScreen) {
00201                 this.currentScreen = newScreen;
00202         }
00203 }


ros_glass_tools
Author(s):
autogenerated on Thu Aug 27 2015 14:47:21