ViewMode.java revision 68f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43
15e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal/*
25e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Copyright (C) 2012 Google Inc.
35e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal * Licensed to The Android Open Source Project.
46f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira *
56f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
66f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * you may not use this file except in compliance with the License.
76f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * You may obtain a copy of the License at
86f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira *
95e5ac748eadbb17eee84b39a424b8b9270ade46cVikram Aggarwal *      http://www.apache.org/licenses/LICENSE-2.0
106f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira *
116f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Unless required by applicable law or agreed to in writing, software
126f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
136f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * See the License for the specific language governing permissions and
156f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * limitations under the License.
166f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira */
176f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
181ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwalpackage com.android.mail.ui;
196f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
206f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereiraimport com.google.common.collect.Lists;
216f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
226f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereiraimport android.content.Context;
236f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereiraimport android.os.Bundle;
246f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereiraimport java.util.ArrayList;
256f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
266f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira/**
276f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Represents the view mode for the tablet Gmail activity.
286f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Transitions between modes should be done through this central object, and UI components that are
296f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * dependent on the mode should listen to changes on this object.
306f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira */
316f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereirapublic class ViewMode {
321ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
33fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * A listener for changes on a ViewMode. To listen to mode changes, implement this
34fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * interface and register your object with the single ViewMode held by the ActivityController
35fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * instance. On mode changes, the onViewModeChanged method will be called with the new mode.
361ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
37b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public interface ModeChangeListener {
38b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        /**
39fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal         * Called when the mode has changed.
40b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal         */
41fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        void onViewModeChanged(int newMode);
42b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    }
43b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal
441ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
4591d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal     * Mode when showing a single conversation.
461ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
478ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int CONVERSATION = 1;
481ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
491ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     * Mode when showing a list of conversations
501ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
518ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int CONVERSATION_LIST = 2;
521ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
53b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Mode when showing a list of folders.
541ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
558ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int FOLDER_LIST = 3;
561ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
571ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     * Mode when showing results from user search.
581ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
5968f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    public static final int SEARCH_RESULTS_LIST = 4;
6068f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    /**
6168f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * Mode when showing results from user search.
6268f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     */
6368f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    public static final int SEARCH_RESULTS_CONVERSATION = 5;
64b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
65b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Uncertain mode. The mode has not been initialized.
66b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
678ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int UNKNOWN = 0;
6855920575c86c02fe5c4e095b7dfe48b04c1361dfVikram Aggarwal
69b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    // Key used to save this {@link ViewMode}.
70b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    private static final String VIEW_MODE_KEY = "view-mode";
716f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    private final ArrayList<ModeChangeListener> mListeners = Lists.newArrayList();
72fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
73fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * The actual mode the activity is in. We start out with an UNKNOWN mode, and require entering
74fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * a valid mode after the object has been created.
75fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
7691d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal    private int mMode = UNKNOWN;
776f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
786f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    public ViewMode(Context context) {
79fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        // Do nothing
806f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
816f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
826f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
83d7a12cd5b5c2639b653d8c671b04844ef02ee01dVikram Aggarwal     * Adds a listener from this view mode.
84b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Must happen in the UI thread.
856f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
86b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public void addListener(ModeChangeListener listener) {
87b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        mListeners.add(listener);
886f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
896f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
906f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
91b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Dispatches a change event for the mode.
92b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Always happens in the UI thread.
936f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
94fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    private void dispatchModeChange(int newMode) {
95fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        mMode = newMode;
96b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        ArrayList<ModeChangeListener> list = new ArrayList<ModeChangeListener>(mListeners);
97b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        for (ModeChangeListener listener : list) {
982175d0a93263672d4498458c81b404b0999134baVikram Aggarwal            assert (listener != null);
99fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal            listener.onViewModeChanged(newMode);
1006f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira        }
1016f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1026f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
1036f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
104fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show the conversation list as the prominent view.
105fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
1066f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
107fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterConversationListMode() {
108fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(CONVERSATION_LIST);
1096f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1106f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
111fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
112fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show a conversation as the prominent view.
113fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
114fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
115fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterConversationMode() {
116fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(CONVERSATION);
1176f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1186f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
119fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
120fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show the folder list as the prominent view.
121fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
122fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
123fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterFolderListMode() {
124fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(FOLDER_LIST);
1256f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1266f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
127fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
12868f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * Requests a transition of the mode to show a list of search results as the
12968f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * prominent view.
13068f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     *
13168f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * @return Whether or not a change occurred.
13268f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     */
13368f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    public boolean enterSearchResultsListMode() {
13468f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira        return setModeInternal(SEARCH_RESULTS_LIST);
13568f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    }
13668f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira
13768f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    /**
13868f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * Requests a transition of the mode to show a conversation that was part of
13968f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * search results.
14068f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     *
14168f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     * @return Whether or not a change occurred.
14268f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira     */
14368f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    public boolean enterSearchResultsConversationMode() {
14468f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira        return setModeInternal(SEARCH_RESULTS_CONVERSATION);
14568f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    }
14668f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira
14768f2e222b4ffccd9f67f02b3a9cfdb3841a7eb43Mindy Pereira    /**
148fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return The current mode.
149fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
150fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public int getMode() {
151fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return mMode;
152b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    }
153b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal
154fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
155fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Restoring from a saved state restores only the mode. It does not restore the listeners of
156fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * this object.
157fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @param inState
158fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
159fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public void handleRestore(Bundle inState) {
160fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        mMode = inState.getInt(VIEW_MODE_KEY);
1616f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1626f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
163b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
164fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Save the existing mode only. Does not save the existing listeners.
165fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @param outState
166b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
167fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public void handleSaveInstanceState(Bundle outState) {
168fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        outState.putInt(VIEW_MODE_KEY, mMode);
1696f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1706f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
171b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
172b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Removes a listener from this view mode.
173b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Must happen in the UI thread.
174b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
175b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public void removeListener(ModeChangeListener listener) {
176b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        mListeners.remove(listener);
1776f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1786f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
1796f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
180b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Sets the internal mode.
181fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
1826f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
18391d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal    private boolean setModeInternal(int mode) {
184b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        if (mMode == mode) {
185b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal            return false;
186b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        }
187fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        dispatchModeChange(mode);
188b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        return true;
1896f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1906f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira}
191