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
19 package sk.baka.ambient.views.gesturelist;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import sk.baka.ambient.commons.Interval;
25 import android.view.View;
26
27 /***
28 * <p>
29 * Manages the model for the {@link GesturesListView}.
30 * </p>
31 * <p>
32 * Handles special End Of Playlist item - this item allows us to insert tracks
33 * at the end of the playlist (and into an empty playlist) using keypad
34 * gestures. The special item is shown only when the list view:
35 * </p>
36 * <ul>
37 * <li>is modifiable</li>
38 * <li>has focus (this property however does not alter the return value of the
39 * function, i.e. the function can return <code>true</code> even if the list
40 * view does not have focus)</li>
41 * <li>is not in the {@link View#isInTouchMode() touch mode}</li>
42 * <li>the clipboard is not empty</li>
43 * </ul>
44 *
45 * @author Martin Vysny
46 */
47 public final class ModelHolder {
48 /***
49 * The owner.
50 */
51 private final GesturesListView owner;
52
53 /***
54 * Creates new instance.
55 *
56 * @param owner
57 * owner listview.
58 */
59 ModelHolder(final GesturesListView owner) {
60 super();
61 this.owner = owner;
62
63
64
65 adapter = new MutableListAdapter(owner, this);
66 }
67
68 /***
69 * The backing array of item data. In the MVC terminology, this is a model
70 * for all items. This list will never contain the EOP object - this object
71 * is factored by the {@link MutableListAdapter}.
72 */
73 private final List<Object> model = new ArrayList<Object>();
74
75 /***
76 * The backing adapter.
77 */
78 final MutableListAdapter adapter;
79
80 /***
81 * <p>
82 * Returns a list of items. The backing array of item data. In the MVC
83 * terminology, this is a model for all items. If you plan to modify this
84 * list, do not forget to call {@link #notifyModified()} after all
85 * modifications are made.
86 * </p>
87 * <p>
88 * This model must never contain the
89 * {@link MutableListAdapter#EOP_MODEL_MARKER} object!
90 * </p>
91 *
92 * @return a live list of item data.
93 */
94 public List<Object> getModel() {
95 return model;
96 }
97
98 /***
99 * Redraws items and reflects changes made to the {@link #getModel()} list.
100 */
101 public void notifyModified() {
102 adapter.notifyModified();
103 }
104
105 /***
106 * These items are highlighted.
107 */
108 private Interval highlight = Interval.EMPTY;
109
110 /***
111 * Highlight given items. Does not update the view - you need to call
112 * {@link #notifyModified()} to force the redraw.
113 *
114 * @param highlight
115 * items to highlight
116 */
117 public void highlight(final Interval highlight) {
118 Interval newHighlight = highlight;
119 if (newHighlight.end >= model.size()) {
120 newHighlight = new Interval(newHighlight.start, model.size());
121 }
122 if (newHighlight.equals(this.highlight))
123 return;
124 this.highlight = newHighlight;
125 owner.listener.highlightChanged(this.highlight);
126 }
127
128 /***
129 * Returns current highlight.
130 *
131 * @return current highlight, never <code>null</code>.
132 */
133 public Interval getHighlight() {
134 return highlight;
135 }
136
137 /***
138 * Returns current highlight. If no items are highlighted, optionally return
139 * current selection.
140 *
141 * @param returnSelectionOnEmptyHighlight
142 * if <code>true</code> and no items are currently being
143 * highlighted, return current selection.
144 *
145 * @return current highlight, never <code>null</code>.
146 */
147 public Interval getHighlight(final boolean returnSelectionOnEmptyHighlight) {
148 if (highlight.isEmpty() && returnSelectionOnEmptyHighlight) {
149 final int sel = owner.getSelectedItemPosition();
150 return (sel < 0) || (sel >= model.size()) ? Interval.EMPTY
151 : Interval.fromItem(sel);
152 }
153 return getHighlight();
154 }
155
156 /***
157 * Returns current highlight. If no items are highlighted, optionally return
158 * given item.
159 *
160 * @param returnSelectionOnEmptyHighlight
161 * if not negative and no items are currently being highlighted,
162 * return selection consisting of a single item.
163 *
164 * @return current highlight, never <code>null</code>.
165 */
166 public Interval getHighlight(final int returnSelectionOnEmptyHighlight) {
167 if (highlight.isEmpty() && (returnSelectionOnEmptyHighlight >= 0)
168 && (returnSelectionOnEmptyHighlight < model.size())) {
169 return Interval.fromItem(returnSelectionOnEmptyHighlight);
170 }
171 return getHighlight();
172 }
173
174 /***
175 * Returns interval containing all items.
176 *
177 * @return non-<code>null</code> interval.
178 */
179 public Interval getAllItems() {
180 return new Interval(0, model.size());
181 }
182 }