quiet the masses...
[Rockbox.git] / apps / gui / icon.c
blob968d83548f7c1909e86040100652964f93d026b8
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 #include <default_icons.h>
32 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
33 #include <remote_default_icons.h>
34 #endif
36 /* These are just the file names, the full path is snprint'ed when used */
37 #define DEFAULT_VIEWER_BMP "viewers"
38 #define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers"
40 /* These should probably be moved to config-<target>.h */
41 #define MAX_ICON_HEIGHT 24
42 #define MAX_ICON_WIDTH 24
45 /* We dont actually do anything with these pointers,
46 but they need to be grouped like this to save code
47 so storing them as void* is ok. (stops compile warning) */
48 static const void * inbuilt_icons[NB_SCREENS] = {
49 (void*)default_icons
50 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
51 , (void*)remote_default_icons
52 #endif
55 static const int default_width[NB_SCREENS] = {
56 BMPWIDTH_default_icons
57 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
58 , BMPWIDTH_remote_default_icons
59 #endif
62 /* height of whole file */
63 static const int default_height[NB_SCREENS] = {
64 BMPHEIGHT_default_icons
65 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
66 , BMPHEIGHT_remote_default_icons
67 #endif
70 #define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \
71 Icon_Last_Themeable *LCD_DEPTH/8)
72 static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE];
73 static bool custom_icons_loaded[NB_SCREENS] = {false};
74 static struct bitmap user_iconset[NB_SCREENS];
76 static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE];
77 static bool viewer_icons_loaded[NB_SCREENS] = {false};
78 static struct bitmap viewer_iconset[NB_SCREENS];
81 #define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \
82 default_height[screen] : \
83 user_iconset[screen].height) \
84 / Icon_Last_Themeable
86 #define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \
87 default_width[screen] : \
88 user_iconset[screen].width)
90 /* x,y in letters, not pixles */
91 void screen_put_icon(struct screen * display,
92 int x, int y, enum themable_icons icon)
94 screen_put_icon_with_offset(display, x, y, 0, 0, icon);
97 void screen_put_icon_with_offset(struct screen * display,
98 int x, int y, int off_x, int off_y,
99 enum themable_icons icon)
101 int xpos, ypos;
102 int width, height;
103 int screen = display->screen_type;
104 display->getstringsize((unsigned char *)"M", &width, &height);
105 xpos = x*ICON_WIDTH(screen) + off_x;
106 ypos = y*height + display->getymargin() + off_y;
108 if ( height > ICON_HEIGHT(screen) )/* center the cursor */
109 ypos += (height - ICON_HEIGHT(screen)) / 2;
110 screen_put_iconxy(display, xpos, ypos, icon);
113 /* x,y in pixels */
114 void screen_put_iconxy(struct screen * display,
115 int xpos, int ypos, enum themable_icons icon)
117 const void *data;
118 int screen = display->screen_type;
119 int width = ICON_WIDTH(screen);
120 int height = ICON_HEIGHT(screen);
121 screen_bitmap_part_func *draw_func = NULL;
123 if (icon == Icon_NOICON)
125 screen_clear_area(display, xpos, ypos, width, height);
126 return;
128 else if (icon >= Icon_Last_Themeable)
130 icon -= Icon_Last_Themeable;
131 if (!viewer_icons_loaded[screen] ||
132 (global_status.viewer_icon_count*height
133 > viewer_iconset[screen].height) ||
134 (icon * height > viewer_iconset[screen].height))
136 screen_put_iconxy(display, xpos, ypos, Icon_Questionmark);
137 return;
139 data = viewer_iconset[screen].data;
141 else if (custom_icons_loaded[screen])
143 data = user_iconset[screen].data;
145 else
147 data = inbuilt_icons[screen];
149 /* add some left padding to the icons if they are on the edge */
150 if (xpos == 0)
151 xpos++;
153 #if (LCD_DEPTH == 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH == 16)
154 if (display->depth == 16)
155 draw_func = display->transparent_bitmap_part;
156 else
157 #endif
158 draw_func = display->bitmap_part;
160 draw_func(data, 0, height * icon, width, xpos, ypos, width, height);
163 void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
165 #ifdef HAVE_LCD_BITMAP
166 screen_put_icon(display, x, y, on?Icon_Cursor:0);
167 #else
168 screen_put_icon(display, x, y, on?CURSOR_CHAR:-1);
169 #endif
172 enum Iconset {
173 Iconset_Mainscreen,
174 Iconset_Mainscreen_viewers,
175 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
176 Iconset_Remotescreen,
177 Iconset_Remotescreen_viewers,
178 #endif
181 static void load_icons(const char* filename, enum Iconset iconset,
182 bool allow_disable)
184 int size_read;
185 bool *loaded_ok = NULL;
186 struct bitmap *bmp = NULL;
187 int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER);
189 switch (iconset)
191 case Iconset_Mainscreen:
192 loaded_ok = &custom_icons_loaded[SCREEN_MAIN];
193 bmp = &user_iconset[SCREEN_MAIN];
194 bmp->data = icon_buffer[SCREEN_MAIN];
195 break;
196 case Iconset_Mainscreen_viewers:
197 loaded_ok = &viewer_icons_loaded[SCREEN_MAIN];
198 bmp = &viewer_iconset[SCREEN_MAIN];
199 bmp->data = viewer_icon_buffer[SCREEN_MAIN];
200 break;
201 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
202 case Iconset_Remotescreen:
203 loaded_ok = &custom_icons_loaded[SCREEN_REMOTE];
204 bmp = &user_iconset[SCREEN_REMOTE];
205 bmp->data = icon_buffer[SCREEN_REMOTE];
206 bmpformat |= FORMAT_REMOTE;
207 break;
208 case Iconset_Remotescreen_viewers:
209 loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE];
210 bmp = &viewer_iconset[SCREEN_REMOTE];
211 bmp->data = viewer_icon_buffer[SCREEN_REMOTE];
212 bmpformat |= FORMAT_REMOTE;
213 break;
214 #endif
217 *loaded_ok = false;
218 if (!allow_disable || (filename[0] && filename[0] != '-'))
220 char path[MAX_PATH];
222 snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename);
223 size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat);
224 if (size_read > 0)
226 *loaded_ok = true;
232 void icons_init(void)
234 load_icons(global_settings.icon_file, Iconset_Mainscreen, true);
236 if (*global_settings.viewers_icon_file)
238 load_icons(global_settings.viewers_icon_file,
239 Iconset_Mainscreen_viewers, true);
240 read_viewer_theme_file();
242 else
244 load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers, false);
247 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
248 load_icons(global_settings.remote_icon_file,
249 Iconset_Remotescreen, true);
251 if (*global_settings.remote_viewers_icon_file)
253 load_icons(global_settings.remote_viewers_icon_file,
254 Iconset_Remotescreen_viewers, true);
256 else
258 load_icons(DEFAULT_REMOTE_VIEWER_BMP,
259 Iconset_Remotescreen_viewers, false);
261 #endif
264 int get_icon_width(enum screen_type screen_type)
266 return ICON_WIDTH(screen_type);