diff options
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/lib/simple_viewer.c | 260 | ||||
-rw-r--r-- | apps/plugins/lib/simple_viewer.h | 28 |
3 files changed, 289 insertions, 0 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 8c160e1cc4..5ed163f951 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES | |||
@@ -9,6 +9,7 @@ fixedpoint.c | |||
9 | playback_control.c | 9 | playback_control.c |
10 | rgb_hsv.c | 10 | rgb_hsv.c |
11 | buflib.c | 11 | buflib.c |
12 | simple_viewer.c | ||
12 | display_text.c | 13 | display_text.c |
13 | strncpy.c | 14 | strncpy.c |
14 | 15 | ||
diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c new file mode 100644 index 0000000000..c83f005ef4 --- /dev/null +++ b/apps/plugins/lib/simple_viewer.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Teruaki Kawashima | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "plugin.h" | ||
24 | #include "pluginlib_actions.h" | ||
25 | #include "simple_viewer.h" | ||
26 | #include <ctype.h> | ||
27 | |||
28 | struct view_info { | ||
29 | #ifdef HAVE_LCD_BITMAP | ||
30 | struct font* pf; | ||
31 | #endif | ||
32 | const char *title; | ||
33 | const char *text; /* displayed text */ | ||
34 | int display_lines; /* number of lines can be displayed */ | ||
35 | int line_count; /* number of lines */ | ||
36 | int line; /* current fisrt line */ | ||
37 | int start; /* possition of first line in text */ | ||
38 | }; | ||
39 | |||
40 | static const char* get_next_line(const char *text, struct view_info *info) | ||
41 | { | ||
42 | (void) info; | ||
43 | const char *ptr = text; | ||
44 | const char *space = NULL; | ||
45 | int total, n, w; | ||
46 | total = 0; | ||
47 | while(*ptr) | ||
48 | { | ||
49 | #ifdef HAVE_LCD_CHARCELLS | ||
50 | n = rb->utf8seek(ptr, 1); | ||
51 | w = 1; | ||
52 | #else | ||
53 | unsigned short ch; | ||
54 | n = ((long)rb->utf8decode(ptr, &ch) - (long)ptr); | ||
55 | w = rb->font_get_width(info->pf, ch); | ||
56 | #endif | ||
57 | if (isspace(*ptr)) | ||
58 | space = ptr+n; | ||
59 | if (*ptr == '\n') | ||
60 | { | ||
61 | ptr += n; | ||
62 | break; | ||
63 | } | ||
64 | if (total + w > LCD_WIDTH) | ||
65 | break; | ||
66 | ptr += n; | ||
67 | total += w; | ||
68 | } | ||
69 | return *ptr && space? space: ptr; | ||
70 | } | ||
71 | |||
72 | static void calc_line_count(struct view_info *info) | ||
73 | { | ||
74 | const char *ptr = info->text; | ||
75 | int i = 0; | ||
76 | |||
77 | while (*ptr) | ||
78 | { | ||
79 | ptr = get_next_line(ptr, info); | ||
80 | i++; | ||
81 | } | ||
82 | info->line_count = i; | ||
83 | } | ||
84 | |||
85 | static void calc_first_line(struct view_info *info, int line) | ||
86 | { | ||
87 | const char *ptr = info->text; | ||
88 | int i = 0; | ||
89 | |||
90 | if (line > info->line_count - info->display_lines) | ||
91 | line = info->line_count - info->display_lines; | ||
92 | if (line < 0) | ||
93 | line = 0; | ||
94 | |||
95 | DEBUGF("%d -> %d\n", info->line, line); | ||
96 | if (info->line <= line) | ||
97 | { | ||
98 | ptr += info->start; | ||
99 | i = info->line; | ||
100 | } | ||
101 | while (*ptr && i < line) | ||
102 | { | ||
103 | ptr = get_next_line(ptr, info); | ||
104 | i++; | ||
105 | } | ||
106 | info->start = ptr - info->text; | ||
107 | info->line = i; | ||
108 | DEBUGF("%d: %d\n", info->line, info->start); | ||
109 | } | ||
110 | |||
111 | static int init_view(struct view_info *info, | ||
112 | const char *title, const char *text) | ||
113 | { | ||
114 | #ifdef HAVE_LCD_BITMAP | ||
115 | info->pf = rb->font_get(FONT_UI); | ||
116 | info->display_lines = LCD_HEIGHT / info->pf->height; | ||
117 | #else | ||
118 | |||
119 | info->display_lines = LCD_HEIGHT; | ||
120 | #endif | ||
121 | |||
122 | info->title = title; | ||
123 | info->text = text; | ||
124 | info->line_count = 0; | ||
125 | info->line = 0; | ||
126 | info->start = 0; | ||
127 | |||
128 | /* no title for small screens. */ | ||
129 | if (info->display_lines < 4) | ||
130 | { | ||
131 | info->title = NULL; | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | info->display_lines--; | ||
136 | } | ||
137 | |||
138 | calc_line_count(info); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static void draw_text(struct view_info *info) | ||
143 | { | ||
144 | #ifdef HAVE_LCD_BITMAP | ||
145 | #define OUTPUT_SIZE LCD_WIDTH+1 | ||
146 | #else | ||
147 | #define OUTPUT_SIZE LCD_WIDTH*3+1 | ||
148 | #endif | ||
149 | static char output[OUTPUT_SIZE]; | ||
150 | const char *text, *ptr; | ||
151 | int i, max_show, lines = 0; | ||
152 | |||
153 | /* clear screen */ | ||
154 | rb->lcd_clear_display(); | ||
155 | |||
156 | /* display title. */ | ||
157 | if(info->title) | ||
158 | { | ||
159 | rb->lcd_puts(0, lines, info->title); | ||
160 | lines++; | ||
161 | } | ||
162 | |||
163 | max_show = MIN(info->line_count - info->line, info->display_lines); | ||
164 | DEBUGF("draw_text: %d-%d/%d\n", | ||
165 | info->line, info->line + max_show, info->line_count); | ||
166 | text = info->text + info->start; | ||
167 | |||
168 | for (i = 0; i < max_show; i++, lines++) | ||
169 | { | ||
170 | ptr = get_next_line(text, info); | ||
171 | DEBUGF("%d>%d-%d, ", i, text-info->text, ptr-text); | ||
172 | rb->strlcpy(output, text, ptr-text+1); | ||
173 | rb->lcd_puts(0, lines, output); | ||
174 | text = ptr; | ||
175 | } | ||
176 | DEBUGF("\n"); | ||
177 | |||
178 | rb->lcd_update(); | ||
179 | } | ||
180 | |||
181 | static void scroll_up(struct view_info *info) | ||
182 | { | ||
183 | if (info->line <= 0) | ||
184 | return; | ||
185 | calc_first_line(info, info->line-1); | ||
186 | draw_text(info); | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | static void scroll_down(struct view_info *info) | ||
191 | { | ||
192 | if (info->line + info->display_lines >= info->line_count) | ||
193 | return; | ||
194 | |||
195 | calc_first_line(info, info->line+1); | ||
196 | draw_text(info); | ||
197 | } | ||
198 | |||
199 | static void scroll_to_top(struct view_info *info) | ||
200 | { | ||
201 | if (info->line <= 0) | ||
202 | return; | ||
203 | |||
204 | calc_first_line(info, 0); | ||
205 | draw_text(info); | ||
206 | } | ||
207 | |||
208 | static void scroll_to_bottom(struct view_info *info) | ||
209 | { | ||
210 | if (info->line + info->display_lines >= info->line_count) | ||
211 | return; | ||
212 | |||
213 | calc_first_line(info, info->line_count - info->display_lines); | ||
214 | draw_text(info); | ||
215 | } | ||
216 | |||
217 | int view_text(const char *title, const char *text) | ||
218 | { | ||
219 | struct view_info info; | ||
220 | const struct button_mapping *view_contexts[] = { | ||
221 | pla_main_ctx, | ||
222 | }; | ||
223 | int button; | ||
224 | |||
225 | init_view(&info, title, text); | ||
226 | draw_text(&info); | ||
227 | |||
228 | /* wait for keypress */ | ||
229 | while(1) | ||
230 | { | ||
231 | button = pluginlib_getaction(TIMEOUT_BLOCK, view_contexts, | ||
232 | ARRAYLEN(view_contexts)); | ||
233 | switch (button) | ||
234 | { | ||
235 | case PLA_UP: | ||
236 | case PLA_UP_REPEAT: | ||
237 | scroll_up(&info); | ||
238 | break; | ||
239 | case PLA_DOWN: | ||
240 | case PLA_DOWN_REPEAT: | ||
241 | scroll_down(&info); | ||
242 | break; | ||
243 | case PLA_LEFT_REPEAT: | ||
244 | scroll_to_top(&info); | ||
245 | break; | ||
246 | case PLA_RIGHT_REPEAT: | ||
247 | scroll_to_bottom(&info); | ||
248 | break; | ||
249 | case PLA_EXIT: | ||
250 | case PLA_CANCEL: | ||
251 | return PLUGIN_OK; | ||
252 | default: | ||
253 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | ||
254 | return PLUGIN_USB_CONNECTED; | ||
255 | break; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return PLUGIN_OK; | ||
260 | } | ||
diff --git a/apps/plugins/lib/simple_viewer.h b/apps/plugins/lib/simple_viewer.h new file mode 100644 index 0000000000..ff3ef23f14 --- /dev/null +++ b/apps/plugins/lib/simple_viewer.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Teruaki Kawashima | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __PLUGINLIB_VIEWER_H__ | ||
23 | #define __PLUGINLIB_VIEWER_H__ | ||
24 | |||
25 | #include "plugin.h" | ||
26 | int view_text(const char *title, const char *text); | ||
27 | |||
28 | #endif /* __PLUGINLIB_VIEWER_H__ */ | ||