ViewMode.java revision d7a12cd5b5c2639b653d8c671b04844ef02ee01d
1/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to 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
18package com.android.mail.ui;
19
20import com.google.common.collect.Lists;
21
22import android.content.Context;
23import android.os.Bundle;
24
25import java.util.ArrayList;
26
27/**
28 * Represents the view mode for the tablet Gmail activity.
29 * Transitions between modes should be done through this central object, and UI components that are
30 * dependent on the mode should listen to changes on this object.
31 */
32public class ViewMode {
33    /**
34     * A listener for changes on a ViewMode. To listen to mode changes, implement this
35     * interface and register your object with the single ViewMode held by the ActivityController
36     * instance. On mode changes, the onViewModeChanged method will be called with the new mode.
37     */
38    public interface ModeChangeListener {
39        /**
40         * Called when the mode has changed.
41         */
42        void onViewModeChanged(int newMode);
43    }
44
45    /**
46     * Mode when showing a single conversation.
47     */
48    public static final int CONVERSATION = 1;
49    /**
50     * Mode when showing a list of conversations
51     */
52    public static final int CONVERSATION_LIST = 2;
53    /**
54     * Mode when showing a list of folders.
55     */
56    public static final int FOLDER_LIST = 3;
57    /**
58     * Mode when showing results from user search.
59     */
60    public static final int SEARCH_RESULTS = 4;
61    /**
62     * Uncertain mode. The mode has not been initialized.
63     */
64    public static final int UNKNOWN = 0;
65
66    // Key used to save this {@link ViewMode}.
67    private static final String VIEW_MODE_KEY = "view-mode";
68    private final ArrayList<ModeChangeListener> mListeners = Lists.newArrayList();
69    /**
70     * The actual mode the activity is in. We start out with an UNKNOWN mode, and require entering
71     * a valid mode after the object has been created.
72     */
73    private int mMode = UNKNOWN;
74
75    public ViewMode(Context context) {
76        // Do nothing
77    }
78
79    /**
80     * Adds a listener from this view mode.
81     * Must happen in the UI thread.
82     */
83    public void addListener(ModeChangeListener listener) {
84        mListeners.add(listener);
85    }
86
87    /**
88     * Dispatches a change event for the mode.
89     * Always happens in the UI thread.
90     */
91    private void dispatchModeChange(int newMode) {
92        mMode = newMode;
93        ArrayList<ModeChangeListener> list = new ArrayList<ModeChangeListener>(mListeners);
94        for (ModeChangeListener listener : list) {
95            listener.onViewModeChanged(newMode);
96        }
97    }
98
99    /**
100     * Requests a transition of the mode to show the conversation list as the prominent view.
101     * @return Whether or not a change occurred.
102     */
103    public boolean enterConversationListMode() {
104        return setModeInternal(CONVERSATION_LIST);
105    }
106
107    /**
108     * Requests a transition of the mode to show a conversation as the prominent view.
109     * @return Whether or not a change occurred.
110     */
111    public boolean enterConversationMode() {
112        return setModeInternal(CONVERSATION);
113    }
114
115    /**
116     * Requests a transition of the mode to show the folder list as the prominent view.
117     * @return Whether or not a change occurred.
118     */
119    public boolean enterFolderListMode() {
120        return setModeInternal(FOLDER_LIST);
121    }
122
123    /**
124     * @return The current mode.
125     */
126    public int getMode() {
127        return mMode;
128    }
129
130    /**
131     * Restoring from a saved state restores only the mode. It does not restore the listeners of
132     * this object.
133     * @param inState
134     */
135    public void handleRestore(Bundle inState) {
136        mMode = inState.getInt(VIEW_MODE_KEY);
137    }
138
139    /**
140     * Save the existing mode only. Does not save the existing listeners.
141     * @param outState
142     */
143    public void handleSaveInstanceState(Bundle outState) {
144        outState.putInt(VIEW_MODE_KEY, mMode);
145    }
146
147    /**
148     * Removes a listener from this view mode.
149     * Must happen in the UI thread.
150     */
151    public void removeListener(ModeChangeListener listener) {
152        mListeners.remove(listener);
153    }
154
155    /**
156     * Sets the internal mode.
157     * @return Whether or not a change occurred.
158     */
159    private boolean setModeInternal(int mode) {
160        if (mMode == mode) {
161            return false;
162        }
163        dispatchModeChange(mode);
164        return true;
165    }
166}
167