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