Calculator.java revision 6702e4b5d52ec458a18ecc1382d020debedb2a8f
1/*
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;
20import android.content.res.Resources;
21import android.content.res.TypedArray;
22import android.os.Bundle;
23import android.os.Parcelable;
24import android.support.v4.view.PagerAdapter;
25import android.support.v4.view.ViewPager;
26import android.util.Log;
27import android.view.KeyEvent;
28import android.view.LayoutInflater;
29import android.view.Menu;
30import android.view.MenuItem;
31import android.view.View;
32import android.view.View.OnClickListener;
33import android.view.ViewConfiguration;
34import android.view.ViewGroup;
35import android.view.WindowManager;
36import android.widget.PopupMenu;
37import android.widget.PopupMenu.OnMenuItemClickListener;
38
39public class Calculator extends Activity implements PanelSwitcher.Listener, Logic.Listener,
40        OnClickListener, OnMenuItemClickListener {
41    EventListener mListener = new EventListener();
42    private CalculatorDisplay mDisplay;
43    private Persist mPersist;
44    private History mHistory;
45    private Logic mLogic;
46    private ViewPager mPager;
47    private View mClearButton;
48    private View mBackspaceButton;
49    private View mOverflowMenuButton;
50
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;
56    private static final boolean LOG_ENABLED = false;
57    private static final String STATE_CURRENT_VIEW = "state-current-view";
58
59    @Override
60    public void onCreate(Bundle state) {
61        super.onCreate(state);
62
63        // Disable IME for this application
64        getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
65                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
66
67        setContentView(R.layout.main);
68        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        }
90
91        mPersist = new Persist(this);
92        mPersist.load();
93
94        mHistory = mPersist.history;
95
96        mDisplay = (CalculatorDisplay) findViewById(R.id.display);
97
98        mLogic = new Logic(this, mHistory, mDisplay);
99        mLogic.setListener(this);
100
101        mLogic.setDeleteMode(mPersist.getDeleteMode());
102        mLogic.setLineLength(mDisplay.getMaxDigits());
103
104        HistoryAdapter historyAdapter = new HistoryAdapter(this, mHistory, mLogic);
105        mHistory.setObserver(historyAdapter);
106
107        if (mPager != null) {
108            mPager.setCurrentItem(state == null ? 0 : state.getInt(STATE_CURRENT_VIEW, 0));
109        }
110
111        mListener.setHandler(mLogic, mPager);
112        mDisplay.setOnKeyListener(mListener);
113
114        if (!ViewConfiguration.get(this).hasPermanentMenuKey()) {
115            createFakeMenu();
116        }
117
118        mLogic.resumeWithHistory();
119        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);
129        }
130    }
131
132    void setOnClickListener(View root, int id) {
133        final View target = root != null ? root.findViewById(id) : findViewById(id);
134        target.setOnClickListener(mListener);
135    }
136
137    @Override
138    public boolean onCreateOptionsMenu(Menu menu) {
139        super.onCreateOptionsMenu(menu);
140        getMenuInflater().inflate(R.menu.menu, menu);
141        return true;
142    }
143
144    @Override
145    public boolean onPrepareOptionsMenu(Menu menu) {
146        super.onPrepareOptionsMenu(menu);
147        menu.findItem(R.id.basic).setVisible(!getBasicVisibility());
148        menu.findItem(R.id.advanced).setVisible(!getAdvancedVisibility());
149        return true;
150    }
151
152
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() {
189        return mPager != null && mPager.getCurrentItem() == BASIC_PANEL;
190    }
191
192    private boolean getAdvancedVisibility() {
193        return mPager != null && mPager.getCurrentItem() == ADVANCED_PANEL;
194    }
195
196    @Override
197    public boolean onOptionsItemSelected(MenuItem item) {
198        switch (item.getItemId()) {
199            case R.id.clear_history:
200                mHistory.clear();
201                mLogic.onClear();
202                break;
203
204            case R.id.basic:
205                if (!getBasicVisibility() && mPager != null) {
206                    mPager.setCurrentItem(BASIC_PANEL);
207                }
208                break;
209
210            case R.id.advanced:
211                if (!getAdvancedVisibility() && mPager != null) {
212                    mPager.setCurrentItem(ADVANCED_PANEL);
213                }
214                break;
215        }
216        return super.onOptionsItemSelected(item);
217    }
218
219    @Override
220    protected void onSaveInstanceState(Bundle state) {
221        super.onSaveInstanceState(state);
222        if (mPager != null) {
223            state.putInt(STATE_CURRENT_VIEW, mPager.getCurrentItem());
224        }
225    }
226
227    @Override
228    public void onPause() {
229        super.onPause();
230        mLogic.updateHistory();
231        mPersist.setDeleteMode(mLogic.getDeleteMode());
232        mPersist.save();
233    }
234
235    @Override
236    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
237        if (keyCode == KeyEvent.KEYCODE_BACK && getAdvancedVisibility()
238                && mPager != null) {
239            mPager.setCurrentItem(BASIC_PANEL);
240            return true;
241        } else {
242            return super.onKeyDown(keyCode, keyEvent);
243        }
244    }
245
246    static void log(String message) {
247        if (LOG_ENABLED) {
248            Log.v(LOG_TAG, message);
249        }
250    }
251
252    @Override
253    public void onChange() {
254        invalidateOptionsMenu();
255    }
256
257    @Override
258    public void onDeleteModeChange() {
259        updateDeleteMode();
260    }
261
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    }
336}
337