rockbox/apps/gui/icon.c
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
later. We still need to hunt down snippets used that are not. 1324 modified
files...
http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
2008-06-28 18:10:04 +00:00

269 lines
8.3 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Jonathan Gordon
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "inttypes.h"
#include "config.h"
#include "icon.h"
#include "screen_access.h"
#include "icons.h"
#include "settings.h"
#include "bmp.h"
#include "filetypes.h"
#include <default_icons.h>
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
#include <remote_default_icons.h>
#endif
/* These are just the file names, the full path is snprint'ed when used */
#define DEFAULT_VIEWER_BMP "viewers"
#define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers"
/* These should probably be moved to config-<target>.h */
#define MAX_ICON_HEIGHT 24
#define MAX_ICON_WIDTH 24
/* We dont actually do anything with these pointers,
but they need to be grouped like this to save code
so storing them as void* is ok. (stops compile warning) */
static const void * inbuilt_icons[NB_SCREENS] = {
(void*)default_icons
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
, (void*)remote_default_icons
#endif
};
static const int default_width[NB_SCREENS] = {
BMPWIDTH_default_icons
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
, BMPWIDTH_remote_default_icons
#endif
};
/* height of whole file */
static const int default_height[NB_SCREENS] = {
BMPHEIGHT_default_icons
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
, BMPHEIGHT_remote_default_icons
#endif
};
#define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \
Icon_Last_Themeable *LCD_DEPTH/8)
static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE];
static bool custom_icons_loaded[NB_SCREENS] = {false};
static struct bitmap user_iconset[NB_SCREENS];
static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE];
static bool viewer_icons_loaded[NB_SCREENS] = {false};
static struct bitmap viewer_iconset[NB_SCREENS];
#define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \
default_height[screen] : \
user_iconset[screen].height) \
/ Icon_Last_Themeable
#define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \
default_width[screen] : \
user_iconset[screen].width)
/* x,y in letters, not pixles */
void screen_put_icon(struct screen * display,
int x, int y, enum themable_icons icon)
{
screen_put_icon_with_offset(display, x, y, 0, 0, icon);
}
void screen_put_icon_with_offset(struct screen * display,
int x, int y, int off_x, int off_y,
enum themable_icons icon)
{
int xpos, ypos;
int width, height;
int screen = display->screen_type;
display->getstringsize((unsigned char *)"M", &width, &height);
xpos = x*ICON_WIDTH(screen) + off_x;
ypos = y*height + off_y;
if ( height > ICON_HEIGHT(screen) )/* center the cursor */
ypos += (height - ICON_HEIGHT(screen)) / 2;
screen_put_iconxy(display, xpos, ypos, icon);
}
/* x,y in pixels */
void screen_put_iconxy(struct screen * display,
int xpos, int ypos, enum themable_icons icon)
{
const void *data;
int screen = display->screen_type;
int width = ICON_WIDTH(screen);
int height = ICON_HEIGHT(screen);
screen_bitmap_part_func *draw_func = NULL;
if (icon == Icon_NOICON)
{
screen_clear_area(display, xpos, ypos, width, height);
return;
}
else if (icon >= Icon_Last_Themeable)
{
icon -= Icon_Last_Themeable;
if (!viewer_icons_loaded[screen] ||
(global_status.viewer_icon_count*height
> viewer_iconset[screen].height) ||
(icon * height > viewer_iconset[screen].height))
{
screen_put_iconxy(display, xpos, ypos, Icon_Questionmark);
return;
}
data = viewer_iconset[screen].data;
}
else if (custom_icons_loaded[screen])
{
data = user_iconset[screen].data;
}
else
{
data = inbuilt_icons[screen];
}
/* add some left padding to the icons if they are on the edge */
if (xpos == 0)
xpos++;
#if (LCD_DEPTH == 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH == 16)
if (display->depth == 16)
draw_func = display->transparent_bitmap_part;
else
#endif
draw_func = display->bitmap_part;
draw_func(data, 0, height * icon, width, xpos, ypos, width, height);
}
void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
{
#ifdef HAVE_LCD_BITMAP
screen_put_icon(display, x, y, on?Icon_Cursor:0);
#else
screen_put_icon(display, x, y, on?CURSOR_CHAR:-1);
#endif
}
enum Iconset {
Iconset_Mainscreen,
Iconset_Mainscreen_viewers,
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
Iconset_Remotescreen,
Iconset_Remotescreen_viewers,
#endif
};
static void load_icons(const char* filename, enum Iconset iconset,
bool allow_disable)
{
int size_read;
bool *loaded_ok = NULL;
struct bitmap *bmp = NULL;
int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER);
switch (iconset)
{
case Iconset_Mainscreen:
loaded_ok = &custom_icons_loaded[SCREEN_MAIN];
bmp = &user_iconset[SCREEN_MAIN];
bmp->data = icon_buffer[SCREEN_MAIN];
break;
case Iconset_Mainscreen_viewers:
loaded_ok = &viewer_icons_loaded[SCREEN_MAIN];
bmp = &viewer_iconset[SCREEN_MAIN];
bmp->data = viewer_icon_buffer[SCREEN_MAIN];
break;
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
case Iconset_Remotescreen:
loaded_ok = &custom_icons_loaded[SCREEN_REMOTE];
bmp = &user_iconset[SCREEN_REMOTE];
bmp->data = icon_buffer[SCREEN_REMOTE];
bmpformat |= FORMAT_REMOTE;
break;
case Iconset_Remotescreen_viewers:
loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE];
bmp = &viewer_iconset[SCREEN_REMOTE];
bmp->data = viewer_icon_buffer[SCREEN_REMOTE];
bmpformat |= FORMAT_REMOTE;
break;
#endif
}
*loaded_ok = false;
if (!allow_disable || (filename[0] && filename[0] != '-'))
{
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename);
size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat);
if (size_read > 0)
{
*loaded_ok = true;
}
}
}
void icons_init(void)
{
load_icons(global_settings.icon_file, Iconset_Mainscreen, true);
if (*global_settings.viewers_icon_file)
{
load_icons(global_settings.viewers_icon_file,
Iconset_Mainscreen_viewers, true);
read_viewer_theme_file();
}
else
{
load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers, false);
}
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
load_icons(global_settings.remote_icon_file,
Iconset_Remotescreen, true);
if (*global_settings.remote_viewers_icon_file)
{
load_icons(global_settings.remote_viewers_icon_file,
Iconset_Remotescreen_viewers, true);
}
else
{
load_icons(DEFAULT_REMOTE_VIEWER_BMP,
Iconset_Remotescreen_viewers, false);
}
#endif
}
int get_icon_width(enum screen_type screen_type)
{
return ICON_WIDTH(screen_type);
}