1 /***
2 * Ambient - A music player for the Android platform
3 Copyright (C) 2007 Martin Vysny
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 package sk.baka.ambient.activity.main;
19
20 import java.util.List;
21
22 import sk.baka.ambient.ActionsEnum;
23 import sk.baka.ambient.AmbientApplication;
24 import sk.baka.ambient.commons.Interval;
25 import sk.baka.ambient.views.ButtonBar;
26 import android.app.Activity;
27 import android.graphics.Point;
28 import android.view.View;
29 import android.view.View.OnClickListener;
30 import android.widget.AdapterView;
31 import android.widget.AdapterView.OnItemClickListener;
32
33 /***
34 * A base class each controller must extend. Defines common operations.
35 *
36 * @author Martin Vysny
37 */
38 public abstract class AbstractController {
39 /***
40 * The main view controlled by this controller.
41 */
42 protected View mainView;
43
44 /***
45 * Reference to the main activity.
46 */
47 protected Activity mainActivity;
48
49 /***
50 * Creates new controller.
51 *
52 * @param mainViewId
53 * the view whose visibility is controlled.
54 * @param mainActivity
55 * the activity.
56 */
57 protected AbstractController(final int mainViewId,
58 final Activity mainActivity) {
59 super();
60 this.mainView = mainActivity.findViewById(mainViewId);
61 if (mainView == null) {
62 throw new IllegalArgumentException("No view with id " + mainViewId);
63 }
64 this.mainActivity = mainActivity;
65 app = AmbientApplication.getInstance();
66 }
67
68 /***
69 * Flips the player visibility - shows it if it is hidden or vice versa.
70 */
71 public final void flipVisibility() {
72 if (isVisible()) {
73 hide();
74 } else {
75 show();
76 }
77 }
78
79 /***
80 * Checks if the view controlled by this controller is visible.
81 *
82 * @return <code>true</code> if visible, <code>false</code> otherwise.
83 */
84 public final boolean isVisible() {
85 return mainView.getVisibility() == View.VISIBLE;
86 }
87
88 /***
89 * Shows the view on screen.
90 */
91 public final void show() {
92 if (!isVisible()) {
93 mainView.setVisibility(View.VISIBLE);
94 visibilityChanged(true);
95 }
96 }
97
98 /***
99 * Invoked when the component visibility changes. By default does nothing.
100 *
101 * @param visible
102 * new visibility flag.
103 */
104 protected void visibilityChanged(boolean visible) {
105
106 }
107
108 /***
109 * Hides the view and removes it (the {@link View#GONE} functionality).
110 */
111 public final void hide() {
112 if (isVisible()) {
113 mainView.setVisibility(View.GONE);
114 visibilityChanged(false);
115 }
116 }
117
118 /***
119 * Sets the visibility of the view controlled by this controller.
120 *
121 * @param visible
122 * if <code>true</code> then the view is made visible, otherwise
123 * it is made GONE.
124 */
125 public final void setVisibility(final boolean visible) {
126 if (visible) {
127 show();
128 } else {
129 hide();
130 }
131 }
132
133 /***
134 * Called when an action button is pressed. By default invokes main
135 * activity. Subclasses can override.
136 *
137 * @param action
138 * the action to take
139 */
140 protected void onAction(final ActionsEnum action) {
141 ((MainActivity) mainActivity).activateAction(action, cycle);
142 }
143
144 /***
145 * If <code>true</code> then random/repeat modes are cycled instead of being
146 * activated.
147 */
148 protected boolean cycle = false;
149
150 /***
151 * The activity button listener.
152 */
153 protected final class Listener implements OnClickListener,
154 OnItemClickListener {
155 public void onClick(View arg0) {
156 final ActionsEnum action = (ActionsEnum) arg0.getTag();
157 onAction(action);
158 }
159
160 @SuppressWarnings("unchecked")
161 public void onItemClick(AdapterView parent, View v, int position,
162 long id) {
163 final List<? extends ActionsEnum> actions = (List<? extends ActionsEnum>) v
164 .getTag();
165 onAction(actions.get(position));
166 }
167 }
168
169 /***
170 * Listens for click actions and activates {@link ActionsEnum} stored in the
171 * tag values.
172 */
173 protected final Listener listener = new Listener();
174
175 /***
176 * Returns the application instance.
177 */
178 protected AmbientApplication app;
179
180 /***
181 * Reinitializes the underlying view. Used when the view was not updated for
182 * a time and is about to be shown on screen. Default implementation does
183 * nothing.
184 *
185 * @param select
186 * reset selection to this interval.
187 */
188 public void update(final Interval select) {
189
190 }
191
192 /***
193 * Initializes given button bar with buttons. The size is 32x32 (48x48 when
194 * hovered) when not zoomed, 48x48 (64x64 when hovered) when zoomed.
195 *
196 * @param buttonbarId
197 * the resource id of the {@link ButtonBar} component.
198 * @param actions
199 * the list of actions.
200 */
201 protected void initButtonBar(final int buttonbarId,
202 List<ActionsEnum> actions) {
203 initButtonBar(buttonbarId, actions, zoom ? new Point(48, 48)
204 : new Point(32, 32), zoom ? new Point(64, 64) : new Point(48,
205 48));
206 }
207
208 /***
209 * Initializes given button bar with buttons.
210 *
211 * @param buttonbarId
212 * the resource id of the {@link ButtonBar} component.
213 * @param actions
214 * the list of actions.
215 * @param bitmapSize
216 * the size of all buttons.
217 * @param hoveredBitmapSize
218 * maximum size of a button when hovered.
219 */
220 protected void initButtonBar(final int buttonbarId,
221 List<ActionsEnum> actions, final Point bitmapSize,
222 final Point hoveredBitmapSize) {
223 final ButtonBar bar = (ButtonBar) mainView.findViewById(buttonbarId);
224 bar.listener = listener;
225 initButtonBar(bar, actions, bitmapSize, hoveredBitmapSize);
226 }
227
228 /***
229 * Initializes given button bar with buttons.
230 *
231 * @param bar
232 * the {@link ButtonBar} component.
233 * @param actions
234 * the list of actions.
235 * @param bitmapSize
236 * the size of all buttons.
237 * @param hoveredBitmapSize
238 * maximum size of a button when hovered.
239 */
240 public static final void initButtonBar(final ButtonBar bar,
241 final List<ActionsEnum> actions, final Point bitmapSize,
242 final Point hoveredBitmapSize) {
243 final int[] images = new int[actions.size()];
244 final int[] captions = new int[actions.size()];
245 for (int i = 0; i < actions.size(); i++) {
246 images[i] = actions.get(i).icon;
247 captions[i] = actions.get(i).caption;
248 }
249 bar.setBitmaps(images, captions, bitmapSize, hoveredBitmapSize);
250 bar.setTag(actions);
251 }
252
253 /***
254 * The controller is about to be destroyed. No invocations are performed
255 * after this call. The controller should release its resources, stop its
256 * activities etc. Make sure that you call {@code super()} if you override
257 * this method!
258 */
259 public void destroy() {
260 mainActivity = null;
261 mainView = null;
262 }
263
264 /***
265 * Checks if this controller was destroyed.
266 *
267 * @return <code>true</code> if this controller is destroyed.
268 */
269 protected final boolean isDestroyed() {
270 return mainActivity == null;
271 }
272
273 @Override
274 public final boolean equals(Object o) {
275 if (o == null) {
276 return false;
277 }
278 return getClass().equals(o.getClass());
279 }
280
281 @Override
282 public final int hashCode() {
283 return getClass().hashCode();
284 }
285
286 /***
287 * Zooms, or un-zooms the controller.
288 *
289 * @param zoom
290 * <code>true</code> zoom the controller in, <code>false</code>
291 * zoom the controller out.
292 */
293 public final void zoom(final boolean zoom) {
294 this.zoom = zoom;
295 performZoom(zoom);
296 }
297
298 /***
299 * Zooms, or un-zooms the controller.
300 *
301 * @param zoom
302 * <code>true</code> zoom the controller in, <code>false</code>
303 * zoom the controller out.
304 */
305 protected abstract void performZoom(boolean zoom);
306
307 private boolean zoom = false;
308
309 /***
310 * Checks if this controller is zoomed.
311 *
312 * @return <code>true</code> if zoomed, <code>false</code> otherwise.
313 */
314 protected final boolean isZoomed() {
315 return zoom;
316 }
317 }