Some gremlins got into my computer again and changed all my code!
[Rockbox.git] / apps / gui / icon.c
blob647c15434ef78b7b86c792fe7fb6ae6489881354
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "inttypes.h"
23 #include "config.h"
24 #include "icon.h"
25 #include "screen_access.h"
26 #include "icons.h"
27 #include "settings.h"
28 #include "bmp.h"
29 #include "filetypes.h"
31 /* Quick and Dirty hack untill lcd bitmap drawing is fixed */
32 #ifdef HAVE_REMOTE_LCD
33 #include "lcd-remote.h"
34 #endif
37 #include <default_icons.h>
38 #ifdef HAVE_REMOTE_LCD
39 #include <remote_default_icons.h>
40 #endif
42 #define DEFAULT_VIEWER_BMP ICON_DIR "/viewers.bmp"
43 #define DEFAULT_REMOTE_VIEWER_BMP ICON_DIR "/remote_viewers.bmp"
45 /* These should probably be moved to config-<target>.h */
46 #define MAX_ICON_HEIGHT 24
47 #define MAX_ICON_WIDTH 24
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
60 static const int default_width[NB_SCREENS] = {
61 BMPWIDTH_default_icons
62 #ifdef HAVE_REMOTE_LCD
63 , BMPWIDTH_remote_default_icons
64 #endif
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
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];
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];
86 #define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \
87 default_height[screen] : \
88 user_iconset[screen].height) \
89 / Icon_Last_Themeable
91 #define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \
92 default_width[screen] : \
93 user_iconset[screen].width)
95 /* x,y in letters, not pixles */
96 void screen_put_icon(struct screen * display,
97 int x, int y, enum themable_icons icon)
99 screen_put_icon_with_offset(display, x, y, 0, 0, icon);
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)
106 int xpos, ypos;
107 int width, height;
108 int screen = display->screen_type;
109 display->getstringsize((unsigned char *)"M", &width, &height);
110 xpos = x*ICON_WIDTH(screen) + off_x;
111 ypos = y*height + display->getymargin() + off_y;
113 if ( height > ICON_HEIGHT(screen) )/* center the cursor */
114 ypos += (height - ICON_HEIGHT(screen)) / 2;
115 screen_put_iconxy(display, xpos, ypos, icon);
118 /* x,y in pixels */
119 typedef void (*lcd_draw_func)(const fb_data *src, int src_x, int src_y,
120 int stride, int x, int y, int width, int height);
121 void screen_put_iconxy(struct screen * display,
122 int xpos, int ypos, enum themable_icons icon)
124 fb_data *data;
125 int screen = display->screen_type;
126 lcd_draw_func draw_func = NULL;
128 if (icon == Icon_NOICON)
130 screen_clear_area(display, xpos, ypos,
131 ICON_WIDTH(screen), ICON_HEIGHT(screen));
132 return;
134 else if (icon >= Icon_Last_Themeable)
136 icon -= Icon_Last_Themeable;
137 if (!viewer_icons_loaded[screen]/* ||
138 (icon*ICON_HEIGHT(screen) > viewer_iconset[screen].height)*/)
140 screen_clear_area(display, xpos, ypos,
141 ICON_WIDTH(screen), ICON_HEIGHT(screen));
142 return;
144 data = (fb_data *)viewer_iconset[screen].data;
146 else if (custom_icons_loaded[screen])
148 data = (fb_data *)user_iconset[screen].data;
150 else
152 data = (fb_data *)inbuilt_icons[screen];
154 /* add some left padding to the icons if they are on the edge */
155 if (xpos == 0)
156 xpos++;
158 #ifdef HAVE_REMOTE_LCD
159 if (display->screen_type == SCREEN_REMOTE)
161 /* Quick and Dirty hack untill lcd bitmap drawing is fixed */
162 draw_func = (lcd_draw_func)lcd_remote_bitmap_part;
164 else
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 */
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));
178 void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
180 #ifdef HAVE_LCD_BITMAP
181 screen_put_icon(display, x, y, on?Icon_Cursor:0);
182 #else
183 screen_put_icon(display, x, y, on?CURSOR_CHAR:-1);
184 #endif
187 enum Iconset {
188 Iconset_Mainscreen,
189 Iconset_Mainscreen_viewers,
190 #ifdef HAVE_REMOTE_LCD
191 Iconset_Remotescreen,
192 Iconset_Remotescreen_viewers,
193 #endif
196 static void load_icons(const char* filename, enum Iconset iconset)
198 int size_read;
199 bool *loaded_ok = NULL;
200 struct bitmap *bmp = NULL;
202 switch (iconset)
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_REMOTE];
217 bmp = &user_iconset[SCREEN_REMOTE];
218 bmp->data = icon_buffer[SCREEN_REMOTE];
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
228 *loaded_ok = false;
229 if (filename != NULL)
231 size_read = read_bmp_file((char*)filename, bmp, IMG_BUFSIZE,
232 FORMAT_NATIVE | FORMAT_DITHER);
233 if (size_read > 0)
235 *loaded_ok = true;
241 void icons_init(void)
243 char path[MAX_PATH];
244 if (global_settings.icon_file[0])
246 snprintf(path, MAX_PATH, "%s/%s.bmp",
247 ICON_DIR, global_settings.icon_file);
248 load_icons(path, Iconset_Mainscreen);
250 if (global_settings.viewers_icon_file[0])
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();
257 else
258 load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers);
259 #ifdef HAVE_REMOTE_LCD
260 if (global_settings.remote_icon_file[0])
262 snprintf(path, MAX_PATH, "%s/%s.bmp",
263 ICON_DIR, global_settings.remote_icon_file);
264 load_icons(path, Iconset_Remotescreen);
266 if (global_settings.remote_viewers_icon_file[0])
268 snprintf(path, MAX_PATH, "%s/%s.bmp",
269 ICON_DIR, global_settings.remote_viewers_icon_file);
270 load_icons(path, Iconset_Remotescreen_viewers);
272 else
273 load_icons(DEFAULT_REMOTE_VIEWER_BMP, Iconset_Remotescreen_viewers);
274 #endif
277 int get_icon_width(enum screen_type screen_type)
279 return ICON_WIDTH(screen_type);