diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2007-04-16 09:14:36 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2007-04-16 09:14:36 +0000 |
commit | 6a5cc0bd25bd468c79e453fa49f353edd824141a (patch) | |
tree | 8b406e8390550ff8b87eae3214309867574657f0 /apps/gui/icon.c | |
parent | 7afe2e86931313653d4dedb6d5167c79c2822aba (diff) | |
download | rockbox-6a5cc0bd25bd468c79e453fa49f353edd824141a.tar.gz rockbox-6a5cc0bd25bd468c79e453fa49f353edd824141a.zip |
Customizable icons for all bitmap targets. (FS#7013)
http://www.rockbox.org/twiki/bin/view/Main/CustomIcons for info on format and how to load them
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13177 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/icon.c')
-rw-r--r-- | apps/gui/icon.c | 261 |
1 files changed, 242 insertions, 19 deletions
diff --git a/apps/gui/icon.c b/apps/gui/icon.c index ef6f61f94e..2cb0035ad7 100644 --- a/apps/gui/icon.c +++ b/apps/gui/icon.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) Robert E. Hak(2002) | 10 | * Copyright (C) 2007 Jonathan Gordon |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 12 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -16,42 +16,265 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | #include <stdio.h> | |
20 | #include <stdlib.h> | ||
21 | #include <string.h> | ||
22 | #include "inttypes.h" | ||
20 | #include "config.h" | 23 | #include "config.h" |
21 | #include "icon.h" | 24 | #include "icon.h" |
22 | #include "screen_access.h" | 25 | #include "screen_access.h" |
23 | #include "icons.h" | 26 | #include "icons.h" |
27 | #include "settings.h" | ||
28 | #include "bmp.h" | ||
29 | #include "filetypes.h" | ||
30 | |||
31 | /* Quick and Dirty hack untill lcd bitmap drawing is fixed */ | ||
32 | #ifdef HAVE_REMOTE_LCD | ||
33 | #include "lcd-remote.h" | ||
34 | #endif | ||
35 | |||
36 | |||
37 | #include <default_icons.h> | ||
38 | #ifdef HAVE_REMOTE_LCD | ||
39 | #include <remote_default_icons.h> | ||
40 | #endif | ||
41 | |||
42 | #define DEFAULT_VIEWER_BMP ICON_DIR "/viewers.bmp" | ||
43 | #define DEFAULT_REMOTE_VIEWER_BMP ICON_DIR "/remote_viewers.bmp" | ||
44 | |||
45 | /* These should robably be moved to config-<target>.h */ | ||
46 | #define MAX_ICON_HEIGHT 24 | ||
47 | #define MAX_ICON_WIDTH 24 | ||
48 | |||
49 | |||
50 | /* We dont actually do anything with these pointers, | ||
51 | but they need to be grouped like this to save code | ||
52 | so storing them as void* is ok. (stops compile warning) */ | ||
53 | static const void * inbuilt_icons[NB_SCREENS] = { | ||
54 | (void*)default_icons | ||
55 | #ifdef HAVE_REMOTE_LCD | ||
56 | , (void*)remote_default_icons | ||
57 | #endif | ||
58 | }; | ||
24 | 59 | ||
25 | /* Count in letter positions, NOT pixels */ | 60 | static const int default_width[NB_SCREENS] = { |
26 | void screen_put_iconxy(struct screen * display, int x, int y, ICON icon) | 61 | BMPWIDTH_default_icons |
62 | #ifdef HAVE_REMOTE_LCD | ||
63 | , BMPWIDTH_remote_default_icons | ||
64 | #endif | ||
65 | }; | ||
66 | |||
67 | /* height of whole file */ | ||
68 | static const int default_height[NB_SCREENS] = { | ||
69 | BMPHEIGHT_default_icons | ||
70 | #ifdef HAVE_REMOTE_LCD | ||
71 | , BMPHEIGHT_remote_default_icons | ||
72 | #endif | ||
73 | }; | ||
74 | |||
75 | #define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \ | ||
76 | Icon_Last_Themeable *LCD_DEPTH/8) | ||
77 | static unsigned char icon_buffer[IMG_BUFSIZE][NB_SCREENS]; | ||
78 | static bool custom_icons_loaded[NB_SCREENS] = {false}; | ||
79 | static struct bitmap user_iconset[NB_SCREENS]; | ||
80 | |||
81 | static unsigned char viewer_icon_buffer[IMG_BUFSIZE][NB_SCREENS]; | ||
82 | static bool viewer_icons_loaded[NB_SCREENS] = {false}; | ||
83 | static struct bitmap viewer_iconset[NB_SCREENS]; | ||
84 | |||
85 | |||
86 | #define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \ | ||
87 | default_height[screen] : \ | ||
88 | user_iconset[screen].height) \ | ||
89 | / Icon_Last_Themeable | ||
90 | |||
91 | #define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \ | ||
92 | default_width[screen] : \ | ||
93 | user_iconset[screen].width) | ||
94 | |||
95 | /* x,y in letters, not pixles */ | ||
96 | void screen_put_icon(struct screen * display, | ||
97 | int x, int y, enum themable_icons icon) | ||
98 | { | ||
99 | screen_put_icon_with_offset(display, x, y, 0, 0, icon); | ||
100 | } | ||
101 | |||
102 | void screen_put_icon_with_offset(struct screen * display, | ||
103 | int x, int y, int off_x, int off_y, | ||
104 | enum themable_icons icon) | ||
27 | { | 105 | { |
28 | #ifdef HAVE_LCD_BITMAP | ||
29 | int width, height; | ||
30 | int xpos, ypos; | 106 | int xpos, ypos; |
107 | int width, height; | ||
108 | int screen = display->screen_type; | ||
31 | display->getstringsize((unsigned char *)"M", &width, &height); | 109 | display->getstringsize((unsigned char *)"M", &width, &height); |
32 | xpos = x*CURSOR_WIDTH; | 110 | xpos = x*ICON_WIDTH(screen) + off_x; |
33 | ypos = y*height + display->getymargin(); | 111 | ypos = y*height + display->getymargin() + off_y; |
112 | |||
113 | if ( height > ICON_HEIGHT(screen) )/* center the cursor */ | ||
114 | ypos += (height - ICON_HEIGHT(screen)) / 2; | ||
115 | screen_put_iconxy(display, xpos, ypos, icon); | ||
116 | } | ||
34 | 117 | ||
35 | if ( height > CURSOR_HEIGHT )/* center the cursor */ | 118 | /* x,y in pixels */ |
36 | ypos += (height - CURSOR_HEIGHT) / 2; | 119 | typedef void (*lcd_draw_func)(const fb_data *src, int src_x, int src_y, |
37 | if(icon==0)/* Don't display invalid icons */ | 120 | int stride, int x, int y, int width, int height); |
38 | screen_clear_area(display, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT); | 121 | void screen_put_iconxy(struct screen * display, |
122 | int xpos, int ypos, enum themable_icons icon) | ||
123 | { | ||
124 | fb_data *data; | ||
125 | int screen = display->screen_type; | ||
126 | lcd_draw_func draw_func = NULL; | ||
127 | |||
128 | if (icon == Icon_NOICON) | ||
129 | { | ||
130 | screen_clear_area(display, xpos, ypos, | ||
131 | ICON_WIDTH(screen), ICON_HEIGHT(screen)); | ||
132 | return; | ||
133 | } | ||
134 | else if (icon >= Icon_Last_Themeable) | ||
135 | { | ||
136 | icon -= Icon_Last_Themeable; | ||
137 | if (!viewer_icons_loaded[screen] || | ||
138 | (icon*ICON_HEIGHT(screen) > viewer_iconset[screen].height)) | ||
139 | { | ||
140 | screen_clear_area(display, xpos, ypos, | ||
141 | ICON_WIDTH(screen), ICON_HEIGHT(screen)); | ||
142 | return; | ||
143 | } | ||
144 | data = (fb_data *)viewer_iconset[screen].data; | ||
145 | } | ||
146 | else if (custom_icons_loaded[screen]) | ||
147 | { | ||
148 | data = (fb_data *)user_iconset[screen].data; | ||
149 | } | ||
39 | else | 150 | else |
40 | display->mono_bitmap(icon, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT); | 151 | { |
41 | #else | 152 | data = (fb_data *)inbuilt_icons[screen]; |
42 | if(icon==-1) | 153 | } |
43 | display->putc(x, y, ' '); | 154 | /* add some left padding to the icons if they are on the edge */ |
155 | if (xpos == 0) | ||
156 | xpos++; | ||
157 | |||
158 | #ifdef HAVE_REMOTE_LCD | ||
159 | if (display->screen_type == SCREEN_REMOTE) | ||
160 | { | ||
161 | /* Quick and Dirty hack untill lcd bitmap drawing is fixed */ | ||
162 | draw_func = (lcd_draw_func)lcd_remote_bitmap_part; | ||
163 | } | ||
44 | else | 164 | else |
45 | display->putc(x, y, icon); | ||
46 | #endif | 165 | #endif |
166 | #if LCD_DEPTH == 16 | ||
167 | draw_func = display->transparent_bitmap_part; | ||
168 | #else /* LCD_DEPTH < 16 */ | ||
169 | draw_func = display->bitmap_part; | ||
170 | #endif /* LCD_DEPTH == 16 */ | ||
171 | |||
172 | draw_func( (const fb_data *)data, | ||
173 | 0, ICON_HEIGHT(screen)*icon, | ||
174 | ICON_WIDTH(screen), xpos, ypos, | ||
175 | ICON_WIDTH(screen), ICON_HEIGHT(screen)); | ||
47 | } | 176 | } |
48 | 177 | ||
49 | void screen_put_cursorxy(struct screen * display, int x, int y, bool on) | 178 | void screen_put_cursorxy(struct screen * display, int x, int y, bool on) |
50 | { | 179 | { |
51 | #ifdef HAVE_LCD_BITMAP | 180 | #ifdef HAVE_LCD_BITMAP |
52 | screen_put_iconxy(display, x, y, on?bitmap_icons_6x8[Icon_Cursor]:0); | 181 | screen_put_icon(display, x, y, on?Icon_Cursor:0); |
53 | #else | 182 | #else |
54 | screen_put_iconxy(display, x, y, on?CURSOR_CHAR:-1); | 183 | screen_put_icon(display, x, y, on?CURSOR_CHAR:-1); |
55 | #endif | 184 | #endif |
56 | 185 | ||
57 | } | 186 | } |
187 | enum Iconset { | ||
188 | Iconset_Mainscreen, | ||
189 | Iconset_Mainscreen_viewers, | ||
190 | #ifdef HAVE_REMOTE_LCD | ||
191 | Iconset_Remotescreen, | ||
192 | Iconset_Remotescreen_viewers, | ||
193 | #endif | ||
194 | }; | ||
195 | |||
196 | static void load_icons(const char* filename, enum Iconset iconset) | ||
197 | { | ||
198 | int size_read; | ||
199 | bool *loaded_ok = NULL; | ||
200 | struct bitmap *bmp = NULL; | ||
201 | |||
202 | switch (iconset) | ||
203 | { | ||
204 | case Iconset_Mainscreen: | ||
205 | loaded_ok = &custom_icons_loaded[SCREEN_MAIN]; | ||
206 | bmp = &user_iconset[SCREEN_MAIN]; | ||
207 | bmp->data = icon_buffer[SCREEN_MAIN]; | ||
208 | break; | ||
209 | case Iconset_Mainscreen_viewers: | ||
210 | loaded_ok = &viewer_icons_loaded[SCREEN_MAIN]; | ||
211 | bmp = &viewer_iconset[SCREEN_MAIN]; | ||
212 | bmp->data = viewer_icon_buffer[SCREEN_MAIN]; | ||
213 | break; | ||
214 | #ifdef HAVE_REMOTE_LCD | ||
215 | case Iconset_Remotescreen: | ||
216 | loaded_ok = &custom_icons_loaded[SCREEN_MAIN]; | ||
217 | bmp = &user_iconset[SCREEN_MAIN]; | ||
218 | bmp->data = icon_buffer[SCREEN_MAIN]; | ||
219 | break; | ||
220 | case Iconset_Remotescreen_viewers: | ||
221 | loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE]; | ||
222 | bmp = &viewer_iconset[SCREEN_REMOTE]; | ||
223 | bmp->data = viewer_icon_buffer[SCREEN_REMOTE]; | ||
224 | break; | ||
225 | #endif | ||
226 | } | ||
227 | |||
228 | *loaded_ok = false; | ||
229 | if (filename != NULL) | ||
230 | { | ||
231 | size_read = read_bmp_file((char*)filename, bmp, IMG_BUFSIZE, | ||
232 | FORMAT_NATIVE | FORMAT_DITHER); | ||
233 | if (size_read > 0) | ||
234 | { | ||
235 | *loaded_ok = true; | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | |||
241 | void icons_init(void) | ||
242 | { | ||
243 | char path[MAX_PATH]; | ||
244 | if (global_settings.icon_file[0]) | ||
245 | { | ||
246 | snprintf(path, MAX_PATH, "%s/%s.bmp", | ||
247 | ICON_DIR, global_settings.icon_file); | ||
248 | load_icons(path, Iconset_Mainscreen); | ||
249 | } | ||
250 | if (global_settings.viewers_icon_file[0]) | ||
251 | { | ||
252 | snprintf(path, MAX_PATH, "%s/%s.bmp", | ||
253 | ICON_DIR, global_settings.viewers_icon_file); | ||
254 | load_icons(path, Iconset_Mainscreen_viewers); | ||
255 | read_viewer_theme_file(); | ||
256 | } | ||
257 | else | ||
258 | load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers); | ||
259 | #ifdef HAVE_REMOTE_LCD | ||
260 | if (global_settings.remote_icon_file[0]) | ||
261 | { | ||
262 | snprintf(path, MAX_PATH, "%s/%s.bmp", | ||
263 | ICON_DIR, global_settings.remote_icon_file); | ||
264 | load_icons(path, Iconset_Remotescreen); | ||
265 | } | ||
266 | if (global_settings.remote_viewers_icon_file[0]) | ||
267 | { | ||
268 | snprintf(path, MAX_PATH, "%s/%s.bmp", | ||
269 | ICON_DIR, global_settings.remote_viewers_icon_file); | ||
270 | load_icons(path, Iconset_Remotescreen_viewers); | ||
271 | } | ||
272 | else | ||
273 | load_icons(DEFAULT_REMOTE_VIEWER_BMP, Iconset_Mainscreen_viewers); | ||
274 | #endif | ||
275 | } | ||
276 | |||
277 | int get_icon_width(enum screen_type screen_type) | ||
278 | { | ||
279 | return ICON_WIDTH(screen_type); | ||
280 | } | ||