/*
* Copyright (C) 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.apps.santatracker.doodles.shared;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import com.google.android.apps.santatracker.doodles.R;
import com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.Builder;
import com.google.android.apps.santatracker.doodles.shared.sound.SoundManager;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.DEFAULT_DOODLE_NAME;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.HOME_CLICKED;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.MUTE_CLICKED;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.PAUSE_CLICKED;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.REPLAY_CLICKED;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.UNMUTE_CLICKED;
import static com.google.android.apps.santatracker.doodles.shared.PineappleLogEvent.UNPAUSE_CLICKED;
/**
* The overlay which is shown when a game is paused.
*/
public class PauseView extends FrameLayout {
private static final int BIG_PAUSE_FADE_IN_MS = 200; // Fading in paused screen elements.
private static final int FADE_IN_MS = 500; // Fading in paused screen elements.
private static final int FADE_OUT_MS = 200; // Fading out paused screen elements.
private static final int BUMP_MS = 200; // The paused text over-zooms a bit on pause.
private static final int RELAX_MS = 200; // The paused text shrinks a bit after zooming up.
private static final float ZOOM_UP_SCALE_OVERSHOOT = 1.2f;
public static final int FADE_DURATION_MS = 400; // The pause button fading in and out.
/**
* A listener for interacting with the PauseView.
*/
public interface GamePausedListener {
void onPause();
void onResume();
void onReplay();
String gameType();
float score();
}
private GamePausedListener listener;
private DoodleConfig doodleConfig;
private PineappleLogger logger;
private ImageButton muteButton;
private GameOverlayButton pauseButton;
private View resumeButton;
private View buttonContainer;
private View background;
public boolean isPauseButtonEnabled = true;
private float backgroundAlpha;
private float pauseButtonAlpha;
public PauseView(Context context) {
this(context, null);
}
public PauseView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PauseView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
loadLayout(context);
hidePauseScreen();
}
public void setDoodleConfig(DoodleConfig doodleConfig) {
this.doodleConfig = doodleConfig;
}
public void setLogger(PineappleLogger logger) {
this.logger = logger;
}
public GamePausedListener getListener() {
return this.listener;
}
public void setListener(GamePausedListener listener) {
this.listener = listener;
}
public void hidePauseButton() {
isPauseButtonEnabled = false;
UIUtil.fadeOutAndHide(pauseButton, FADE_DURATION_MS, pauseButtonAlpha);
}
public void showPauseButton() {
isPauseButtonEnabled = true;
UIUtil.showAndFadeIn(pauseButton, FADE_DURATION_MS, pauseButtonAlpha);
}
public void onFinishedLoading() {
setVisibility(View.VISIBLE);
}
protected void loadLayout(final Context context) {
setVisibility(View.INVISIBLE);
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.pause_view, this);
buttonContainer = view.findViewById(R.id.button_container);
muteButton = (ImageButton) view.findViewById(R.id.mute_button);
if (SoundManager.soundsAreMuted) {
muteButton.setImageResource(R.drawable.common_btn_speaker_off);
}
muteButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
boolean shouldMute = !SoundManager.soundsAreMuted;
String logEventName = shouldMute ? MUTE_CLICKED : UNMUTE_CLICKED;
logger.logEvent(new Builder(DEFAULT_DOODLE_NAME, logEventName)
.withEventSubType(listener.gameType()).build());
muteButton.setImageResource(
shouldMute ? R.drawable.common_btn_speaker_off : R.drawable.common_btn_speaker_on);
muteButton.setContentDescription(context.getResources().getString(
shouldMute ? R.string.unmute : R.string.mute));
EventBus.getInstance().sendEvent(EventBus.MUTE_SOUNDS, shouldMute);
}
});
pauseButton = (GameOverlayButton) view.findViewById(R.id.pause_button);
pauseButtonAlpha = pauseButton.getAlpha();
pauseButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
pause();
}
});
resumeButton = view.findViewById(R.id.resume_button);
resumeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
logger.logEvent(new Builder(DEFAULT_DOODLE_NAME, UNPAUSE_CLICKED)
.withEventSubType(listener.gameType()).build());
unpause();
}
});
View replayButton = view.findViewById(R.id.replay_button);
replayButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
logger.logEvent(new Builder(DEFAULT_DOODLE_NAME, REPLAY_CLICKED)
.withEventSubType(listener.gameType())
.withLatencyMs(PineappleLogTimer.getInstance().timeElapsedMs())
.withEventValue1(listener.score())
.build());
replay();
}
});
View menuButton = view.findViewById(R.id.menu_button);
menuButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
EventBus.getInstance().sendEvent(EventBus.PLAY_SOUND, R.raw.menu_item_click);
logger.logEvent(new Builder(DEFAULT_DOODLE_NAME, HOME_CLICKED)
.withEventSubType(listener.gameType())
.withLatencyMs(PineappleLogTimer.getInstance().timeElapsedMs())
.withEventValue1(listener.score())
.build());
LaunchDecisionMaker.finishActivity(context);
}
});
background = view.findViewById(R.id.pause_view_background);
backgroundAlpha = background.getAlpha();
}
private void replay() {
PineappleLogTimer.getInstance().unpause();
hidePauseScreen();
if (listener != null) {
EventBus.getInstance().sendEvent(EventBus.PLAY_SOUND, R.raw.menu_item_click);
listener.onReplay();
}
}
/**
* Pauses the current game.
*/
public void pause() {
if (!isPauseButtonEnabled) {
return;
}
logger.logEvent(new Builder(DEFAULT_DOODLE_NAME, PAUSE_CLICKED)
.withEventSubType(listener.gameType())
.withLatencyMs(PineappleLogTimer.getInstance().timeElapsedMs())
.build());
PineappleLogTimer.getInstance().pause();
if (listener != null) {
EventBus.getInstance().sendEvent(EventBus.PLAY_SOUND, R.raw.menu_item_click);
listener.onPause();
}
showPauseScreen();
AndroidUtils.allowScreenToTurnOff(getContext());
}
private void unpause() {
PineappleLogTimer.getInstance().unpause();
hidePauseScreen();
if (listener != null) {
EventBus.getInstance().sendEvent(EventBus.PLAY_SOUND, R.raw.menu_item_click);
listener.onResume();
}
AndroidUtils.forceScreenToStayOn(getContext());
}
private void showPauseScreen() {
isPauseButtonEnabled = false;
SoundManager soundManager = SoundManager.getInstance();
soundManager.mute(R.raw.fruit_doodle_music);
soundManager.pauseShortSounds();
if (SoundManager.soundsAreMuted) {
muteButton.setImageResource(R.drawable.common_btn_speaker_off);
} else {
muteButton.setImageResource(R.drawable.common_btn_speaker_on);
}
muteButton.setAlpha(0.0f);
resumeButton.setAlpha(0.0f);
buttonContainer.setAlpha(0);
background.setAlpha(0);
muteButton.setVisibility(VISIBLE);
resumeButton.setVisibility(VISIBLE);
buttonContainer.setVisibility(VISIBLE);
background.setVisibility(VISIBLE);
ValueAnimator fadeBigPauseIn = UIUtil.animator(BIG_PAUSE_FADE_IN_MS,
new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
resumeButton.setAlpha((float) valueAnimator.getAnimatedValue("textAlpha"));
background.setAlpha((float) valueAnimator.getAnimatedValue("bgAlpha"));
}
},
UIUtil.floatValue("textAlpha", 0, 1),
UIUtil.floatValue("bgAlpha", 0, backgroundAlpha)
);
ValueAnimator fadePauseButtonOut = UIUtil.animator(BIG_PAUSE_FADE_IN_MS,
new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
pauseButton.setAlpha((float) valueAnimator.getAnimatedValue("pauseButtonAlpha"));
}
},
UIUtil.floatValue("pauseButtonAlpha", pauseButtonAlpha, 0)
);
fadePauseButtonOut.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
pauseButton.setVisibility(INVISIBLE);
}
});
ValueAnimator zoomUp = UIUtil.animator(BUMP_MS, new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float scale = (float) valueAnimator.getAnimatedValue("scale");
resumeButton.setScaleX(scale);
resumeButton.setScaleY(scale);
}
},
UIUtil.floatValue("scale", 0, ZOOM_UP_SCALE_OVERSHOOT)
);
ValueAnimator relax = UIUtil.animator(RELAX_MS, new OvershootInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float scale = (float) valueAnimator.getAnimatedValue("scale");
resumeButton.setScaleX(scale);
resumeButton.setScaleY(scale);
}
},
UIUtil.floatValue("scale", ZOOM_UP_SCALE_OVERSHOOT, 1));
ValueAnimator fadeIn = UIUtil.animator(FADE_IN_MS, new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
muteButton.setAlpha((float) valueAnimator.getAnimatedValue("alpha"));
buttonContainer.setAlpha((float) valueAnimator.getAnimatedValue("alpha"));
}
},
UIUtil.floatValue("alpha", 0, 1)
);
AnimatorSet animations = new AnimatorSet();
animations.play(fadeBigPauseIn).with(zoomUp);
animations.play(fadePauseButtonOut).with(zoomUp);
animations.play(relax).after(zoomUp);
animations.play(fadeIn).after(zoomUp);
animations.start();
}
private void hidePauseScreen() {
SoundManager soundManager = SoundManager.getInstance();
soundManager.unmute(R.raw.fruit_doodle_music);
soundManager.resumeShortSounds();
ValueAnimator fadeOut = UIUtil.animator(FADE_OUT_MS, new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
muteButton.setAlpha((float) valueAnimator.getAnimatedValue("overlayAlpha"));
background.setAlpha((float) valueAnimator.getAnimatedValue("bgAlpha"));
buttonContainer.setAlpha((float) valueAnimator.getAnimatedValue("overlayAlpha"));
resumeButton.setAlpha((float) valueAnimator.getAnimatedValue("overlayAlpha"));
resumeButton.setScaleX((float) valueAnimator.getAnimatedValue("iconScale"));
resumeButton.setScaleY((float) valueAnimator.getAnimatedValue("iconScale"));
}
},
UIUtil.floatValue("overlayAlpha", 1, 0),
UIUtil.floatValue("bgAlpha", backgroundAlpha, 0),
UIUtil.floatValue("iconScale", 1, 2)
);
fadeOut.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
muteButton.setVisibility(INVISIBLE);
resumeButton.setVisibility(INVISIBLE);
buttonContainer.setVisibility(INVISIBLE);
background.setVisibility(INVISIBLE);
isPauseButtonEnabled = true;
}
});
pauseButton.setAlpha(0.0f);
pauseButton.setVisibility(VISIBLE);
ValueAnimator fadePauseButtonIn = UIUtil.animator(FADE_OUT_MS,
new AccelerateDecelerateInterpolator(),
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
pauseButton.setAlpha((float) valueAnimator.getAnimatedValue("alpha"));
}
},
UIUtil.floatValue("alpha", 0, pauseButtonAlpha)
);
AnimatorSet animations = new AnimatorSet();
animations.play(fadeOut).with(fadePauseButtonIn);
animations.start();
}
}