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"
30 #ifdef HAVE_LCD_BITMAP
32 struct viewport scrollbar_vp
; /* viewport for scrollbar */
36 const char *text
; /* displayed text */
37 int display_lines
; /* number of lines can be displayed */
38 int line_count
; /* number of lines */
39 int line
; /* current first line */
40 int start
; /* possition of first line in text */
43 static bool isbrchr(const unsigned char *str
, int len
)
45 const unsigned char *p
= "!,-.:;? 、。!,.:;?―";
51 int n
= rb
->utf8seek(p
, 1);
52 if (len
== n
&& !rb
->strncmp(p
, str
, len
))
59 static const char* get_next_line(const char *text
, struct view_info
*info
)
61 const char *ptr
= text
;
62 const char *space
= NULL
;
67 #ifdef HAVE_LCD_CHARCELLS
68 n
= rb
->utf8seek(ptr
, 1);
72 n
= ((long)rb
->utf8decode(ptr
, &ch
) - (long)ptr
);
73 if (rb
->is_diacritic(ch
, NULL
))
76 w
= rb
->font_get_width(info
->pf
, ch
);
79 space
= ptr
+(isspace(*ptr
) || total
+ w
<= info
->vp
.width
? n
: 0);
85 if (total
+ w
> info
->vp
.width
)
90 return *ptr
&& space
? space
: ptr
;
93 static void calc_line_count(struct view_info
*info
)
95 const char *ptr
= info
->text
;
97 #ifdef HAVE_LCD_BITMAP
98 bool scrollbar
= false;
103 ptr
= get_next_line(ptr
, info
);
105 #ifdef HAVE_LCD_BITMAP
106 if (!scrollbar
&& i
> info
->display_lines
)
110 info
->scrollbar_vp
= info
->vp
;
111 info
->scrollbar_vp
.width
= rb
->global_settings
->scrollbar_width
;
112 info
->vp
.width
-= info
->scrollbar_vp
.width
;
113 if (rb
->global_settings
->scrollbar
!= SCROLLBAR_RIGHT
)
114 info
->vp
.x
= info
->scrollbar_vp
.width
;
116 info
->scrollbar_vp
.x
= info
->vp
.width
;
121 info
->line_count
= i
;
124 static void calc_first_line(struct view_info
*info
, int line
)
126 const char *ptr
= info
->text
;
129 if (line
> info
->line_count
- info
->display_lines
)
130 line
= info
->line_count
- info
->display_lines
;
134 if (info
->line
<= line
)
139 while (*ptr
&& i
< line
)
141 ptr
= get_next_line(ptr
, info
);
144 info
->start
= ptr
- info
->text
;
148 static int init_view(struct view_info
*info
,
149 const char *title
, const char *text
)
151 rb
->viewport_set_defaults(&info
->vp
, SCREEN_MAIN
);
152 #ifdef HAVE_LCD_BITMAP
153 info
->pf
= rb
->font_get(FONT_UI
);
154 info
->display_lines
= info
->vp
.height
/ info
->pf
->height
;
156 info
->display_lines
= info
->vp
.height
;
161 info
->line_count
= 0;
165 #ifdef HAVE_LCD_BITMAP
166 /* no title for small screens. */
167 if (info
->display_lines
< 4)
173 info
->display_lines
--;
174 info
->vp
.y
+= info
->pf
->height
;
175 info
->vp
.height
-= info
->pf
->height
;
179 calc_line_count(info
);
183 static void draw_text(struct view_info
*info
)
185 #ifdef HAVE_LCD_BITMAP
186 #define OUTPUT_SIZE LCD_WIDTH+1
188 #define OUTPUT_SIZE LCD_WIDTH*3+1
190 static char output
[OUTPUT_SIZE
];
191 const char *text
, *ptr
;
193 struct screen
* display
= rb
->screens
[SCREEN_MAIN
];
196 display
->clear_display();
198 #ifdef HAVE_LCD_BITMAP
202 display
->set_viewport(NULL
);
203 display
->puts(0, 0, info
->title
);
207 max_show
= MIN(info
->line_count
- info
->line
, info
->display_lines
);
208 text
= info
->text
+ info
->start
;
210 display
->set_viewport(&info
->vp
);
211 for (line
= 0; line
< max_show
; line
++)
214 ptr
= get_next_line(text
, info
);
216 while(len
> 0 && isspace(text
[len
-1]))
218 rb
->memcpy(output
, text
, len
);
220 display
->puts(0, line
, output
);
223 #ifdef HAVE_LCD_BITMAP
224 if (info
->line_count
> info
->display_lines
)
226 display
->set_viewport(&info
->scrollbar_vp
);
227 rb
->gui_scrollbar_draw(display
, (info
->scrollbar_vp
.width
? 0: 1), 0,
228 info
->scrollbar_vp
.width
- 1, info
->scrollbar_vp
.height
,
229 info
->line_count
, info
->line
, info
->line
+ max_show
,
234 display
->set_viewport(NULL
);
238 static void scroll_up(struct view_info
*info
, int n
)
243 calc_first_line(info
, info
->line
-n
);
247 static void scroll_down(struct view_info
*info
, int n
)
249 if (info
->line
+ info
->display_lines
>= info
->line_count
)
252 calc_first_line(info
, info
->line
+n
);
256 static void scroll_to_top(struct view_info
*info
)
261 calc_first_line(info
, 0);
265 static void scroll_to_bottom(struct view_info
*info
)
267 if (info
->line
+ info
->display_lines
>= info
->line_count
)
270 calc_first_line(info
, info
->line_count
- info
->display_lines
);
274 int view_text(const char *title
, const char *text
)
276 struct view_info info
;
277 const struct button_mapping
*view_contexts
[] = {
282 init_view(&info
, title
, text
);
285 /* wait for keypress */
288 button
= pluginlib_getaction(TIMEOUT_BLOCK
, view_contexts
,
289 ARRAYLEN(view_contexts
));
294 #ifdef HAVE_SCROLLWHEEL
295 case PLA_SCROLL_BACK
:
296 case PLA_SCROLL_BACK_REPEAT
:
301 case PLA_DOWN_REPEAT
:
302 #ifdef HAVE_SCROLLWHEEL
304 case PLA_SCROLL_FWD_REPEAT
:
306 scroll_down(&info
, 1);
309 scroll_up(&info
, info
.display_lines
);
312 scroll_down(&info
, info
.display_lines
);
314 case PLA_LEFT_REPEAT
:
315 scroll_to_top(&info
);
317 case PLA_RIGHT_REPEAT
:
318 scroll_to_bottom(&info
);
324 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
325 return PLUGIN_USB_CONNECTED
;