ViewMode.java revision 3825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bb
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;
24import java.util.ArrayList;
25
26/**
27 * Represents the view mode for the tablet Gmail activity.
28 * Transitions between modes should be done through this central object, and UI components that are
29 * dependent on the mode should listen to changes on this object.
30 */
31public class ViewMode {
32    /**
33     * A listener for changes on a ViewMode. To listen to mode changes, implement this
34     * interface and register your object with the single ViewMode held by the ActivityController
35     * instance. On mode changes, the onViewModeChanged method will be called with the new mode.
36     */
37    public interface ModeChangeListener {
38        /**
39         * Called when the mode has changed.
40         */
41        void onViewModeChanged(int newMode);
42    }
43
44    /**
45     * Mode when showing a single conversation.
46     */
47    public static final int CONVERSATION = 1;
48    /**
49     * Mode when showing a list of conversations
50     */
51    public static final int CONVERSATION_LIST = 2;
52    /**
53     * Mode when showing a list of folders.
54     */
55    public static final int FOLDER_LIST = 3;
56    /**
57     * Mode when showing results from user search.
58     */
59    public static final int SEARCH_RESULTS_LIST = 4;
60    /**
61     * Mode when showing results from user search.
62     */
63    public static final int SEARCH_RESULTS_CONVERSATION = 5;
64    /**
65     * Mode when showing the "waiting for sync" message.
66     */
67    public static final int WAITING_FOR_ACCOUNT_INITIALIZATION = 6;
68    /**
69     * Uncertain mode. The mode has not been initialized.
70     */
71    public static final int UNKNOWN = 0;
72
73    // Key used to save this {@link ViewMode}.
74    private static final String VIEW_MODE_KEY = "view-mode";
75    private final ArrayList<ModeChangeListener> mListeners = Lists.newArrayList();
76    /**
77     * The actual mode the activity is in. We start out with an UNKNOWN mode, and require entering
78     * a valid mode after the object has been created.
79     */
80    private int mMode = UNKNOWN;
81
82    public ViewMode(Context context) {
83        // Do nothing
84    }
85
86    /**
87     * Adds a listener from this view mode.
88     * Must happen in the UI thread.
89     */
90    public void addListener(ModeChangeListener listener) {
91        mListeners.add(listener);
92    }
93
94    /**
95     * Dispatches a change event for the mode.
96     * Always happens in the UI thread.
97     */
98    private void dispatchModeChange() {
99        ArrayList<ModeChangeListener> list = new ArrayList<ModeChangeListener>(mListeners);
100        for (ModeChangeListener listener : list) {
101            assert (listener != null);
102            listener.onViewModeChanged(mMode);
103        }
104    }
105
106    /**
107     * Requests a transition of the mode to show the conversation list as the prominent view.
108     * @return Whether or not a change occurred.
109     */
110    public boolean enterConversationListMode() {
111        return setModeInternal(CONVERSATION_LIST);
112    }
113
114    /**
115     * Requests a transition of the mode to show a conversation as the prominent view.
116     * @return Whether or not a change occurred.
117     */
118    public boolean enterConversationMode() {
119        return setModeInternal(CONVERSATION);
120    }
121
122    /**
123     * Requests a transition of the mode to show the folder list as the prominent view.
124     * @return Whether or not a change occurred.
125     */
126    public boolean enterFolderListMode() {
127        return setModeInternal(FOLDER_LIST);
128    }
129
130    /**
131     * Requests a transition of the mode to show a list of search results as the
132     * prominent view.
133     *
134     * @return Whether or not a change occurred.
135     */
136    public boolean enterSearchResultsListMode() {
137        return setModeInternal(SEARCH_RESULTS_LIST);
138    }
139
140    /**
141     * Requests a transition of the mode to show a conversation that was part of
142     * search results.
143     *
144     * @return Whether or not a change occurred.
145     */
146    public boolean enterSearchResultsConversationMode() {
147        return setModeInternal(SEARCH_RESULTS_CONVERSATION);
148    }
149
150    /**
151     * Requests a transition of the mode to show the "waiting for sync" messages
152     *
153     * @return Whether or not a change occurred.
154     */
155    public boolean enterWaitingForInitializationMode() {
156        return setModeInternal(WAITING_FOR_ACCOUNT_INITIALIZATION);
157    }
158
159    /**
160     * @return The current mode.
161     */
162    public int getMode() {
163        return mMode;
164    }
165
166    /**
167     * Return whether the current mode is considered a list mode.
168     */
169    public boolean isListMode() {
170        return mMode == ViewMode.CONVERSATION_LIST || mMode == ViewMode.SEARCH_RESULTS_LIST;
171    }
172
173    /**
174     * Restoring from a saved state restores only the mode. It does not restore the listeners of
175     * this object.
176     * @param inState
177     */
178    public void handleRestore(Bundle inState) {
179        if (inState == null) {
180            return;
181        }
182        // Restore the previous mode, and UNKNOWN if nothing exists.
183        final int newMode = inState.getInt(VIEW_MODE_KEY, UNKNOWN);
184        if (newMode != UNKNOWN) {
185            setModeInternal(newMode);
186        }
187    }
188
189    /**
190     * Save the existing mode only. Does not save the existing listeners.
191     * @param outState
192     */
193    public void handleSaveInstanceState(Bundle outState) {
194        if (outState == null) {
195            return;
196        }
197        outState.putInt(VIEW_MODE_KEY, mMode);
198    }
199
200    /**
201     * Removes a listener from this view mode.
202     * Must happen in the UI thread.
203     */
204    public void removeListener(ModeChangeListener listener) {
205        mListeners.remove(listener);
206    }
207
208    /**
209     * Sets the internal mode.
210     * @return Whether or not a change occurred.
211     */
212    private boolean setModeInternal(int mode) {
213        if (mMode == mode) {
214            return false;
215        }
216        mMode = mode;
217        dispatchModeChange();
218        return true;
219    }
220}
221