summaryrefslogtreecommitdiff
path: root/apps/gui/icon.c
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-04-16 09:14:36 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-04-16 09:14:36 +0000
commit6a5cc0bd25bd468c79e453fa49f353edd824141a (patch)
tree8b406e8390550ff8b87eae3214309867574657f0 /apps/gui/icon.c
parent7afe2e86931313653d4dedb6d5167c79c2822aba (diff)
downloadrockbox-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.c261
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) */
53static 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 */ 60static const int default_width[NB_SCREENS] = {
26void 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 */
68static 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)
77static unsigned char icon_buffer[IMG_BUFSIZE][NB_SCREENS];
78static bool custom_icons_loaded[NB_SCREENS] = {false};
79static struct bitmap user_iconset[NB_SCREENS];
80
81static unsigned char viewer_icon_buffer[IMG_BUFSIZE][NB_SCREENS];
82static bool viewer_icons_loaded[NB_SCREENS] = {false};
83static 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 */
96void 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
102void 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; 119typedef 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); 121void 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
49void screen_put_cursorxy(struct screen * display, int x, int y, bool on) 178void 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}
187enum Iconset {
188 Iconset_Mainscreen,
189 Iconset_Mainscreen_viewers,
190#ifdef HAVE_REMOTE_LCD
191 Iconset_Remotescreen,
192 Iconset_Remotescreen_viewers,
193#endif
194};
195
196static 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
241void 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
277int get_icon_width(enum screen_type screen_type)
278{
279 return ICON_WIDTH(screen_type);
280}