1/*
2 * Copyright (C) 2007 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 android.view.menu;
18
19import android.app.Activity;
20import android.os.Bundle;
21import android.util.ListScenario;
22import android.util.SparseArray;
23import android.view.Menu;
24import android.view.MenuItem;
25
26/**
27 * Utility base class for creating various Menu scenarios. Configurable by the
28 * number of menu items. Used @link {@link ListScenario} as a reference.
29 */
30public class MenuScenario extends Activity implements MenuItem.OnMenuItemClickListener {
31    private Params mParams = new Params();
32    private Menu mMenu;
33    private MenuItem[] mItems;
34    private boolean[] mWasItemClicked;
35
36    @Override
37    protected void onCreate(Bundle icicle) {
38        super.onCreate(icicle);
39
40        dispatchInitParams();
41    }
42
43    private void dispatchInitParams() {
44        onInitParams(mParams);
45        onParamsChanged();
46    }
47
48    public void setParams(Params params) {
49        mParams = params;
50        onParamsChanged();
51    }
52
53    public void onParamsChanged() {
54        mItems = new MenuItem[mParams.numItems];
55        mWasItemClicked = new boolean[mParams.numItems];
56    }
57
58    @Override
59    public boolean onCreateOptionsMenu(Menu menu) {
60        // Safe to hold on to
61        mMenu = menu;
62
63        if (!mParams.shouldShowMenu) return false;
64
65        MenuItem item;
66        for (int i = 0; i < mParams.numItems; i++) {
67            if ((item = onAddMenuItem(menu, i)) == null) {
68                // Add a default item for this position if the subclasses
69                // haven't
70                CharSequence givenTitle = mParams.itemTitles.get(i);
71                item = menu.add(0, 0, 0, (givenTitle != null) ? givenTitle : ("Item " + i));
72            }
73
74            if (item != null) {
75                mItems[i] = item;
76
77                if (mParams.listenForClicks) {
78                    item.setOnMenuItemClickListener(this);
79                }
80            }
81
82        }
83
84        return true;
85    }
86
87    @Override
88    public boolean onPrepareOptionsMenu(Menu menu) {
89        // Safe to hold on to
90        mMenu = menu;
91
92        return mParams.shouldShowMenu;
93    }
94
95    /**
96     * Override this to add an item to the menu.
97     *
98     * @param itemPosition The position of the item to add (only for your
99     *            reference).
100     * @return The item that was added to the menu, or null if nothing was
101     *         added.
102     */
103    protected MenuItem onAddMenuItem(Menu menu, int itemPosition) {
104        return null;
105    }
106
107    /**
108     * Override this to set the parameters for the scenario. Call through to super first.
109     *
110     * @param params
111     */
112    protected void onInitParams(Params params) {
113    }
114
115    public Menu getMenu() {
116        return mMenu;
117    }
118
119    public boolean onMenuItemClick(MenuItem item) {
120        final int position = findItemPosition(item);
121        if (position < 0) return false;
122
123        mWasItemClicked[position] = true;
124
125        return true;
126    }
127
128    public boolean wasItemClicked(int position) {
129        return mWasItemClicked[position];
130    }
131
132    /**
133     * Finds the position for a given Item.
134     *
135     * @param item The item to find.
136     * @return The position, or -1 if not found.
137     */
138    public int findItemPosition(MenuItem item) {
139        // Could create reverse mapping, but optimizations aren't important (yet :P)
140        for (int i = 0; i < mParams.numItems; i++) {
141            if (mItems[i] == item) return i;
142        }
143
144        return -1;
145    }
146
147    public static class Params {
148        // Using as data structure, so no m prefix
149        private boolean shouldShowMenu = true;
150        private int numItems = 10;
151        private boolean listenForClicks = true;
152        private SparseArray<CharSequence> itemTitles = new SparseArray<CharSequence>();
153
154        public Params setShouldShowMenu(boolean shouldShowMenu) {
155            this.shouldShowMenu = shouldShowMenu;
156            return this;
157        }
158
159        public Params setNumItems(int numItems) {
160            this.numItems = numItems;
161            return this;
162        }
163
164        public Params setListenForClicks(boolean listenForClicks) {
165            this.listenForClicks = listenForClicks;
166            return this;
167        }
168
169        public Params setItemTitle(int itemPos, CharSequence title) {
170            itemTitles.put(itemPos, title);
171            return this;
172        }
173    }
174}
175