blob: f63b19056f5d41b15c17a9ff6343ffe350732ac2 [file] [log] [blame]
The Android Open Source Projectb301ed22009-03-03 19:32:17 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.calculator2;
18
19import android.app.Activity;
Adam Powell353efcf2011-09-12 21:02:24 -070020import android.content.res.Resources;
21import android.content.res.TypedArray;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080022import android.os.Bundle;
Adam Powell353efcf2011-09-12 21:02:24 -070023import android.os.Parcelable;
24import android.support.v4.view.PagerAdapter;
25import android.support.v4.view.ViewPager;
Dmitri Plotnikov9476df22011-01-17 14:46:51 -080026import android.util.Log;
27import android.view.KeyEvent;
Adam Powell353efcf2011-09-12 21:02:24 -070028import android.view.LayoutInflater;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080029import android.view.Menu;
30import android.view.MenuItem;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080031import android.view.View;
Mindy Pereira0a1148f2011-08-22 17:30:05 -070032import android.view.View.OnClickListener;
Adam Powell353efcf2011-09-12 21:02:24 -070033import android.view.ViewConfiguration;
34import android.view.ViewGroup;
35import android.view.WindowManager;
Mindy Pereira0a1148f2011-08-22 17:30:05 -070036import android.widget.PopupMenu;
37import android.widget.PopupMenu.OnMenuItemClickListener;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080038
Mindy Pereira0a1148f2011-08-22 17:30:05 -070039public class Calculator extends Activity implements PanelSwitcher.Listener, Logic.Listener,
40 OnClickListener, OnMenuItemClickListener {
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080041 EventListener mListener = new EventListener();
42 private CalculatorDisplay mDisplay;
43 private Persist mPersist;
44 private History mHistory;
45 private Logic mLogic;
Adam Powell353efcf2011-09-12 21:02:24 -070046 private ViewPager mPager;
Dmitri Plotnikov25018112011-01-17 16:32:39 -080047 private View mClearButton;
48 private View mBackspaceButton;
Mindy Pereira0a1148f2011-08-22 17:30:05 -070049 private View mOverflowMenuButton;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080050
51 static final int BASIC_PANEL = 0;
52 static final int ADVANCED_PANEL = 1;
53
54 private static final String LOG_TAG = "Calculator";
55 private static final boolean DEBUG = false;
Joe Onorato6bef2f82011-04-07 18:41:10 -070056 private static final boolean LOG_ENABLED = false;
Mihai Predacf3ca322010-03-09 12:27:45 +010057 private static final String STATE_CURRENT_VIEW = "state-current-view";
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080058
59 @Override
Mihai Predacf3ca322010-03-09 12:27:45 +010060 public void onCreate(Bundle state) {
61 super.onCreate(state);
Jeff Hamilton0c464d22009-04-11 01:54:05 -070062
Gilles Debunne92ccd212011-08-12 09:29:15 -070063 // Disable IME for this application
64 getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
65 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
66
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080067 setContentView(R.layout.main);
Adam Powell353efcf2011-09-12 21:02:24 -070068 mPager = (ViewPager) findViewById(R.id.panelswitch);
69 if (mPager != null) {
70 mPager.setAdapter(new PageAdapter(mPager));
71 } else {
72 // Single page UI
73 final TypedArray buttons = getResources().obtainTypedArray(R.array.buttons);
74 for (int i = 0; i < buttons.length(); i++) {
75 setOnClickListener(null, buttons.getResourceId(i, 0));
76 }
77 buttons.recycle();
78 }
79
80 if (mClearButton == null) {
81 mClearButton = findViewById(R.id.clear);
82 mClearButton.setOnClickListener(mListener);
83 mClearButton.setOnLongClickListener(mListener);
84 }
85 if (mBackspaceButton == null) {
86 mBackspaceButton = findViewById(R.id.del);
87 mBackspaceButton.setOnClickListener(mListener);
88 mBackspaceButton.setOnLongClickListener(mListener);
89 }
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080090
91 mPersist = new Persist(this);
Dmitri Plotnikov25018112011-01-17 16:32:39 -080092 mPersist.load();
93
The Android Open Source Projectb301ed22009-03-03 19:32:17 -080094 mHistory = mPersist.history;
95
96 mDisplay = (CalculatorDisplay) findViewById(R.id.display);
97
Dmitri Plotnikov25018112011-01-17 16:32:39 -080098 mLogic = new Logic(this, mHistory, mDisplay);
99 mLogic.setListener(this);
100
101 mLogic.setDeleteMode(mPersist.getDeleteMode());
Dmitri Plotnikov582273d2011-01-21 15:55:40 -0800102 mLogic.setLineLength(mDisplay.getMaxDigits());
Dmitri Plotnikov25018112011-01-17 16:32:39 -0800103
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800104 HistoryAdapter historyAdapter = new HistoryAdapter(this, mHistory, mLogic);
105 mHistory.setObserver(historyAdapter);
Mihai Predacf3ca322010-03-09 12:27:45 +0100106
Adam Powell353efcf2011-09-12 21:02:24 -0700107 if (mPager != null) {
108 mPager.setCurrentItem(state == null ? 0 : state.getInt(STATE_CURRENT_VIEW, 0));
Dmitri Plotnikove2092452011-01-16 15:27:03 -0800109 }
Mihai Predacf3ca322010-03-09 12:27:45 +0100110
Adam Powell353efcf2011-09-12 21:02:24 -0700111 mListener.setHandler(mLogic, mPager);
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800112 mDisplay.setOnKeyListener(mListener);
113
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700114 if (!ViewConfiguration.get(this).hasPermanentMenuKey()) {
115 createFakeMenu();
116 }
Dmitri Plotnikove2092452011-01-16 15:27:03 -0800117
Dmitri Plotnikov582273d2011-01-21 15:55:40 -0800118 mLogic.resumeWithHistory();
Dmitri Plotnikov25018112011-01-17 16:32:39 -0800119 updateDeleteMode();
120 }
121
122 private void updateDeleteMode() {
123 if (mLogic.getDeleteMode() == Logic.DELETE_MODE_BACKSPACE) {
124 mClearButton.setVisibility(View.GONE);
125 mBackspaceButton.setVisibility(View.VISIBLE);
126 } else {
127 mClearButton.setVisibility(View.VISIBLE);
128 mBackspaceButton.setVisibility(View.GONE);
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800129 }
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800130 }
131
Adam Powell353efcf2011-09-12 21:02:24 -0700132 void setOnClickListener(View root, int id) {
133 final View target = root != null ? root.findViewById(id) : findViewById(id);
134 target.setOnClickListener(mListener);
Dmitri Plotnikove2092452011-01-16 15:27:03 -0800135 }
136
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800137 @Override
138 public boolean onCreateOptionsMenu(Menu menu) {
139 super.onCreateOptionsMenu(menu);
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700140 getMenuInflater().inflate(R.menu.menu, menu);
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800141 return true;
142 }
Dmitri Plotnikov052c92a2011-01-10 18:30:42 -0800143
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800144 @Override
145 public boolean onPrepareOptionsMenu(Menu menu) {
146 super.onPrepareOptionsMenu(menu);
Mindy Pereirae5179482011-09-14 13:09:57 -0700147 menu.findItem(R.id.basic).setVisible(!getBasicVisibility());
148 menu.findItem(R.id.advanced).setVisible(!getAdvancedVisibility());
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800149 return true;
150 }
151
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700152
153 private void createFakeMenu() {
154 mOverflowMenuButton = findViewById(R.id.overflow_menu);
155 if (mOverflowMenuButton != null) {
156 mOverflowMenuButton.setVisibility(View.VISIBLE);
157 mOverflowMenuButton.setOnClickListener(this);
158 }
159 }
160
161 @Override
162 public void onClick(View v) {
163 switch (v.getId()) {
164 case R.id.overflow_menu:
165 PopupMenu menu = constructPopupMenu();
166 if (menu != null) {
167 menu.show();
168 }
169 break;
170 }
171 }
172
173 private PopupMenu constructPopupMenu() {
174 final PopupMenu popupMenu = new PopupMenu(this, mOverflowMenuButton);
175 final Menu menu = popupMenu.getMenu();
176 popupMenu.inflate(R.menu.menu);
177 popupMenu.setOnMenuItemClickListener(this);
178 onPrepareOptionsMenu(menu);
179 return popupMenu;
180 }
181
182
183 @Override
184 public boolean onMenuItemClick(MenuItem item) {
185 return onOptionsItemSelected(item);
186 }
187
188 private boolean getBasicVisibility() {
Mindy Pereirae5179482011-09-14 13:09:57 -0700189 return mPager != null && mPager.getCurrentItem() == BASIC_PANEL;
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700190 }
191
192 private boolean getAdvancedVisibility() {
Mindy Pereirae5179482011-09-14 13:09:57 -0700193 return mPager != null && mPager.getCurrentItem() == ADVANCED_PANEL;
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700194 }
195
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800196 @Override
197 public boolean onOptionsItemSelected(MenuItem item) {
198 switch (item.getItemId()) {
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700199 case R.id.clear_history:
200 mHistory.clear();
Mindy Pereiradf54c1e2011-08-22 17:30:05 -0700201 mLogic.onClear();
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700202 break;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800203
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700204 case R.id.basic:
Mindy Pereira6702e4b2012-05-03 09:47:40 -0700205 if (!getBasicVisibility() && mPager != null) {
Mindy Pereira05a16112012-05-18 08:21:16 -0700206 mPager.setCurrentItem(BASIC_PANEL, true);
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700207 }
208 break;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800209
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700210 case R.id.advanced:
Mindy Pereira6702e4b2012-05-03 09:47:40 -0700211 if (!getAdvancedVisibility() && mPager != null) {
Mindy Pereira05a16112012-05-18 08:21:16 -0700212 mPager.setCurrentItem(ADVANCED_PANEL, true);
Mindy Pereira0a1148f2011-08-22 17:30:05 -0700213 }
214 break;
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800215 }
216 return super.onOptionsItemSelected(item);
217 }
218
219 @Override
Mihai Predacf3ca322010-03-09 12:27:45 +0100220 protected void onSaveInstanceState(Bundle state) {
221 super.onSaveInstanceState(state);
Adam Powell353efcf2011-09-12 21:02:24 -0700222 if (mPager != null) {
223 state.putInt(STATE_CURRENT_VIEW, mPager.getCurrentItem());
Dmitri Plotnikove2092452011-01-16 15:27:03 -0800224 }
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800225 }
226
227 @Override
228 public void onPause() {
229 super.onPause();
230 mLogic.updateHistory();
Dmitri Plotnikov25018112011-01-17 16:32:39 -0800231 mPersist.setDeleteMode(mLogic.getDeleteMode());
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800232 mPersist.save();
233 }
234
Mihai Predabcabcbb2009-08-05 17:07:31 +0200235 @Override
236 public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
Mindy Pereira6702e4b2012-05-03 09:47:40 -0700237 if (keyCode == KeyEvent.KEYCODE_BACK && getAdvancedVisibility()
238 && mPager != null) {
Adam Powell353efcf2011-09-12 21:02:24 -0700239 mPager.setCurrentItem(BASIC_PANEL);
Mihai Predabcabcbb2009-08-05 17:07:31 +0200240 return true;
241 } else {
242 return super.onKeyDown(keyCode, keyEvent);
243 }
244 }
245
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800246 static void log(String message) {
247 if (LOG_ENABLED) {
248 Log.v(LOG_TAG, message);
249 }
250 }
Jacek Surazski1d311752009-08-25 17:33:12 +0200251
Dmitri Plotnikov052c92a2011-01-10 18:30:42 -0800252 @Override
253 public void onChange() {
254 invalidateOptionsMenu();
255 }
Dmitri Plotnikov25018112011-01-17 16:32:39 -0800256
257 @Override
258 public void onDeleteModeChange() {
259 updateDeleteMode();
260 }
Adam Powell353efcf2011-09-12 21:02:24 -0700261
262 class PageAdapter extends PagerAdapter {
263 private View mSimplePage;
264 private View mAdvancedPage;
265
266 public PageAdapter(ViewPager parent) {
267 final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
268 final View simplePage = inflater.inflate(R.layout.simple_pad, parent, false);
269 final View advancedPage = inflater.inflate(R.layout.advanced_pad, parent, false);
270 mSimplePage = simplePage;
271 mAdvancedPage = advancedPage;
272
273 final Resources res = getResources();
274 final TypedArray simpleButtons = res.obtainTypedArray(R.array.simple_buttons);
275 for (int i = 0; i < simpleButtons.length(); i++) {
276 setOnClickListener(simplePage, simpleButtons.getResourceId(i, 0));
277 }
278 simpleButtons.recycle();
279
280 final TypedArray advancedButtons = res.obtainTypedArray(R.array.advanced_buttons);
281 for (int i = 0; i < advancedButtons.length(); i++) {
282 setOnClickListener(advancedPage, advancedButtons.getResourceId(i, 0));
283 }
284 advancedButtons.recycle();
285
286 final View clearButton = simplePage.findViewById(R.id.clear);
287 if (clearButton != null) {
288 mClearButton = clearButton;
289 }
290
291 final View backspaceButton = simplePage.findViewById(R.id.del);
292 if (backspaceButton != null) {
293 mBackspaceButton = backspaceButton;
294 }
295 }
296
297 @Override
298 public int getCount() {
299 return 2;
300 }
301
302 @Override
303 public void startUpdate(View container) {
304 }
305
306 @Override
307 public Object instantiateItem(View container, int position) {
308 final View page = position == 0 ? mSimplePage : mAdvancedPage;
309 ((ViewGroup) container).addView(page);
310 return page;
311 }
312
313 @Override
314 public void destroyItem(View container, int position, Object object) {
315 ((ViewGroup) container).removeView((View) object);
316 }
317
318 @Override
319 public void finishUpdate(View container) {
320 }
321
322 @Override
323 public boolean isViewFromObject(View view, Object object) {
324 return view == object;
325 }
326
327 @Override
328 public Parcelable saveState() {
329 return null;
330 }
331
332 @Override
333 public void restoreState(Parcelable state, ClassLoader loader) {
334 }
335 }
The Android Open Source Projectb301ed22009-03-03 19:32:17 -0800336}