ViewMode.java revision fa131a2ff399fd1d544f759b063268fb4e8a3e70
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 Pereira
256f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereiraimport java.util.ArrayList;
266f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
276f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira/**
286f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Represents the view mode for the tablet Gmail activity.
296f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * Transitions between modes should be done through this central object, and UI components that are
306f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira * dependent on the mode should listen to changes on this object.
316f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira */
326f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereirapublic class ViewMode {
331ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
34fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * A listener for changes on a ViewMode. To listen to mode changes, implement this
35fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * interface and register your object with the single ViewMode held by the ActivityController
36fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * instance. On mode changes, the onViewModeChanged method will be called with the new mode.
371ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
38b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public interface ModeChangeListener {
39b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        /**
40fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal         * Called when the mode has changed.
41b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal         */
42fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        void onViewModeChanged(int newMode);
43b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    }
44b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal
451ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
4691d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal     * Mode when showing a single conversation.
471ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
488ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int CONVERSATION = 1;
491ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
501ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     * Mode when showing a list of conversations
511ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
528ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int CONVERSATION_LIST = 2;
531ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
54b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Mode when showing a list of folders.
551ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
568ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int FOLDER_LIST = 3;
571ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    /**
581ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     * Mode when showing results from user search.
591ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal     */
608ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int SEARCH_RESULTS = 4;
61b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
62b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Uncertain mode. The mode has not been initialized.
63b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
648ffe4320a17c3f4234f473e8f0ce083732064aa9Vikram Aggarwal    public static final int UNKNOWN = 0;
6555920575c86c02fe5c4e095b7dfe48b04c1361dfVikram Aggarwal
66b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    // Key used to save this {@link ViewMode}.
67b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    private static final String VIEW_MODE_KEY = "view-mode";
686f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    private final ArrayList<ModeChangeListener> mListeners = Lists.newArrayList();
69fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
70fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * The actual mode the activity is in. We start out with an UNKNOWN mode, and require entering
71fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * a valid mode after the object has been created.
72fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
7391d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal    private int mMode = UNKNOWN;
746f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
756f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    public ViewMode(Context context) {
76fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        // Do nothing
776f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
786f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
796f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
80b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     *  Adds a listener from this view mode.
81b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Must happen in the UI thread.
826f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
83b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public void addListener(ModeChangeListener listener) {
84b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        mListeners.add(listener);
856f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
866f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
876f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
88b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Dispatches a change event for the mode.
89b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Always happens in the UI thread.
906f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
91fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    private void dispatchModeChange(int newMode) {
92fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        mMode = newMode;
93b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        ArrayList<ModeChangeListener> list = new ArrayList<ModeChangeListener>(mListeners);
94b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        for (ModeChangeListener listener : list) {
95fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal            listener.onViewModeChanged(newMode);
966f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira        }
976f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
986f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
996f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
100fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show the conversation list as the prominent view.
101fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
1026f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
103fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterConversationListMode() {
104fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(CONVERSATION_LIST);
1056f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1066f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
107fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
108fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show a conversation as the prominent view.
109fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
110fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
111fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterConversationMode() {
112fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(CONVERSATION);
1136f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1146f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
115fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
116fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Requests a transition of the mode to show the folder list as the prominent view.
117fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
118fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
119fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public boolean enterFolderListMode() {
120fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return setModeInternal(FOLDER_LIST);
1216f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1226f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
123fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
124fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return The current mode.
125fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
126fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public int getMode() {
127fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        return mMode;
128b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    }
129b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal
130fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    /**
131fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Restoring from a saved state restores only the mode. It does not restore the listeners of
132fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * this object.
133fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @param inState
134fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     */
135fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public void handleRestore(Bundle inState) {
136fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        mMode = inState.getInt(VIEW_MODE_KEY);
1376f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1386f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
139b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
140fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * Save the existing mode only. Does not save the existing listeners.
141fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @param outState
142b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
143fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal    public void handleSaveInstanceState(Bundle outState) {
144fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        outState.putInt(VIEW_MODE_KEY, mMode);
1456f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1466f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
147b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    /**
148b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Removes a listener from this view mode.
149b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Must happen in the UI thread.
150b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     */
151b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal    public void removeListener(ModeChangeListener listener) {
152b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        mListeners.remove(listener);
1536f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1546f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira
1556f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    /**
156b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal     * Sets the internal mode.
157fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal     * @return Whether or not a change occurred.
1586f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira     */
15991d8d26212f741ec33568f3bc9943f8289a576c8Vikram Aggarwal    private boolean setModeInternal(int mode) {
160b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        if (mMode == mode) {
161b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal            return false;
162b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        }
163fa131a2ff399fd1d544f759b063268fb4e8a3e70Vikram Aggarwal        dispatchModeChange(mode);
164b9e1a353c6a173a2885642dbcc1939f3281f29f7Vikram Aggarwal        return true;
1656f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira    }
1666f92de64bbdf1ea6c4cd9774fc96921a10c266d7Mindy Pereira}
167