RTL support in menus
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22945 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f06c98fec8
commit
6d80565b1b
11 changed files with 127 additions and 19 deletions
|
@ -40,6 +40,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "viewport.h"
|
#include "viewport.h"
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
#define ICON_PADDING 1
|
#define ICON_PADDING 1
|
||||||
|
|
||||||
|
@ -61,6 +62,9 @@ bool list_display_title(struct gui_synclist *list, enum screen_type screen);
|
||||||
| | | items | I - icons
|
| | | items | I - icons
|
||||||
| | | |
|
| | | |
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
Note: This image is flipped horizontally when the language is a
|
||||||
|
right-to-left one (Hebrew, Arabic)
|
||||||
*/
|
*/
|
||||||
static bool draw_title(struct screen *display, struct gui_synclist *list)
|
static bool draw_title(struct screen *display, struct gui_synclist *list)
|
||||||
{
|
{
|
||||||
|
@ -77,10 +81,17 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
|
||||||
struct viewport title_icon = title_text[screen];
|
struct viewport title_icon = title_text[screen];
|
||||||
title_icon.width = get_icon_width(screen)
|
title_icon.width = get_icon_width(screen)
|
||||||
+ ICON_PADDING*2;
|
+ ICON_PADDING*2;
|
||||||
title_icon.x += ICON_PADDING;
|
if (lang_is_rtl())
|
||||||
|
{
|
||||||
|
title_icon.x = title_text[screen].width - ICON_PADDING -
|
||||||
|
get_icon_width(screen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
title_icon.x = ICON_PADDING;
|
||||||
|
title_text[screen].x += title_icon.width;
|
||||||
|
}
|
||||||
title_text[screen].width -= title_icon.width;
|
title_text[screen].width -= title_icon.width;
|
||||||
title_text[screen].x += title_icon.width;
|
|
||||||
|
|
||||||
display->set_viewport(&title_icon);
|
display->set_viewport(&title_icon);
|
||||||
screen_put_icon(display, 0, 0, list->title_icon);
|
screen_put_icon(display, 0, 0, list->title_icon);
|
||||||
|
@ -108,7 +119,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
|
||||||
#ifdef HAVE_LCD_COLOR
|
#ifdef HAVE_LCD_COLOR
|
||||||
unsigned char cur_line = 0;
|
unsigned char cur_line = 0;
|
||||||
#endif
|
#endif
|
||||||
int item_offset;
|
int item_offset, is_rtl = lang_is_rtl();
|
||||||
bool show_title;
|
bool show_title;
|
||||||
line_height = font_get(parent->font)->height;
|
line_height = font_get(parent->font)->height;
|
||||||
display->set_viewport(parent);
|
display->set_viewport(parent);
|
||||||
|
@ -132,12 +143,12 @@ void list_draw(struct screen *display, struct gui_synclist *list)
|
||||||
vp = list_text[screen];
|
vp = list_text[screen];
|
||||||
vp.width = SCROLLBAR_WIDTH;
|
vp.width = SCROLLBAR_WIDTH;
|
||||||
list_text[screen].width -= SCROLLBAR_WIDTH;
|
list_text[screen].width -= SCROLLBAR_WIDTH;
|
||||||
if(global_settings.scrollbar == SCROLLBAR_LEFT)
|
if (global_settings.scrollbar == SCROLLBAR_SHOW)
|
||||||
list_text[screen].x += SCROLLBAR_WIDTH;
|
list_text[screen].x += SCROLLBAR_WIDTH;
|
||||||
vp.height = line_height *
|
vp.height = line_height *
|
||||||
viewport_get_nb_lines(&list_text[screen]);
|
viewport_get_nb_lines(&list_text[screen]);
|
||||||
vp.x = parent->x;
|
vp.x = parent->x;
|
||||||
if(global_settings.scrollbar == SCROLLBAR_RIGHT)
|
if (global_settings.scrollbar == SCROLLBAR_SHOW_OPPOSITE)
|
||||||
vp.x += list_text[screen].width;
|
vp.x += list_text[screen].width;
|
||||||
display->set_viewport(&vp);
|
display->set_viewport(&vp);
|
||||||
gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1,
|
gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1,
|
||||||
|
@ -149,7 +160,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
|
||||||
else if (show_title)
|
else if (show_title)
|
||||||
{
|
{
|
||||||
/* shift everything right a bit... */
|
/* shift everything right a bit... */
|
||||||
if(global_settings.scrollbar == SCROLLBAR_LEFT)
|
if (global_settings.scrollbar == SCROLLBAR_SHOW)
|
||||||
{
|
{
|
||||||
list_text[screen].width -= SCROLLBAR_WIDTH;
|
list_text[screen].width -= SCROLLBAR_WIDTH;
|
||||||
list_text[screen].x += SCROLLBAR_WIDTH;
|
list_text[screen].x += SCROLLBAR_WIDTH;
|
||||||
|
@ -167,8 +178,10 @@ void list_draw(struct screen *display, struct gui_synclist *list)
|
||||||
list_icons.width = icon_width * icon_count;
|
list_icons.width = icon_width * icon_count;
|
||||||
list_text[screen].width -=
|
list_text[screen].width -=
|
||||||
list_icons.width + ICON_PADDING;
|
list_icons.width + ICON_PADDING;
|
||||||
list_text[screen].x +=
|
if (is_rtl)
|
||||||
list_icons.width + ICON_PADDING;
|
list_icons.x += list_text[screen].width;
|
||||||
|
else
|
||||||
|
list_text[screen].x += list_icons.width + ICON_PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=start; i<end && i<list->nb_items; i++)
|
for (i=start; i<end && i<list->nb_items; i++)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "bmp.h"
|
#include "bmp.h"
|
||||||
#include "filetypes.h"
|
#include "filetypes.h"
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
#include "bitmaps/default_icons.h"
|
#include "bitmaps/default_icons.h"
|
||||||
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
|
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
|
||||||
|
@ -170,6 +171,8 @@ void screen_put_iconxy(struct screen * display,
|
||||||
#endif
|
#endif
|
||||||
draw_func = display->bitmap_part;
|
draw_func = display->bitmap_part;
|
||||||
|
|
||||||
|
if (lang_is_rtl())
|
||||||
|
xpos = display->getwidth() - xpos - width;
|
||||||
draw_func(data, 0, height * icon, stride, xpos, ypos, width, height);
|
draw_func(data, 0, height * icon, stride, xpos, ypos, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
# Arabic language file, translated by:
|
# Arabic language file, translated by:
|
||||||
# - Mohamed Tarek
|
# - Mohamed Tarek
|
||||||
# - Raafat Akkad
|
# - Raafat Akkad
|
||||||
|
<options>
|
||||||
|
rtl: 1
|
||||||
|
</options>
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW
|
id: LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW
|
||||||
desc: deprecated
|
desc: deprecated
|
||||||
|
|
|
@ -13075,3 +13075,54 @@
|
||||||
swcodec: "Release Time"
|
swcodec: "Release Time"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_HIDE
|
||||||
|
desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
|
||||||
|
user: core
|
||||||
|
<source>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Hide"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Hide"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Hide"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_SHOW
|
||||||
|
desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
|
||||||
|
user: core
|
||||||
|
<source>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
id: LANG_SHOW_OPPOSITE
|
||||||
|
desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
|
||||||
|
user: core
|
||||||
|
<source>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show Opposite"
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show Opposite"
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: none
|
||||||
|
lcd_bitmap: "Show Opposite"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
# - Rani Hod
|
# - Rani Hod
|
||||||
# - Tomer Shalev
|
# - Tomer Shalev
|
||||||
# - Sasha Khamkov
|
# - Sasha Khamkov
|
||||||
|
|
||||||
|
<options>
|
||||||
|
rtl: 1
|
||||||
|
</options>
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_SET_BOOL_YES
|
id: LANG_SET_BOOL_YES
|
||||||
desc: bool true representation
|
desc: bool true representation
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
/* These defines must match the initial bytes in the binary lang file */
|
/* These defines must match the initial bytes in the binary lang file */
|
||||||
/* See tools/genlang (TODO: Use common include for both) */
|
/* See tools/genlang (TODO: Use common include for both) */
|
||||||
#define LANGUAGE_COOKIE 0x1a
|
#define LANGUAGE_COOKIE 0x1a
|
||||||
#define LANGUAGE_VERSION 0x04
|
#define LANGUAGE_VERSION 0x05
|
||||||
|
#define LANGUAGE_FLAG_RTL 0x01
|
||||||
|
|
||||||
#define HEADER_SIZE 3
|
#define HEADER_SIZE 4
|
||||||
|
|
||||||
static unsigned char language_buffer[MAX_LANGUAGE_SIZE];
|
static unsigned char language_buffer[MAX_LANGUAGE_SIZE];
|
||||||
|
|
||||||
|
@ -51,6 +52,13 @@ void lang_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char lang_options = 0;
|
||||||
|
|
||||||
|
int lang_is_rtl(void)
|
||||||
|
{
|
||||||
|
return (lang_options & LANGUAGE_FLAG_RTL) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
int lang_load(const char *filename)
|
int lang_load(const char *filename)
|
||||||
{
|
{
|
||||||
int fsize;
|
int fsize;
|
||||||
|
@ -98,6 +106,7 @@ int lang_load(const char *filename)
|
||||||
retcode = 3;
|
retcode = 3;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
lang_options = (retcode ? 0 : lang_header[3]);
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,4 +30,6 @@ int lang_load(const char *filename);
|
||||||
/* get the ID of an english string so it can be localised */
|
/* get the ID of an english string so it can be localised */
|
||||||
int lang_english_to_id(const char* english);
|
int lang_english_to_id(const char* english);
|
||||||
|
|
||||||
|
/* returns whether the loaded language is a right-to-left language */
|
||||||
|
int lang_is_rtl(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -158,7 +158,7 @@ enum { REPLAYGAIN_TRACK = 0, REPLAYGAIN_ALBUM, REPLAYGAIN_SHUFFLE, REPLAYGAIN_OF
|
||||||
enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL };
|
enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL };
|
||||||
|
|
||||||
/* scrollbar visibility/position */
|
/* scrollbar visibility/position */
|
||||||
enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT };
|
enum { SCROLLBAR_HIDE = 0, SCROLLBAR_SHOW, SCROLLBAR_SHOW_OPPOSITE };
|
||||||
|
|
||||||
/* Alarm settings */
|
/* Alarm settings */
|
||||||
#ifdef HAVE_RTC_ALARM
|
#ifdef HAVE_RTC_ALARM
|
||||||
|
|
|
@ -641,8 +641,9 @@ const struct settings_list settings[] = {
|
||||||
ID2P(LANG_STATUSBAR_BOTTOM)),
|
ID2P(LANG_STATUSBAR_BOTTOM)),
|
||||||
#endif
|
#endif
|
||||||
CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, scrollbar,
|
CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, scrollbar,
|
||||||
LANG_SCROLL_BAR, SCROLLBAR_LEFT, "scrollbar","off,left,right",
|
LANG_SCROLL_BAR, SCROLLBAR_SHOW,
|
||||||
NULL, 3, ID2P(LANG_OFF), ID2P(LANG_LEFT), ID2P(LANG_RIGHT)),
|
"scrollbar","hide,show,show_opposite", NULL, 3,
|
||||||
|
ID2P(LANG_HIDE), ID2P(LANG_SHOW), ID2P(LANG_SHOW_OPPOSITE)),
|
||||||
INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
|
INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
|
||||||
"scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,
|
"scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,
|
||||||
NULL, NULL, NULL),
|
NULL, NULL, NULL),
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
#ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */
|
#ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */
|
||||||
#define LCDFN(fn) lcd_ ## fn
|
#define LCDFN(fn) lcd_ ## fn
|
||||||
|
@ -170,11 +171,16 @@ void LCDFN(puts_style_offset)(int x, int y, const unsigned char *str,
|
||||||
int style, int offset)
|
int style, int offset)
|
||||||
{
|
{
|
||||||
int xpos, ypos, w, h;
|
int xpos, ypos, w, h;
|
||||||
|
unsigned long chars_in_str;
|
||||||
LCDFN(scroll_stop_line)(current_vp, y);
|
LCDFN(scroll_stop_line)(current_vp, y);
|
||||||
if(!str || !str[0])
|
if(!str || !str[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
chars_in_str = utf8length((char *)str);
|
||||||
LCDFN(getstringsize)(str, &w, &h);
|
LCDFN(getstringsize)(str, &w, &h);
|
||||||
xpos = x * w / utf8length((char *)str);
|
xpos = x * w / chars_in_str;
|
||||||
|
if (lang_is_rtl())
|
||||||
|
xpos = current_vp->width - w - xpos;
|
||||||
ypos = y * h;
|
ypos = y * h;
|
||||||
LCDFN(putsxyofs_style)(xpos, ypos, str, style, w, h, offset);
|
LCDFN(putsxyofs_style)(xpos, ypos, str, style, w, h, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
# See apps/language.c (TODO: Use common include for both)
|
# See apps/language.c (TODO: Use common include for both)
|
||||||
# Cookie and binary version for the binary lang file
|
# Cookie and binary version for the binary lang file
|
||||||
my $LANGUAGE_COOKIE = 0x1a;
|
my $LANGUAGE_COOKIE = 0x1a;
|
||||||
my $LANGUAGE_VERSION = 0x04;
|
my $LANGUAGE_VERSION = 0x05;
|
||||||
|
my $LANGUAGE_FLAG_RTL = 0x01;
|
||||||
|
|
||||||
# A note for future users and readers: The original v1 language system allowed
|
# A note for future users and readers: The original v1 language system allowed
|
||||||
# the build to create and use a different language than english built-in. We
|
# the build to create and use a different language than english built-in. We
|
||||||
|
@ -167,6 +168,12 @@ sub phrase {
|
||||||
$phrase{$n}=$v;
|
$phrase{$n}=$v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my %options;
|
||||||
|
sub options {
|
||||||
|
my ($full, $n, $v)=@_;
|
||||||
|
$options{$n}=$v;
|
||||||
|
}
|
||||||
|
|
||||||
sub parsetarget {
|
sub parsetarget {
|
||||||
my ($debug, $strref, $full, $n, $v)=@_;
|
my ($debug, $strref, $full, $n, $v)=@_;
|
||||||
my $string;
|
my $string;
|
||||||
|
@ -381,6 +388,8 @@ my $voiceid=0x8000; # counter for voice-only ID numbers
|
||||||
open(LANG, "<$input") || die "Error: couldn't read language file named $input\n";
|
open(LANG, "<$input") || die "Error: couldn't read language file named $input\n";
|
||||||
my @phrase;
|
my @phrase;
|
||||||
my $header = 1;
|
my $header = 1;
|
||||||
|
my $langoptions = 0;
|
||||||
|
|
||||||
while(<LANG>) {
|
while(<LANG>) {
|
||||||
|
|
||||||
$line++;
|
$line++;
|
||||||
|
@ -510,9 +519,15 @@ while(<LANG>) {
|
||||||
print "### $idstr: The phrase is not used. Skipped\n";
|
print "### $idstr: The phrase is not used. Skipped\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
undef @phrase;
|
|
||||||
|
|
||||||
} # end of </phrase>
|
} # end of </phrase>
|
||||||
|
elsif($part eq "/options") {
|
||||||
|
# closing the options
|
||||||
|
if ($options{'rtl'}) {
|
||||||
|
$langoptions |= $LANGUAGE_FLAG_RTL;
|
||||||
|
}
|
||||||
|
} # end of </options>
|
||||||
|
|
||||||
|
undef @phrase;
|
||||||
|
|
||||||
# starts with a slash, this _ends_ this section
|
# starts with a slash, this _ends_ this section
|
||||||
$m = pop @m; # get back old value, the previous level's tag
|
$m = pop @m; # get back old value, the previous level's tag
|
||||||
|
@ -661,7 +676,8 @@ elsif($binary) {
|
||||||
|
|
||||||
open(OUTF, ">$binary") or die "Error: Can't create $binary";
|
open(OUTF, ">$binary") or die "Error: Can't create $binary";
|
||||||
binmode OUTF;
|
binmode OUTF;
|
||||||
printf OUTF ("%c%c%c", $LANGUAGE_COOKIE, $LANGUAGE_VERSION, $target_id); # magic lang file header
|
printf OUTF ("%c%c%c%c", $LANGUAGE_COOKIE, $LANGUAGE_VERSION, $target_id,
|
||||||
|
$langoptions); # magic lang file header
|
||||||
|
|
||||||
# loop over the target phrases
|
# loop over the target phrases
|
||||||
for $i (1 .. $idcount) {
|
for $i (1 .. $idcount) {
|
||||||
|
|
Loading…
Reference in a new issue