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 #ifdef HAVE_LCD_BITMAP
54 static bool tv_set_font(const unsigned char *font
)
56 unsigned char path
[MAX_PATH
];
58 if (font
!= NULL
&& *font
!= '\0')
60 rb
->snprintf(path
, MAX_PATH
, "%s/%s.fnt", FONT_DIR
, font
);
61 if (rb
->font_load(NULL
, path
) < 0)
63 rb
->splash(HZ
/2, "font load failed");
70 static bool tv_check_header_and_footer(struct tv_preferences
*new_prefs
)
72 bool change_prefs
= false;
74 if (rb
->global_settings
->statusbar
!= STATUSBAR_TOP
)
76 if (new_prefs
->header_mode
== HD_SBAR
)
78 new_prefs
->header_mode
= HD_NONE
;
81 else if (new_prefs
->header_mode
== HD_BOTH
)
83 new_prefs
->header_mode
= HD_PATH
;
87 if (rb
->global_settings
->statusbar
!= STATUSBAR_BOTTOM
)
89 if (new_prefs
->footer_mode
== FT_SBAR
)
91 new_prefs
->footer_mode
= FT_NONE
;
94 else if (new_prefs
->footer_mode
== FT_BOTH
)
96 new_prefs
->footer_mode
= FT_PAGE
;
104 static void tv_show_header(void)
106 unsigned header_mode
= header_mode
;
107 if (header_mode
== HD_SBAR
|| header_mode
== HD_BOTH
)
108 rb
->gui_syncstatusbar_draw(rb
->statusbars
, true);
110 if (header_mode
== HD_PATH
|| header_mode
== HD_BOTH
)
111 rb
->lcd_putsxy(0, header_height
- preferences
->font
->height
, preferences
->file_name
);
114 static void tv_show_footer(const struct tv_screen_pos
*pos
)
116 unsigned char buf
[12];
117 unsigned footer_mode
= preferences
->footer_mode
;
119 if (footer_mode
== FT_SBAR
|| footer_mode
== FT_BOTH
)
120 rb
->gui_syncstatusbar_draw(rb
->statusbars
, true);
122 if (footer_mode
== FT_PAGE
|| footer_mode
== FT_BOTH
)
125 rb
->snprintf(buf
, sizeof(buf
), "%d", pos
->page
+ 1);
127 rb
->snprintf(buf
, sizeof(buf
), "%d - %d", pos
->page
+ 1, pos
->page
+ 2);
129 rb
->lcd_putsxy(0, LCD_HEIGHT
- footer_height
, buf
);
133 static void tv_show_scrollbar(off_t cur_pos
, int size
)
141 sb_height
= LCD_HEIGHT
- header_height
- footer_height
;
142 if (preferences
->horizontal_scrollbar
)
144 items
= preferences
->windows
* window_columns
;
145 min_shown
= cur_window
* window_columns
+ cur_column
;
146 max_shown
= min_shown
+ window_columns
;
147 sb_width
= (need_vertical_scrollbar
)? TV_SCROLLBAR_WIDTH
: 0;
148 sb_height
-= TV_SCROLLBAR_HEIGHT
;
150 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
],
152 LCD_HEIGHT
- footer_height
- TV_SCROLLBAR_HEIGHT
,
153 LCD_WIDTH
- sb_width
, TV_SCROLLBAR_HEIGHT
,
154 items
, min_shown
, max_shown
, HORIZONTAL
);
157 if (need_vertical_scrollbar
)
159 items
= (int) tv_get_total_text_size();
160 min_shown
= (int) cur_pos
;
161 max_shown
= min_shown
+ size
;
163 rb
->gui_scrollbar_draw(rb
->screens
[SCREEN_MAIN
], 0, header_height
,
164 TV_SCROLLBAR_WIDTH
-1, sb_height
,
165 items
, min_shown
, max_shown
, VERTICAL
);
169 static int tv_calc_display_lines(void)
171 int scrollbar_height
= preferences
->horizontal_scrollbar
? TV_SCROLLBAR_HEIGHT
: 0;
172 unsigned header_mode
= preferences
->header_mode
;
173 unsigned footer_mode
= preferences
->footer_mode
;
175 header_height
= (header_mode
== HD_SBAR
|| header_mode
== HD_BOTH
)?
176 STATUSBAR_HEIGHT
: 0;
178 footer_height
= (footer_mode
== FT_SBAR
|| footer_mode
== FT_BOTH
)?
179 STATUSBAR_HEIGHT
: 0;
181 if (header_mode
== HD_NONE
|| header_mode
== HD_PATH
||
182 footer_mode
== FT_NONE
|| footer_mode
== FT_PAGE
)
183 rb
->gui_syncstatusbar_draw(rb
->statusbars
, false);
185 if (header_mode
== HD_PATH
|| header_mode
== HD_BOTH
)
186 header_height
+= preferences
->font
->height
;
188 if (footer_mode
== FT_PAGE
|| footer_mode
== FT_BOTH
)
189 footer_height
+= preferences
->font
->height
;
191 return (LCD_HEIGHT
- header_height
- footer_height
- scrollbar_height
) / preferences
->font
->height
;
195 static void tv_show_bookmarks(const struct tv_screen_pos
*top_pos
)
197 struct tv_screen_pos bookmarks
[TV_MAX_BOOKMARKS
];
198 int count
= tv_get_bookmark_positions(bookmarks
);
201 #ifdef HAVE_LCD_BITMAP
202 rb
->lcd_set_drawmode(DRMODE_COMPLEMENT
);
206 line
= (bookmarks
[count
].page
- top_pos
->page
) * display_lines
207 + (bookmarks
[count
].line
- top_pos
->line
);
208 if (line
>= 0 && line
< display_lines
)
210 #ifdef HAVE_LCD_BITMAP
211 rb
->lcd_fillrect(start_width
, header_height
+ line
* preferences
->font
->height
,
212 window_width
, preferences
->font
->height
);
214 rb
->lcd_putc(start_width
- 1, line
, TV_BOOKMARK_ICON
);
218 #ifdef HAVE_LCD_BITMAP
219 rb
->lcd_set_drawmode(DRMODE_SOLID
);
223 void tv_draw_window(void)
225 struct tv_screen_pos pos
;
226 const unsigned char *line_buf
;
228 int offset
= cur_column
* col_width
;
231 int draw_width
= (preferences
->windows
- cur_window
) * LCD_WIDTH
- offset
;
232 int dx
= start_width
- offset
;
234 tv_copy_screen_pos(&pos
);
235 rb
->lcd_clear_display();
237 if (preferences
->alignment
== AL_LEFT
)
238 tv_read_start(cur_window
, (cur_column
> 0));
240 tv_read_start(0, preferences
->windows
> 1);
242 for (line
= 0; line
< display_lines
; line
++)
244 if (!tv_get_next_line(&line_buf
))
247 if (preferences
->alignment
== AL_RIGHT
)
249 rb
->lcd_getstringsize(line_buf
, &line_width
, NULL
);
250 dx
= draw_width
- line_width
;
253 #ifdef HAVE_LCD_BITMAP
254 rb
->lcd_putsxy(dx
, header_height
+ line
* preferences
->font
->height
, line_buf
);
256 rb
->lcd_puts(dx
, line
, line_buf
);
260 size
= tv_read_end();
262 tv_show_bookmarks(&pos
);
264 #ifdef HAVE_LCD_BITMAP
265 tv_show_scrollbar(pos
.file_pos
, size
);
267 tv_show_footer(&pos
);
273 bool tv_traverse_lines(void)
278 tv_read_start(0, false);
279 for (i
= 0; i
< display_lines
; i
++)
281 if (!tv_get_next_line(NULL
))
291 static void tv_change_preferences(const struct tv_preferences
*oldp
)
293 #ifdef HAVE_LCD_BITMAP
294 static bool font_changing
= false;
295 const unsigned char *font_str
;
296 bool change_prefs
= false;
297 struct tv_preferences new_prefs
;
298 tv_copy_preferences(&new_prefs
);
300 font_str
= (oldp
&& !font_changing
)? oldp
->font_name
: rb
->global_settings
->font_file
;
303 if (font_changing
|| rb
->strcmp(font_str
, preferences
->font_name
))
305 font_changing
= true;
306 if (!tv_set_font(preferences
->font_name
))
308 rb
->strlcpy(new_prefs
.font_name
, font_str
, MAX_PATH
);
313 if (tv_check_header_and_footer(&new_prefs
) || change_prefs
)
315 tv_set_preferences(&new_prefs
);
319 font_changing
= false;
321 /* calculates display lines */
322 display_lines
= tv_calc_display_lines();
326 /* REAL fixed pitch :) all chars use up 1 cell */
330 #ifdef HAVE_LCD_BITMAP
331 col_width
= 2 * rb
->font_get_width(preferences
->font
, ' ');
336 if (cur_window
>= preferences
->windows
)
339 window_width
= LCD_WIDTH
;
340 #ifdef HAVE_LCD_BITMAP
341 need_vertical_scrollbar
= false;
344 tv_set_read_conditions(preferences
->windows
, window_width
);
345 if (tv_traverse_lines() && preferences
->vertical_scrollbar
)
347 need_vertical_scrollbar
= true;
348 start_width
= TV_SCROLLBAR_WIDTH
;
354 window_width
-= start_width
;
355 window_columns
= window_width
/ col_width
;
359 tv_set_read_conditions(preferences
->windows
, window_width
);
362 bool tv_init_window(unsigned char **buf
, size_t *size
)
364 tv_add_preferences_change_listner(tv_change_preferences
);
365 return tv_init_text_reader(buf
, size
);
368 void tv_finalize_window(void)
370 tv_finalize_text_reader();
372 #ifdef HAVE_LCD_BITMAP
374 if (rb
->strcmp(rb
->global_settings
->font_file
, preferences
->font_name
))
376 tv_set_font(rb
->global_settings
->font_file
);
381 void tv_move_window(int window_delta
, int column_delta
)
383 cur_window
+= window_delta
;
384 cur_column
+= column_delta
;
391 else if (cur_window
>= preferences
->windows
)
393 cur_window
= preferences
->windows
- 1;
404 cur_column
= window_columns
- 1;
409 if (cur_window
== preferences
->windows
- 1)
411 else if (cur_column
>= window_columns
)