1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Gilles Roux
12 * 2010 Yoshihisa Uchida
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
24 #include "tv_bookmark.h"
25 #include "tv_preferences.h"
26 #include "tv_screen_pos.h"
27 #include "tv_text_reader.h"
28 #include "tv_window.h"
30 #define TV_SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
31 #define TV_SCROLLBAR_HEIGHT 4
33 #ifndef HAVE_LCD_BITMAP
34 #define TV_BOOKMARK_ICON 0xe101
37 #ifdef HAVE_LCD_BITMAP
38 static int header_height
;
39 static int footer_height
;
40 static bool need_vertical_scrollbar
= false;
43 static int start_width
;
44 static int display_lines
;
46 static int window_width
;
47 static int window_columns
;
50 static int cur_window
;
51 static int cur_column
;
53 static const struct tv_preferences
*prefs
= NULL
;
55 #ifdef HAVE_LCD_BITMAP
56 static bool tv_set_font(const unsigned char *font
)
58 unsigned char path
[MAX_PATH
];
60 if (font
!= NULL
&& *font
!= '\0')
62 rb
->snprintf(path
, MAX_PATH
, "%s/%s.fnt", FONT_DIR
, font
);
63 if (rb
->font_load(NULL
, path
) < 0)
65 rb
->splash(HZ
/2, "font load failed");
72 static void tv_check_header_and_footer(void)
74 struct tv_preferences new_prefs
;
76 tv_copy_preferences(&new_prefs
);
78 if (rb
->global_settings
->statusbar
!= STATUSBAR_TOP
)
80 if (new_prefs
.header_mode
== HD_SBAR
)
81 new_prefs
.header_mode
= HD_NONE
;
82 else if (new_prefs
.header_mode
== HD_BOTH
)
83 new_prefs
.header_mode
= HD_PATH
;
85 if (rb
->global_settings
->statusbar
!= STATUSBAR_BOTTOM
)
87 if (new_prefs
.footer_mode
== FT_SBAR
)
88 new_prefs
.footer_mode
= FT_NONE
;
89 else if (new_prefs
.footer_mode
== FT_BOTH
)
90 new_prefs
.footer_mode
= FT_PAGE
;
92 tv_set_preferences(&new_prefs
);
95 static void tv_show_header(void)
97 if (prefs
->header_mode
== HD_SBAR
|| prefs
->header_mode
== HD_BOTH
)
98 rb
->gui_syncstatusbar_draw(rb
->statusbars
, true);
100 if (prefs
->header_mode
== HD_PATH
|| prefs
->header_mode
== HD_BOTH
)
101 rb
->lcd_putsxy(0, header_height
- prefs
->font
->height
, prefs
->file_name
);
104 static void tv_show_footer(const struct tv_screen_pos
*pos
)
106 unsigned char buf
[12];
108 if (prefs
->footer_mode
== FT_SBAR
|| prefs
->footer_mode
== FT_BOTH
)
109 rb
->gui_syncstatusbar_draw(rb
->statusbars
, true);
111 if (prefs
->footer_mode
== FT_PAGE
|| prefs
->footer_mode
== FT_BOTH
)
114 rb
->snprintf(buf
, sizeof(buf
), "%d", pos
->page
+ 1);
116 rb
->snprintf(buf
, sizeof(buf
), "%d - %d", pos
->page
+ 1, pos
->page
+ 2);
118 rb
->lcd_putsxy(0, LCD_HEIGHT
- footer_height
, buf
);
122 static void tv_show_scrollbar(off_t cur_pos
, int size
)
130 sb_height
= LCD_HEIGHT
- header_height
- footer_height
;
131 if (prefs
->horizontal_scrollbar
)
133 items
= prefs
->windows
* window_columns
;
134 min_shown
= cur_window
* window_columns
+ cur_column
;
135 max_shown
= min_shown
+ window_columns
;
136 sb_width
= (need_vertical_scrollbar
)? TV_SCROLLBAR_WIDTH
: 0;
137 sb_height
-= TV_SCROLLBAR_HEIGHT
;
139 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],
141 LCD_HEIGHT
- footer_height
- TV_SCROLLBAR_HEIGHT
,
142 LCD_WIDTH
- sb_width
, TV_SCROLLBAR_HEIGHT
,
143 items
, min_shown
, max_shown
, HORIZONTAL
);
146 if (need_vertical_scrollbar
)
148 items
= (int) tv_get_total_text_size();
149 min_shown
= (int) cur_pos
;
150 max_shown
= min_shown
+ size
;
152 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
], 0, header_height
,
153 TV_SCROLLBAR_WIDTH
-1, sb_height
,
154 items
, min_shown
, max_shown
, VERTICAL
);
158 static int tv_calc_display_lines(void)
160 int scrollbar_height
= (prefs
->horizontal_scrollbar
)? TV_SCROLLBAR_HEIGHT
: 0;
162 header_height
= (prefs
->header_mode
== HD_SBAR
|| prefs
->header_mode
== HD_BOTH
)?
163 STATUSBAR_HEIGHT
: 0;
165 footer_height
= (prefs
->footer_mode
== FT_SBAR
|| prefs
->footer_mode
== FT_BOTH
)?
166 STATUSBAR_HEIGHT
: 0;
168 if (prefs
->header_mode
== HD_NONE
|| prefs
->header_mode
== HD_PATH
||
169 prefs
->footer_mode
== FT_NONE
|| prefs
->footer_mode
== FT_PAGE
)
170 rb
->gui_syncstatusbar_draw(rb
->statusbars
, false);
172 if (prefs
->header_mode
== HD_PATH
|| prefs
->header_mode
== HD_BOTH
)
173 header_height
+= prefs
->font
->height
;
175 if (prefs
->footer_mode
== FT_PAGE
|| prefs
->footer_mode
== FT_BOTH
)
176 footer_height
+= prefs
->font
->height
;
178 return (LCD_HEIGHT
- header_height
- footer_height
- scrollbar_height
) / prefs
->font
->height
;
182 static void tv_show_bookmarks(const struct tv_screen_pos
*top_pos
)
184 struct tv_screen_pos bookmarks
[TV_MAX_BOOKMARKS
];
185 int count
= tv_get_bookmark_positions(bookmarks
);
188 #ifdef HAVE_LCD_BITMAP
189 rb
->lcd_set_drawmode(DRMODE_COMPLEMENT
);
193 line
= (bookmarks
[count
].page
- top_pos
->page
) * display_lines
194 + (bookmarks
[count
].line
- top_pos
->line
);
195 if (line
>= 0 && line
< display_lines
)
197 #ifdef HAVE_LCD_BITMAP
198 rb
->lcd_fillrect(start_width
, header_height
+ line
* prefs
->font
->height
,
199 window_width
, prefs
->font
->height
);
201 rb
->lcd_putc(start_width
- 1, line
, TV_BOOKMARK_ICON
);
205 #ifdef HAVE_LCD_BITMAP
206 rb
->lcd_set_drawmode(DRMODE_SOLID
);
210 void tv_draw_window(void)
212 struct tv_screen_pos pos
;
213 const unsigned char *line_buf
;
215 int offset
= cur_column
* col_width
;
218 int draw_width
= (prefs
->windows
- cur_window
) * LCD_WIDTH
- offset
;
219 int dx
= start_width
- offset
;
221 tv_copy_screen_pos(&pos
);
222 rb
->lcd_clear_display();
224 if (prefs
->alignment
== LEFT
)
225 tv_read_start(cur_window
, (cur_column
> 0));
227 tv_read_start(0, prefs
->windows
> 1);
229 for (line
= 0; line
< display_lines
; line
++)
231 if (!tv_get_next_line(&line_buf
))
234 if (prefs
->alignment
== RIGHT
)
236 rb
->lcd_getstringsize(line_buf
, &line_width
, NULL
);
237 dx
= draw_width
- line_width
;
240 #ifdef HAVE_LCD_BITMAP
241 rb
->lcd_putsxy(dx
, header_height
+ line
* prefs
->font
->height
, line_buf
);
243 rb
->lcd_puts(dx
, line
, line_buf
);
247 size
= tv_read_end();
249 tv_show_bookmarks(&pos
);
251 #ifdef HAVE_LCD_BITMAP
252 tv_show_scrollbar(pos
.file_pos
, size
);
254 tv_show_footer(&pos
);
260 bool tv_traverse_lines(void)
265 tv_read_start(0, false);
266 for (i
= 0; i
< display_lines
; i
++)
268 if (!tv_get_next_line(NULL
))
278 static void tv_change_preferences(const struct tv_preferences
*oldp
)
280 #ifdef HAVE_LCD_BITMAP
281 static bool font_changing
= false;
282 const unsigned char *font_str
;
284 font_str
= (oldp
&& !font_changing
)? oldp
->font_name
: rb
->global_settings
->font_file
;
285 font_changing
= true;
288 if (rb
->strcmp(font_str
, prefs
->font_name
))
290 if (!tv_set_font(prefs
->font_name
))
292 struct tv_preferences new_prefs
= *prefs
;
294 rb
->strlcpy(new_prefs
.font_name
, font_str
, MAX_PATH
);
295 tv_set_preferences(&new_prefs
);
298 else if (!oldp
|| font_changing
)
299 tv_set_font(font_str
);
301 /* calculates display lines */
302 tv_check_header_and_footer();
303 display_lines
= tv_calc_display_lines();
305 /* if font_changing == false, the remaining processes need not be executed. */
309 font_changing
= false;
313 /* REAL fixed pitch :) all chars use up 1 cell */
317 #ifdef HAVE_LCD_BITMAP
318 col_width
= 2 * rb
->font_get_width(prefs
->font
, ' ');
323 if (cur_window
>= prefs
->windows
)
326 window_width
= LCD_WIDTH
;
327 #ifdef HAVE_LCD_BITMAP
328 need_vertical_scrollbar
= false;
331 tv_set_read_conditions(prefs
->windows
, window_width
);
332 if (tv_traverse_lines() && prefs
->vertical_scrollbar
)
334 need_vertical_scrollbar
= true;
335 start_width
= TV_SCROLLBAR_WIDTH
;
341 window_width
-= start_width
;
342 window_columns
= window_width
/ col_width
;
346 tv_set_read_conditions(prefs
->windows
, window_width
);
349 bool tv_init_window(unsigned char *buf
, size_t bufsize
, size_t *used_size
)
351 tv_add_preferences_change_listner(tv_change_preferences
);
352 if (!tv_init_text_reader(buf
, bufsize
, used_size
))
355 prefs
= tv_get_preferences();
359 void tv_finalize_window(void)
361 tv_finalize_text_reader();
363 #ifdef HAVE_LCD_BITMAP
365 if (rb
->strcmp(rb
->global_settings
->font_file
, prefs
->font_name
))
367 tv_set_font(rb
->global_settings
->font_file
);
372 void tv_move_window(int window_delta
, int column_delta
)
374 cur_window
+= window_delta
;
375 cur_column
+= column_delta
;
382 else if (cur_window
>= prefs
->windows
)
384 cur_window
= prefs
->windows
- 1;
395 cur_column
= window_columns
- 1;
400 if (cur_window
== prefs
->windows
- 1)
402 else if (cur_column
>= window_columns
)