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;
20
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import sk.baka.ambient.R;
25
26 import android.content.Context;
27 import android.text.Spannable;
28 import android.text.SpannableStringBuilder;
29 import android.text.Spanned;
30 import android.text.style.ImageSpan;
31 import android.text.util.Linkify;
32
33 /***
34 * A play on the {@link Linkify} class - iconifies given spannables instead.
35 *
36 * @author Martin Vysny
37 */
38 public final class Iconify {
39 private Iconify() {
40 throw new Error();
41 }
42
43 private final static Map<String, Integer> keyIconMap = new HashMap<String, Integer>();
44 static {
45 keyIconMap.put("U", android.R.drawable.arrow_up_float);
46 keyIconMap.put("D", android.R.drawable.arrow_down_float);
47 keyIconMap.put("DEL", R.drawable.del);
48 keyIconMap.put("B", R.drawable.btn_back);
49 keyIconMap.put("C", android.R.drawable.checkbox_off_background);
50 keyIconMap.put("L", R.drawable.arrow_left_float);
51 keyIconMap.put("R", R.drawable.arrow_right_float);
52 keyIconMap.put("l", R.drawable.touch_left);
53 keyIconMap.put("r", R.drawable.touch_right);
54 keyIconMap.put("lu", R.drawable.touch_lu);
55 keyIconMap.put("ld", R.drawable.touch_ld);
56 keyIconMap.put("ru", R.drawable.touch_ru);
57 keyIconMap.put("rd", R.drawable.touch_rd);
58 keyIconMap.put("u", R.drawable.touch_up);
59 keyIconMap.put("d", R.drawable.touch_down);
60 }
61
62 /***
63 * Iconifies given spannable.
64 *
65 * @param c
66 * the context
67 * @param s
68 * the spannable
69 */
70 public static void iconify(final Context c, final Spannable s) {
71 for (int i = 0; i < s.length();) {
72 i = findNextDiv(s, i);
73 if (i < 0) {
74 return;
75 }
76 int nextDiv = findNextDiv(s, i + 1);
77 if (nextDiv < 0) {
78 return;
79 }
80 final String icon = s.subSequence(i + 1, nextDiv).toString();
81 replace(c, s, i, icon.length() + 2, keyIconMap.get(icon));
82 i = nextDiv + 1;
83 }
84 }
85
86 private static int findNextDiv(Spannable s, int start) {
87 for (int i = start; i < s.length(); i++) {
88 final char ch = s.charAt(i);
89 if (ch == '#') {
90 return i;
91 }
92 }
93 return -1;
94 }
95
96 /***
97 * Loads and iconifies given spannable.
98 *
99 * @param c
100 * the context
101 * @param stringResId
102 * the string resource ID
103 * @return iconified spannable.
104 */
105 public static CharSequence iconify(final Context c, final int stringResId) {
106 final SpannableStringBuilder sb = new SpannableStringBuilder(c
107 .getResources().getText(stringResId));
108 iconify(c, sb);
109 return sb;
110 }
111
112 private static void replace(final Context c, Spannable s, int currentPos,
113 int matchLen, Integer resId) {
114 if (resId == null) {
115 return;
116 }
117 s.setSpan(new ImageSpan(c, resId), currentPos, currentPos + matchLen,
118 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
119 }
120 }