1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Teruaki Kawashima
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 ****************************************************************************/
24 #include "pluginlib_actions.h"
25 #include "simple_viewer.h"
29 #ifdef HAVE_LCD_BITMAP
31 struct viewport scrollbar_vp
; /* viewport for scrollbar */
35 const char *text
; /* displayed text */
36 int display_lines
; /* number of lines can be displayed */
37 int line_count
; /* number of lines */
38 int line
; /* current first line */
39 int start
; /* possition of first line in text */
42 static bool isbrchr(const unsigned char *str
, int len
)
44 const unsigned char *p
= "!,-.:;? 、。!,.:;?―";
50 int n
= rb
->utf8seek(p
, 1);
51 if (len
== n
&& !rb
->strncmp(p
, str
, len
))
58 static const char* get_next_line(const char *text
, struct view_info
*info
)
60 const char *ptr
= text
;
61 const char *space
= NULL
;
66 #ifdef HAVE_LCD_CHARCELLS
67 n
= rb
->utf8seek(ptr
, 1);
71 n
= ((long)rb
->utf8decode(ptr
, &ch
) - (long)ptr
);
72 if (rb
->is_diacritic(ch
, NULL
))
75 w
= rb
->font_get_width(info
->pf
, ch
);
78 space
= ptr
+(isspace(*ptr
) || total
+ w
<= info
->vp
.width
? n
: 0);
84 if (total
+ w
> info
->vp
.width
)
89 return *ptr
&& space
? space
: ptr
;
92 static void calc_line_count(struct view_info
*info
)
94 const char *ptr
= info
->text
;
96 #ifdef HAVE_LCD_BITMAP
97 bool scrollbar
= false;
102 ptr
= get_next_line(ptr
, info
);
104 #ifdef HAVE_LCD_BITMAP
105 if (!scrollbar
&& i
> info
->display_lines
)
109 info
->scrollbar_vp
= info
->vp
;
110 info
->scrollbar_vp
.width
= rb
->global_settings
->scrollbar_width
;
111 info
->vp
.width
-= info
->scrollbar_vp
.width
;
112 if (rb
->global_settings
->scrollbar
!= SCROLLBAR_RIGHT
)
113 info
->vp
.x
= info
->scrollbar_vp
.width
;
115 info
->scrollbar_vp
.x
= info
->vp
.width
;
120 info
->line_count
= i
;
123 static void calc_first_line(struct view_info
*info
, int line
)
125 const char *ptr
= info
->text
;
128 if (line
> info
->line_count
- info
->display_lines
)
129 line
= info
->line_count
- info
->display_lines
;
133 if (info
->line
<= line
)
138 while (*ptr
&& i
< line
)
140 ptr
= get_next_line(ptr
, info
);
143 info
->start
= ptr
- info
->text
;
147 static int init_view(struct view_info
*info
,
148 const char *title
, const char *text
)
150 rb
->viewport_set_defaults(&info
->vp
, SCREEN_MAIN
);
151 #ifdef HAVE_LCD_BITMAP
152 info
->pf
= rb
->font_get(FONT_UI
);
153 info
->display_lines
= info
->vp
.height
/ info
->pf
->height
;
155 info
->display_lines
= info
->vp
.height
;
160 info
->line_count
= 0;
164 #ifdef HAVE_LCD_BITMAP
165 /* no title for small screens. */
166 if (info
->display_lines
< 4)
172 info
->display_lines
--;
173 info
->vp
.y
+= info
->pf
->height
;
174 info
->vp
.height
-= info
->pf
->height
;
178 calc_line_count(info
);
182 static void draw_text(struct view_info
*info
)
184 #ifdef HAVE_LCD_BITMAP
185 #define OUTPUT_SIZE LCD_WIDTH+1
187 #define OUTPUT_SIZE LCD_WIDTH*3+1
189 static char output
[OUTPUT_SIZE
];
190 const char *text
, *ptr
;
192 struct screen
* display
= rb
->screens
[SCREEN_MAIN
];
195 display
->clear_display();
197 #ifdef HAVE_LCD_BITMAP
201 display
->set_viewport(NULL
);
202 display
->puts(0, 0, info
->title
);
206 max_show
= MIN(info
->line_count
- info
->line
, info
->display_lines
);
207 text
= info
->text
+ info
->start
;
209 display
->set_viewport(&info
->vp
);
210 for (line
= 0; line
< max_show
; line
++)
213 ptr
= get_next_line(text
, info
);
215 while(len
> 0 && isspace(text
[len
-1]))
217 rb
->memcpy(output
, text
, len
);
219 display
->puts(0, line
, output
);
222 #ifdef HAVE_LCD_BITMAP
223 if (info
->line_count
> info
->display_lines
)
225 display
->set_viewport(&info
->scrollbar_vp
);
226 rb
->gui_scrollbar_draw(display
, (info
->scrollbar_vp
.width
? 0: 1), 0,
227 info
->scrollbar_vp
.width
- 1, info
->scrollbar_vp
.height
,
228 info
->line_count
, info
->line
, info
->line
+ max_show
,
233 display
->set_viewport(NULL
);
237 static void scroll_up(struct view_info
*info
, int n
)
242 calc_first_line(info
, info
->line
-n
);
246 static void scroll_down(struct view_info
*info
, int n
)
248 if (info
->line
+ info
->display_lines
>= info
->line_count
)
251 calc_first_line(info
, info
->line
+n
);
255 static void scroll_to_top(struct view_info
*info
)
260 calc_first_line(info
, 0);
264 static void scroll_to_bottom(struct view_info
*info
)
266 if (info
->line
+ info
->display_lines
>= info
->line_count
)
269 calc_first_line(info
, info
->line_count
- info
->display_lines
);
273 int view_text(const char *title
, const char *text
)
275 struct view_info info
;
276 const struct button_mapping
*view_contexts
[] = {
281 init_view(&info
, title
, text
);
284 /* wait for keypress */
287 button
= pluginlib_getaction(TIMEOUT_BLOCK
, view_contexts
,
288 ARRAYLEN(view_contexts
));
293 #ifdef HAVE_SCROLLWHEEL
294 case PLA_SCROLL_BACK
:
295 case PLA_SCROLL_BACK_REPEAT
:
300 case PLA_DOWN_REPEAT
:
301 #ifdef HAVE_SCROLLWHEEL
303 case PLA_SCROLL_FWD_REPEAT
:
305 scroll_down(&info
, 1);
308 scroll_up(&info
, info
.display_lines
);
311 scroll_down(&info
, info
.display_lines
);
313 case PLA_LEFT_REPEAT
:
314 scroll_to_top(&info
);
316 case PLA_RIGHT_REPEAT
:
317 scroll_to_bottom(&info
);
323 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
324 return PLUGIN_USB_CONNECTED
;