text viewer: tv_window doesn't depend on the layout of the text viewer.
[kugel-rb.git] / apps / plugins / text_viewer / tv_display.c
blob59b4bdf437e29162649ac1a447d53b7d97a9c705
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Yoshihisa Uchida
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "tv_display.h"
22 #include "tv_preferences.h"
25 * display layout
27 * when is defined HAVE_LCD_BITMAP
28 * +-------------------------+
29 * |statusbar (1) |
30 * +-------------------------+
31 * |filename (2) |
32 * +---+---------------------+
33 * |s | |
34 * |c | |
35 * |r | draw area |
36 * |o | |
37 * |l | |
38 * |l | |
39 * |b | |
40 * |a | |
41 * |r | |
42 * |(3)| |
43 * +---+---------------------+
44 * | |scrollbar (4) |
45 * +---+---------------------+
46 * |page (5) |
47 * +-------------------------+
48 * |statusbar (6) |
49 * +-------------------------+
51 * (1) displays when rb->global_settings->statusbar == STATUSBAR_TOP.
52 * (2) displays when preferences->header_mode is HD_PATH.
53 * (3) displays when preferences->vertical_scrollbar is SB_ON.
54 * (4) displays when preferences->horizontal_scrollbar is SB_ON.
55 * (5) displays when preferences->footer_mode is FT_PAGE.
56 * (6) displays when rb->global_settings->statusbar == STATUSBAR_BOTTOM.
59 * when isn't defined HAVE_LCD_BITMAP
60 * +---+---------------------+
61 * | | |
62 * |(7)| draw area |
63 * | | |
64 * +---+---------------------+
65 * (7) bookmark
68 #define TV_SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
69 #define TV_SCROLLBAR_HEIGHT 4
71 #ifndef HAVE_LCD_BITMAP
72 #define TV_BOOKMARK_ICON 0xe101
73 #endif
75 struct tv_rect {
76 int x;
77 int y;
78 int w;
79 int h;
82 static struct viewport vp_info;
83 static bool is_initialized_vp = false;
85 static struct screen* display;
87 #ifdef HAVE_LCD_BITMAP
88 static int drawmode = DRMODE_SOLID;
89 #endif
91 /* layout */
92 #ifdef HAVE_LCD_BITMAP
93 static struct tv_rect header;
94 static struct tv_rect footer;
95 static struct tv_rect horizontal_scrollbar;
96 static struct tv_rect vertical_scrollbar;
97 #else
98 static struct tv_rect bookmark;
99 #endif
100 static struct tv_rect drawarea;
102 static bool show_vertical_scrollbar;
104 static int display_columns;
105 static int display_rows;
107 static int col_width = 1;
108 static int row_height = 1;
110 static int totalsize;
112 #ifdef HAVE_LCD_BITMAP
114 static void tv_show_header(void)
116 unsigned header_mode = header_mode;
118 if (preferences->header_mode == HD_PATH)
119 display->putsxy(header.x, header.y, preferences->file_name);
122 static void tv_show_footer(const struct tv_screen_pos *pos)
124 unsigned char buf[12];
125 unsigned footer_mode = preferences->footer_mode;
127 if (footer_mode == FT_PAGE)
129 if (pos->line == 0)
130 rb->snprintf(buf, sizeof(buf), "%d", pos->page + 1);
131 else
132 rb->snprintf(buf, sizeof(buf), "%d - %d", pos->page + 1, pos->page + 2);
133 display->putsxy(footer.x, footer.y + 1, buf);
137 static void tv_show_scrollbar(int window, int col, off_t cur_pos, int size)
139 int items;
140 int min_shown;
141 int max_shown;
143 if (preferences->horizontal_scrollbar)
145 items = preferences->windows * display_columns;
146 min_shown = window * display_columns + col;
147 max_shown = min_shown + display_columns;
149 rb->gui_scrollbar_draw(display,
150 horizontal_scrollbar.x, horizontal_scrollbar.y + 1,
151 horizontal_scrollbar.w, TV_SCROLLBAR_HEIGHT,
152 items, min_shown, max_shown, HORIZONTAL);
155 if (show_vertical_scrollbar)
157 items = (int) totalsize;
158 min_shown = (int) cur_pos;
159 max_shown = min_shown + size;
161 rb->gui_scrollbar_draw(display,
162 vertical_scrollbar.x, vertical_scrollbar.y,
163 TV_SCROLLBAR_WIDTH, vertical_scrollbar.h,
164 items, min_shown, max_shown, VERTICAL);
168 #endif
170 void tv_init_scrollbar(off_t total, bool show_scrollbar)
172 totalsize = total;
173 show_vertical_scrollbar = show_scrollbar;
176 void tv_show_bookmarks(const int *rows, int count)
178 #ifdef HAVE_LCD_BITMAP
179 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
180 #endif
182 while (count--)
184 #ifdef HAVE_LCD_BITMAP
185 display->fillrect(drawarea.x, drawarea.y + rows[count] * row_height,
186 drawarea.w, row_height);
187 #else
188 display->putchar(bookmark.x, drawarea.y + rows[count], TV_BOOKMARK_ICON);
189 #endif
193 void tv_update_extra(int window, int col, const struct tv_screen_pos *pos, int size)
195 #ifdef HAVE_LCD_BITMAP
196 tv_show_scrollbar(window, col, pos->file_pos, size);
197 tv_show_header();
198 tv_show_footer(pos);
199 #else
200 (void)window;
201 (void)col;
202 (void)pos;
203 (void)size;
204 #endif
207 void tv_draw_text(int row, const unsigned char *text, int offset)
209 int xpos = -offset * col_width;
210 int text_width;
212 if (row < 0 || row >= display_rows)
213 return;
215 if (preferences->alignment == AL_RIGHT)
217 display->getstringsize(text, &text_width, NULL);
218 xpos += ((offset > 0)? drawarea.w * 2 : drawarea.w) - text_width;
221 #ifdef HAVE_LCD_BITMAP
222 display->putsxy(drawarea.x + xpos, drawarea.y + row * row_height, text);
223 #else
224 display->puts(drawarea.x + xpos, drawarea.y + row, text);
225 #endif
228 void tv_start_display(void)
230 display->set_viewport(&vp_info);
231 #ifdef HAVE_LCD_BITMAP
232 drawmode = rb->lcd_get_drawmode();
233 rb->lcd_set_drawmode(DRMODE_SOLID);
234 #endif
236 #if LCD_DEPTH > 1
237 rb->lcd_set_backdrop(NULL);
238 #endif
239 display->clear_viewport();
242 void tv_end_display(void)
244 display->update_viewport();
246 #ifdef HAVE_LCD_BITMAP
247 rb->lcd_set_drawmode(drawmode);
248 #endif
250 display->set_viewport(NULL);
253 void tv_set_layout(bool show_scrollbar)
255 #ifdef HAVE_LCD_BITMAP
256 int scrollbar_width = (show_scrollbar)? TV_SCROLLBAR_WIDTH + 1 : 0;
257 int scrollbar_height = (preferences->horizontal_scrollbar)? TV_SCROLLBAR_HEIGHT + 1 : 0;
259 row_height = preferences->font->height;
261 header.x = 0;
262 header.y = 1;
263 header.w = vp_info.width;
264 header.h = (preferences->header_mode == HD_PATH)? row_height + 1 : 0;
266 footer.x = 0;
267 footer.w = vp_info.width;
268 footer.h = (preferences->footer_mode == FT_PAGE)? row_height + 1 : 0;
269 footer.y = vp_info.height - 1 - footer.h;
271 drawarea.x = scrollbar_width;
272 drawarea.y = header.y + header.h;
273 drawarea.w = vp_info.width - scrollbar_width;
274 drawarea.h = footer.y - drawarea.y - scrollbar_height;
276 horizontal_scrollbar.x = drawarea.x;
277 horizontal_scrollbar.y = footer.y - scrollbar_height;
278 horizontal_scrollbar.w = drawarea.w;
279 horizontal_scrollbar.h = scrollbar_height;
281 vertical_scrollbar.x = 0;
282 vertical_scrollbar.y = drawarea.y;
283 vertical_scrollbar.w = scrollbar_width;
284 vertical_scrollbar.h = drawarea.h;
285 #else
286 (void) show_scrollbar;
288 row_height = 1;
290 bookmark.x = 0;
291 bookmark.y = 0;
292 bookmark.w = 1;
293 bookmark.h = vp_info.height;
295 drawarea.x = 1;
296 drawarea.y = 0;
297 drawarea.w = vp_info.width - 1;
298 drawarea.h = vp_info.height;
299 #endif
301 display_columns = drawarea.w / col_width;
302 display_rows = drawarea.h / row_height;
305 void tv_get_drawarea_info(int *width, int *cols, int *rows)
307 *width = drawarea.w;
308 *cols = display_columns;
309 *rows = display_rows;
312 static void tv_change_viewport(void)
314 #ifdef HAVE_LCD_BITMAP
315 struct viewport vp;
317 if (is_initialized_vp)
318 rb->viewportmanager_theme_undo(SCREEN_MAIN, false);
319 else
320 is_initialized_vp = true;
322 rb->viewportmanager_theme_enable(SCREEN_MAIN, preferences->statusbar, &vp);
323 vp_info = vp;
324 vp_info.flags &= ~VP_FLAG_ALIGNMENT_MASK;
325 #else
326 if (!is_initialized_vp)
328 rb->viewport_set_defaults(&vp_info, SCREEN_MAIN);
329 is_initialized_vp = true;
331 #endif
334 #ifdef HAVE_LCD_BITMAP
335 static bool tv_set_font(const unsigned char *font)
337 unsigned char path[MAX_PATH];
339 if (font != NULL && *font != '\0')
341 rb->snprintf(path, MAX_PATH, "%s/%s.fnt", FONT_DIR, font);
342 if (rb->font_load(NULL, path) < 0)
344 rb->splash(HZ/2, "font load failed");
345 return false;
348 return true;
350 #endif
352 static void tv_change_preferences(const struct tv_preferences *oldp)
354 #ifdef HAVE_LCD_BITMAP
355 static bool font_changing = false;
356 const unsigned char *font_str;
357 struct tv_preferences new_prefs;
359 font_str = (oldp && !font_changing)? oldp->font_name : rb->global_settings->font_file;
361 /* change font */
362 if (font_changing || rb->strcmp(font_str, preferences->font_name))
364 if (!tv_set_font(preferences->font_name))
366 font_changing = true;
367 tv_copy_preferences(&new_prefs);
368 rb->strlcpy(new_prefs.font_name, font_str, MAX_PATH);
369 tv_set_preferences(&new_prefs);
371 col_width = 2 * rb->font_get_width(preferences->font, ' ');
372 font_changing = false;
374 #else
375 (void)oldp;
376 #endif
377 tv_change_viewport();
380 bool tv_init_display(unsigned char **buf, size_t *size)
382 (void)buf;
383 (void)size;
385 display = rb->screens[SCREEN_MAIN];
386 display->clear_viewport();
388 tv_add_preferences_change_listner(tv_change_preferences);
390 return true;
393 void tv_finalize_display(void)
395 #ifdef HAVE_LCD_BITMAP
396 /* restore font */
397 if (rb->strcmp(rb->global_settings->font_file, preferences->font_name))
399 tv_set_font(rb->global_settings->font_file);
402 /* undo viewport */
403 rb->viewportmanager_theme_undo(SCREEN_MAIN, false);
404 #endif
407 bool tv_exist_scrollbar(void)
409 #ifdef HAVE_LCD_BITMAP
410 return true;
411 #else
412 return false;
413 #endif