1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.app;
18
19import android.content.Context;
20import android.view.LayoutInflater;
21import android.view.View;
22import android.view.View.OnClickListener;
23import android.view.ViewGroup;
24import android.view.animation.AlphaAnimation;
25import android.view.animation.Animation;
26import android.widget.RelativeLayout;
27
28import com.android.gallery3d.R;
29
30import java.util.HashMap;
31import java.util.Map;
32
33public class PhotoPageBottomControls implements OnClickListener {
34    public interface Delegate {
35        public boolean canDisplayBottomControls();
36        public boolean canDisplayBottomControl(int control);
37        public void onBottomControlClicked(int control);
38        public void refreshBottomControlsWhenReady();
39    }
40
41    private Delegate mDelegate;
42    private ViewGroup mParentLayout;
43    private ViewGroup mContainer;
44
45    private boolean mContainerVisible = false;
46    private Map<View, Boolean> mControlsVisible = new HashMap<View, Boolean>();
47
48    private Animation mContainerAnimIn = new AlphaAnimation(0f, 1f);
49    private Animation mContainerAnimOut = new AlphaAnimation(1f, 0f);
50    private static final int CONTAINER_ANIM_DURATION_MS = 200;
51
52    private static final int CONTROL_ANIM_DURATION_MS = 150;
53    private static Animation getControlAnimForVisibility(boolean visible) {
54        Animation anim = visible ? new AlphaAnimation(0f, 1f)
55                : new AlphaAnimation(1f, 0f);
56        anim.setDuration(CONTROL_ANIM_DURATION_MS);
57        return anim;
58    }
59
60    public PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout) {
61        mDelegate = delegate;
62        mParentLayout = layout;
63
64        LayoutInflater inflater = (LayoutInflater) context
65                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
66        mContainer = (ViewGroup) inflater
67                .inflate(R.layout.photopage_bottom_controls, mParentLayout, false);
68        mParentLayout.addView(mContainer);
69
70        for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
71            View child = mContainer.getChildAt(i);
72            child.setOnClickListener(this);
73            mControlsVisible.put(child, false);
74        }
75
76        mContainerAnimIn.setDuration(CONTAINER_ANIM_DURATION_MS);
77        mContainerAnimOut.setDuration(CONTAINER_ANIM_DURATION_MS);
78
79        mDelegate.refreshBottomControlsWhenReady();
80    }
81
82    private void hide() {
83        mContainer.clearAnimation();
84        mContainerAnimOut.reset();
85        mContainer.startAnimation(mContainerAnimOut);
86        mContainer.setVisibility(View.INVISIBLE);
87    }
88
89    private void show() {
90        mContainer.clearAnimation();
91        mContainerAnimIn.reset();
92        mContainer.startAnimation(mContainerAnimIn);
93        mContainer.setVisibility(View.VISIBLE);
94    }
95
96    public void refresh() {
97        boolean visible = mDelegate.canDisplayBottomControls();
98        boolean containerVisibilityChanged = (visible != mContainerVisible);
99        if (containerVisibilityChanged) {
100            if (visible) {
101                show();
102            } else {
103                hide();
104            }
105            mContainerVisible = visible;
106        }
107        if (!mContainerVisible) {
108            return;
109        }
110        for (View control : mControlsVisible.keySet()) {
111            Boolean prevVisibility = mControlsVisible.get(control);
112            boolean curVisibility = mDelegate.canDisplayBottomControl(control.getId());
113            if (prevVisibility.booleanValue() != curVisibility) {
114                if (!containerVisibilityChanged) {
115                    control.clearAnimation();
116                    control.startAnimation(getControlAnimForVisibility(curVisibility));
117                }
118                control.setVisibility(curVisibility ? View.VISIBLE : View.INVISIBLE);
119                mControlsVisible.put(control, curVisibility);
120            }
121        }
122        // Force a layout change
123        mContainer.requestLayout(); // Kick framework to draw the control.
124    }
125
126    public void cleanup() {
127        mParentLayout.removeView(mContainer);
128        mControlsVisible.clear();
129    }
130
131    @Override
132    public void onClick(View view) {
133        Boolean controlVisible = mControlsVisible.get(view);
134        if (mContainerVisible && controlVisible != null && controlVisible.booleanValue()) {
135            mDelegate.onBottomControlClicked(view.getId());
136        }
137    }
138}
139