diff options
author | Zakk Roberts <midk@rockbox.org> | 2006-05-01 05:45:18 +0000 |
---|---|---|
committer | Zakk Roberts <midk@rockbox.org> | 2006-05-01 05:45:18 +0000 |
commit | 07fcf77cb0b734135fdc730a164f3333d6c703e5 (patch) | |
tree | b30cffeb322adff6c09033c482ec3e0288167aef /apps/plugins/viewer.c | |
parent | 0d6b5557a113afab41c7ef239c9ce5ddabebea8b (diff) | |
download | rockbox-07fcf77cb0b734135fdc730a164f3333d6c703e5.tar.gz rockbox-07fcf77cb0b734135fdc730a164f3333d6c703e5.zip |
Patch #5056 by Jonathan Gordon, with rework and additions by me: Updated Viewer plugin. Replaces annoying mode-toggle key-combos with a settings menu, including a new 'Scroll by Line' option. I've also added a 'hands-free' auto-scroll feature and added lcd_setmargins to the plugin API, since we need it here.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9844 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/viewer.c')
-rw-r--r-- | apps/plugins/viewer.c | 704 |
1 files changed, 328 insertions, 376 deletions
diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c index 51bf03af75..947dfc980a 100644 --- a/apps/plugins/viewer.c +++ b/apps/plugins/viewer.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | PLUGIN_HEADER | 24 | PLUGIN_HEADER |
25 | 25 | ||
26 | #define SETTINGS_FILE "/.rockbox/viewers/viewer.dat" | 26 | #define SETTINGS_FILE "/.rockbox/viewers/viewer.cfg" |
27 | 27 | ||
28 | #define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ | 28 | #define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */ |
29 | #define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ | 29 | #define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */ |
@@ -55,22 +55,19 @@ PLUGIN_HEADER | |||
55 | 55 | ||
56 | /* Is a scrollbar called for on the current screen? */ | 56 | /* Is a scrollbar called for on the current screen? */ |
57 | #define NEED_SCROLLBAR() \ | 57 | #define NEED_SCROLLBAR() \ |
58 | ((!(ONE_SCREEN_FITS_ALL())) && (scrollbar_mode[view_mode]==SB_ON)) | 58 | ((!(ONE_SCREEN_FITS_ALL())) && (prefs.scrollbar_mode==SB_ON)) |
59 | 59 | ||
60 | /* variable button definitions */ | 60 | /* variable button definitions */ |
61 | 61 | ||
62 | /* Recorder keys */ | 62 | /* Recorder keys */ |
63 | #if CONFIG_KEYPAD == RECORDER_PAD | 63 | #if CONFIG_KEYPAD == RECORDER_PAD |
64 | #define VIEWER_MENU BUTTON_OFF | 64 | #define VIEWER_QUIT BUTTON_OFF |
65 | #define VIEWER_PAGE_UP BUTTON_UP | 65 | #define VIEWER_PAGE_UP BUTTON_UP |
66 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 66 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
67 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 67 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
68 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 68 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
69 | #define VIEWER_MODE_WRAP BUTTON_F1 | 69 | #define VIEWER_MENU BUTTON_F1 |
70 | #define VIEWER_MODE_LINE BUTTON_F2 | 70 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
71 | #define VIEWER_MODE_WIDTH BUTTON_F3 | ||
72 | #define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_F1) | ||
73 | #define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_F3) | ||
74 | #define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) | 71 | #define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) |
75 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) | 72 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) |
76 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) | 73 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) |
@@ -78,151 +75,128 @@ PLUGIN_HEADER | |||
78 | 75 | ||
79 | /* Ondio keys */ | 76 | /* Ondio keys */ |
80 | #elif CONFIG_KEYPAD == ONDIO_PAD | 77 | #elif CONFIG_KEYPAD == ONDIO_PAD |
81 | #define VIEWER_MENU BUTTON_OFF | ||
82 | #define VIEWER_PAGE_UP BUTTON_UP | 78 | #define VIEWER_PAGE_UP BUTTON_UP |
83 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 79 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
84 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 80 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
85 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 81 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
86 | #define VIEWER_MODE_WRAP (BUTTON_MENU | BUTTON_LEFT) | 82 | #define VIEWER_MENU BUTTON_OFF |
87 | #define VIEWER_MODE_LINE (BUTTON_MENU | BUTTON_UP) | 83 | #define VIEWER_AUTOSCROLL BUTTON_MENU |
88 | #define VIEWER_MODE_WIDTH (BUTTON_MENU | BUTTON_RIGHT) | ||
89 | #define VIEWER_MODE_PAGE (BUTTON_MENU | BUTTON_DOWN) | ||
90 | #define VIEWER_MODE_SCROLLBAR (BUTTON_MENU | BUTTON_OFF) | ||
91 | 84 | ||
92 | /* Player keys */ | 85 | /* Player keys */ |
93 | #elif CONFIG_KEYPAD == PLAYER_PAD | 86 | #elif CONFIG_KEYPAD == PLAYER_PAD |
94 | #define VIEWER_MENU BUTTON_STOP | 87 | #define VIEWER_QUIT BUTTON_STOP |
95 | #define VIEWER_PAGE_UP BUTTON_LEFT | 88 | #define VIEWER_PAGE_UP BUTTON_LEFT |
96 | #define VIEWER_PAGE_DOWN BUTTON_RIGHT | 89 | #define VIEWER_PAGE_DOWN BUTTON_RIGHT |
97 | #define VIEWER_SCREEN_LEFT (BUTTON_MENU | BUTTON_LEFT) | 90 | #define VIEWER_MENU BUTTON_MENU |
98 | #define VIEWER_SCREEN_RIGHT (BUTTON_MENU | BUTTON_RIGHT) | 91 | #define VIEWER_AUTOSCROLL BUTTON_ON |
99 | #define VIEWER_MODE_WRAP (BUTTON_ON | BUTTON_LEFT) | ||
100 | #define VIEWER_MODE_LINE (BUTTON_ON | BUTTON_MENU | BUTTON_RIGHT) | ||
101 | #define VIEWER_MODE_WIDTH (BUTTON_ON | BUTTON_RIGHT) | ||
102 | 92 | ||
103 | /* iRiver H1x0 && H3x0 keys */ | 93 | /* iRiver H1x0 && H3x0 keys */ |
104 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | 94 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ |
105 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | 95 | (CONFIG_KEYPAD == IRIVER_H300_PAD) |
106 | #define VIEWER_MENU BUTTON_OFF | 96 | #define VIEWER_QUIT BUTTON_OFF |
107 | #define VIEWER_PAGE_UP BUTTON_UP | 97 | #define VIEWER_PAGE_UP BUTTON_UP |
108 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 98 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
109 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 99 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
110 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 100 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
111 | #define VIEWER_MODE_WRAP BUTTON_REC | 101 | #define VIEWER_MENU BUTTON_MODE |
112 | #define VIEWER_MODE_LINE BUTTON_MODE | 102 | #define VIEWER_AUTOSCROLL BUTTON_SELECT |
113 | #define VIEWER_MODE_WIDTH BUTTON_SELECT | ||
114 | #define VIEWER_MODE_PAGE (BUTTON_ON | BUTTON_MODE) | ||
115 | #define VIEWER_MODE_SCROLLBAR (BUTTON_ON | BUTTON_REC) | ||
116 | #define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) | 103 | #define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP) |
117 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) | 104 | #define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN) |
118 | #define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT) | ||
119 | #define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT) | ||
120 | 105 | ||
121 | /* iPods with the 4G pad */ | 106 | /* iPods with the 4G pad */ |
122 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 107 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
123 | (CONFIG_KEYPAD == IPOD_3G_PAD) | 108 | (CONFIG_KEYPAD == IPOD_3G_PAD) |
109 | #define VIEWER_QUIT_PRE BUTTON_SELECT | ||
110 | #define VIEWER_QUIT (BUTTON_SELECT | BUTTON_MENU) | ||
124 | #define VIEWER_MENU BUTTON_MENU | 111 | #define VIEWER_MENU BUTTON_MENU |
112 | #define VIEWER_AUTOSCROLL BUTTON_PLAY | ||
125 | #define VIEWER_PAGE_UP BUTTON_SCROLL_BACK | 113 | #define VIEWER_PAGE_UP BUTTON_SCROLL_BACK |
126 | #define VIEWER_PAGE_DOWN BUTTON_SCROLL_FWD | 114 | #define VIEWER_PAGE_DOWN BUTTON_SCROLL_FWD |
127 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 115 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
128 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 116 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
129 | #define VIEWER_MODE_WRAP (BUTTON_SELECT | BUTTON_LEFT) | ||
130 | #define VIEWER_MODE_LINE (BUTTON_SELECT | BUTTON_PLAY) | ||
131 | #define VIEWER_MODE_WIDTH (BUTTON_SELECT | BUTTON_RIGHT) | ||
132 | #define VIEWER_MODE_PAGE (BUTTON_SELECT | BUTTON_LEFT | BUTTON_MENU) | ||
133 | #define VIEWER_MODE_SCROLLBAR (BUTTON_SELECT | BUTTON_LEFT | BUTTON_RIGHT) | ||
134 | 117 | ||
135 | /* iFP7xx keys */ | 118 | /* iFP7xx keys */ |
136 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD | 119 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD |
137 | #define VIEWER_MENU BUTTON_PLAY | 120 | #define VIEWER_QUIT BUTTON_PLAY |
138 | #define VIEWER_PAGE_UP BUTTON_UP | 121 | #define VIEWER_PAGE_UP BUTTON_UP |
139 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 122 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
140 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 123 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
141 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 124 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
142 | #define VIEWER_MODE_WRAP (BUTTON_EQ | BUTTON_REL) | 125 | #define VIEWER_MENU BUTTON_MODE |
143 | #define VIEWER_MODE_LINE (BUTTON_EQ | BUTTON_REPEAT) | 126 | #define VIEWER_AUTOSCROLL BUTTON_SELECT |
144 | #define VIEWER_MODE_WIDTH BUTTON_MODE | ||
145 | 127 | ||
146 | /* iAudio X5 keys */ | 128 | /* iAudio X5 keys */ |
147 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD | 129 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD |
148 | #define VIEWER_MENU BUTTON_POWER | 130 | #define VIEWER_QUIT BUTTON_POWER |
149 | #define VIEWER_PAGE_UP BUTTON_UP | 131 | #define VIEWER_PAGE_UP BUTTON_UP |
150 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 132 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
151 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 133 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
152 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 134 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
153 | #define VIEWER_MODE_WRAP (BUTTON_PLAY | BUTTON_REL) | 135 | #define VIEWER_MENU BUTTON_SELECT |
154 | #define VIEWER_MODE_LINE (BUTTON_PLAY | BUTTON_REPEAT) | 136 | #define VIEWER_AUTOSCROLL BUTTON_PLAY |
155 | #define VIEWER_MODE_WIDTH BUTTON_SELECT | ||
156 | 137 | ||
157 | /* iAudio X5 keys */ | 138 | /* GIGABEAT keys */ |
158 | #elif CONFIG_KEYPAD == GIGABEAT_PAD | 139 | #elif CONFIG_KEYPAD == GIGABEAT_PAD |
159 | #define VIEWER_MENU BUTTON_A | 140 | #define VIEWER_QUIT BUTTON_POWER |
160 | #define VIEWER_PAGE_UP BUTTON_UP | 141 | #define VIEWER_PAGE_UP BUTTON_UP |
161 | #define VIEWER_PAGE_DOWN BUTTON_DOWN | 142 | #define VIEWER_PAGE_DOWN BUTTON_DOWN |
162 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT | 143 | #define VIEWER_SCREEN_LEFT BUTTON_LEFT |
163 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT | 144 | #define VIEWER_SCREEN_RIGHT BUTTON_RIGHT |
164 | #define VIEWER_MODE_WRAP (BUTTON_POWER | BUTTON_REL) | 145 | #define VIEWER_MENU BUTTON_MENU |
165 | #define VIEWER_MODE_LINE (BUTTON_POWER | BUTTON_REPEAT) | 146 | #define VIEWER_AUTOSCROLL BUTTON_A |
166 | #define VIEWER_MODE_WIDTH BUTTON_MENU | ||
167 | 147 | ||
168 | #endif | 148 | #endif |
169 | 149 | ||
170 | enum { | 150 | struct preferences { |
171 | WRAP=0, | 151 | enum { |
172 | CHOP, | 152 | WRAP=0, |
173 | WORD_MODES | 153 | CHOP, |
174 | } word_mode = 0; | 154 | WORD_MODES |
175 | static unsigned char *word_mode_str[] = {"wrap", "chop", "words"}; | 155 | } word_mode; |
176 | 156 | ||
177 | enum { | 157 | enum { |
178 | NORMAL=0, | 158 | NORMAL=0, |
179 | JOIN, | 159 | JOIN, |
180 | #ifdef HAVE_LCD_BITMAP | 160 | #ifdef HAVE_LCD_BITMAP |
181 | REFLOW, /* Makes no sense for the player */ | 161 | REFLOW, /* Makes no sense for the player */ |
182 | #endif | 162 | #endif |
183 | EXPAND, | 163 | EXPAND, |
184 | LINE_MODES, | 164 | LINE_MODES, |
185 | #ifndef HAVE_LCD_BITMAP | 165 | #ifndef HAVE_LCD_BITMAP |
186 | REFLOW /* Sorting it behind LINE_MODES effectively disables it. */ | 166 | REFLOW /* Sorting it behind LINE_MODES effectively disables it. */ |
187 | #endif | 167 | #endif |
188 | } line_mode = 0; | 168 | } line_mode; |
189 | |||
190 | static unsigned char *line_mode_str[] = { | ||
191 | [NORMAL] = "normal", [JOIN] = "join", [REFLOW] = "reflow", | ||
192 | [EXPAND] = "expand", [LINE_MODES] = "lines" | ||
193 | }; | ||
194 | 169 | ||
195 | enum { | 170 | enum { |
196 | NARROW=0, | 171 | NARROW=0, |
197 | WIDE, | 172 | WIDE, |
198 | VIEW_MODES | 173 | VIEW_MODES |
199 | } view_mode = 0; | 174 | } view_mode; |
200 | static unsigned char *view_mode_str[] = {"narrow", "wide", "view"}; | ||
201 | 175 | ||
202 | #ifdef HAVE_LCD_BITMAP | 176 | #ifdef HAVE_LCD_BITMAP |
203 | enum { | 177 | enum { |
204 | SB_OFF=0, | 178 | SB_OFF=0, |
205 | SB_ON, | 179 | SB_ON, |
206 | SCROLLBAR_MODES | 180 | SCROLLBAR_MODES |
207 | } scrollbar_mode[VIEW_MODES] = {SB_OFF, SB_ON}; | 181 | } scrollbar_mode; |
208 | #ifdef VIEWER_MODE_SCROLLBAR | 182 | bool need_scrollbar; |
209 | static unsigned char *scrollbar_mode_str[] = {"off", "on", "scrollbar"}; | 183 | |
210 | #endif | 184 | enum { |
211 | 185 | NO_OVERLAP=0, | |
212 | static bool need_scrollbar; | 186 | OVERLAP, |
213 | 187 | PAGE_MODES | |
214 | 188 | } page_mode; | |
215 | enum { | 189 | |
216 | NO_OVERLAP=0, | 190 | #endif /* HAVE_LCD_BITMAP */ |
217 | OVERLAP, | 191 | |
218 | PAGE_MODES | 192 | enum { |
219 | } page_mode = 0; | 193 | PAGE=0, |
220 | 194 | LINE, | |
221 | #ifdef VIEWER_MODE_PAGE | 195 | SCROLL_MODES |
222 | static unsigned char *page_mode_str[] = {"don't overlap", "overlap", "pages"}; | 196 | } scroll_mode; |
223 | #endif | 197 | |
224 | 198 | int autoscroll_speed; | |
225 | #endif | 199 | } prefs; |
226 | 200 | ||
227 | static unsigned char buffer[BUFFER_SIZE + 1]; | 201 | static unsigned char buffer[BUFFER_SIZE + 1]; |
228 | static unsigned char line_break[] = {0,0x20,'-',9,0xB,0xC}; | 202 | static unsigned char line_break[] = {0,0x20,'-',9,0xB,0xC}; |
@@ -245,6 +219,9 @@ static struct plugin_api* rb; | |||
245 | 219 | ||
246 | static unsigned char glyph_width[256]; | 220 | static unsigned char glyph_width[256]; |
247 | 221 | ||
222 | bool done = false; | ||
223 | int col = 0; | ||
224 | |||
248 | #define ADVANCE_COUNTERS(c) do { width += glyph_width[c]; k++; } while(0) | 225 | #define ADVANCE_COUNTERS(c) do { width += glyph_width[c]; k++; } while(0) |
249 | #define LINE_IS_FULL ((k>MAX_COLUMNS-1) || (width > draw_columns)) | 226 | #define LINE_IS_FULL ((k>MAX_COLUMNS-1) || (width > draw_columns)) |
250 | static unsigned char* crop_at_width(const unsigned char* p) | 227 | static unsigned char* crop_at_width(const unsigned char* p) |
@@ -284,7 +261,7 @@ static unsigned char* find_last_space(const unsigned char* p, int size) | |||
284 | { | 261 | { |
285 | int i, j, k; | 262 | int i, j, k; |
286 | 263 | ||
287 | k = (line_mode==JOIN) || (line_mode==REFLOW) ? 0:1; | 264 | k = (prefs.line_mode==JOIN) || (prefs.line_mode==REFLOW) ? 0:1; |
288 | 265 | ||
289 | for (i=size-1; i>=0; i--) | 266 | for (i=size-1; i>=0; i--) |
290 | for (j=k; j < (int) sizeof(line_break); j++) | 267 | for (j=k; j < (int) sizeof(line_break); j++) |
@@ -307,16 +284,16 @@ static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_sho | |||
307 | if BUFFER_OOB(cur_line) | 284 | if BUFFER_OOB(cur_line) |
308 | return NULL; | 285 | return NULL; |
309 | 286 | ||
310 | if (view_mode == WIDE) { | 287 | if (prefs.view_mode == WIDE) { |
311 | search_len = MAX_WIDTH; | 288 | search_len = MAX_WIDTH; |
312 | } | 289 | } |
313 | else { /* view_mode == NARROW */ | 290 | else { /* prefs.view_mode == NARROW */ |
314 | search_len = crop_at_width(cur_line) - cur_line; | 291 | search_len = crop_at_width(cur_line) - cur_line; |
315 | } | 292 | } |
316 | 293 | ||
317 | size = BUFFER_OOB(cur_line+search_len) ? buffer_end-cur_line : search_len; | 294 | size = BUFFER_OOB(cur_line+search_len) ? buffer_end-cur_line : search_len; |
318 | 295 | ||
319 | if ((line_mode == JOIN) || (line_mode == REFLOW)) { | 296 | if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW)) { |
320 | /* Need to scan ahead and possibly increase search_len and size, | 297 | /* Need to scan ahead and possibly increase search_len and size, |
321 | or possibly set next_line at second hard return in a row. */ | 298 | or possibly set next_line at second hard return in a row. */ |
322 | next_line = NULL; | 299 | next_line = NULL; |
@@ -332,7 +309,7 @@ static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_sho | |||
332 | c = cur_line[j]; | 309 | c = cur_line[j]; |
333 | switch (c) { | 310 | switch (c) { |
334 | case ' ': | 311 | case ' ': |
335 | if (line_mode == REFLOW) { | 312 | if (prefs.line_mode == REFLOW) { |
336 | if (newlines > 0) { | 313 | if (newlines > 0) { |
337 | size = j; | 314 | size = j; |
338 | next_line = cur_line + size; | 315 | next_line = cur_line + size; |
@@ -363,7 +340,7 @@ static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_sho | |||
363 | break; | 340 | break; |
364 | 341 | ||
365 | default: | 342 | default: |
366 | if (line_mode==JOIN || newlines>0) { | 343 | if (prefs.line_mode==JOIN || newlines>0) { |
367 | while (spaces) { | 344 | while (spaces) { |
368 | spaces--; | 345 | spaces--; |
369 | ADVANCE_COUNTERS(' '); | 346 | ADVANCE_COUNTERS(' '); |
@@ -398,20 +375,20 @@ static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_sho | |||
398 | 375 | ||
399 | if (next_line == NULL) | 376 | if (next_line == NULL) |
400 | if (size == search_len) { | 377 | if (size == search_len) { |
401 | if (word_mode == WRAP) /* Find last space */ | 378 | if (prefs.word_mode == WRAP) /* Find last space */ |
402 | next_line = find_last_space(cur_line, size); | 379 | next_line = find_last_space(cur_line, size); |
403 | 380 | ||
404 | if (next_line == NULL) | 381 | if (next_line == NULL) |
405 | next_line = crop_at_width(cur_line); | 382 | next_line = crop_at_width(cur_line); |
406 | else | 383 | else |
407 | if (word_mode == WRAP) | 384 | if (prefs.word_mode == WRAP) |
408 | for (i=0; | 385 | for (i=0; |
409 | i<WRAP_TRIM && isspace(next_line[0]) && !BUFFER_OOB(next_line); | 386 | i<WRAP_TRIM && isspace(next_line[0]) && !BUFFER_OOB(next_line); |
410 | i++) | 387 | i++) |
411 | next_line++; | 388 | next_line++; |
412 | } | 389 | } |
413 | 390 | ||
414 | if (line_mode == EXPAND) | 391 | if (prefs.line_mode == EXPAND) |
415 | if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */ | 392 | if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */ |
416 | if (next_line[0] == 0) | 393 | if (next_line[0] == 0) |
417 | if (next_line != cur_line) | 394 | if (next_line != cur_line) |
@@ -458,7 +435,7 @@ static unsigned char* find_prev_line(const unsigned char* cur_line) | |||
458 | points from where they wrap when scrolling down. | 435 | points from where they wrap when scrolling down. |
459 | If buffer is at top of file, start at top of buffer. */ | 436 | If buffer is at top of file, start at top of buffer. */ |
460 | 437 | ||
461 | if ((line_mode == JOIN) || (line_mode == REFLOW)) | 438 | if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW)) |
462 | prev_line = p = NULL; | 439 | prev_line = p = NULL; |
463 | else | 440 | else |
464 | prev_line = p = find_last_feed(buffer, cur_line-buffer-1); | 441 | prev_line = p = find_last_feed(buffer, cur_line-buffer-1); |
@@ -537,7 +514,7 @@ static int read_and_synch(int direction) | |||
537 | rb->memcpy(MID_SECTOR, TOP_SECTOR, SMALL_BLOCK_SIZE); | 514 | rb->memcpy(MID_SECTOR, TOP_SECTOR, SMALL_BLOCK_SIZE); |
538 | } | 515 | } |
539 | else /* down */ { | 516 | else /* down */ { |
540 | if (view_mode == WIDE) { | 517 | if (prefs.view_mode == WIDE) { |
541 | /* WIDE mode needs more buffer so we have to read smaller blocks */ | 518 | /* WIDE mode needs more buffer so we have to read smaller blocks */ |
542 | move_size = SMALL_BLOCK_SIZE; | 519 | move_size = SMALL_BLOCK_SIZE; |
543 | offset = LARGE_BLOCK_SIZE; | 520 | offset = LARGE_BLOCK_SIZE; |
@@ -573,6 +550,12 @@ static void viewer_scroll_up(void) | |||
573 | screen_top_ptr = p; | 550 | screen_top_ptr = p; |
574 | } | 551 | } |
575 | 552 | ||
553 | static void viewer_scroll_down(void) | ||
554 | { | ||
555 | if (next_screen_ptr != NULL) | ||
556 | screen_top_ptr = next_line_ptr; | ||
557 | } | ||
558 | |||
576 | #ifdef HAVE_LCD_BITMAP | 559 | #ifdef HAVE_LCD_BITMAP |
577 | static void viewer_scrollbar(void) { | 560 | static void viewer_scrollbar(void) { |
578 | int w, h, items, min_shown, max_shown; | 561 | int w, h, items, min_shown, max_shown; |
@@ -586,7 +569,7 @@ static void viewer_scrollbar(void) { | |||
586 | else | 569 | else |
587 | max_shown = min_shown + (next_screen_ptr - screen_top_ptr); | 570 | max_shown = min_shown + (next_screen_ptr - screen_top_ptr); |
588 | 571 | ||
589 | rb->scrollbar(0, 0, w-1, LCD_HEIGHT, items, min_shown, max_shown, VERTICAL); | 572 | rb->scrollbar(0, 0, w-2, LCD_HEIGHT, items, min_shown, max_shown, VERTICAL); |
590 | } | 573 | } |
591 | #endif | 574 | #endif |
592 | 575 | ||
@@ -603,11 +586,10 @@ static void viewer_draw(int col) | |||
603 | int len; | 586 | int len; |
604 | unsigned char *endptr; | 587 | unsigned char *endptr; |
605 | 588 | ||
606 | |||
607 | /* If col==-1 do all calculations but don't display */ | 589 | /* If col==-1 do all calculations but don't display */ |
608 | if (col != -1) { | 590 | if (col != -1) { |
609 | #ifdef HAVE_LCD_BITMAP | 591 | #ifdef HAVE_LCD_BITMAP |
610 | left_col = need_scrollbar? 1:0; | 592 | left_col = prefs.need_scrollbar? 1:0; |
611 | #else | 593 | #else |
612 | left_col = 0; | 594 | left_col = 0; |
613 | #endif | 595 | #endif |
@@ -653,10 +635,10 @@ static void viewer_draw(int col) | |||
653 | } | 635 | } |
654 | line_len = line_end - line_begin; | 636 | line_len = line_end - line_begin; |
655 | 637 | ||
656 | if (line_mode == JOIN) { | 638 | if (prefs.line_mode == JOIN) { |
657 | if (line_begin[0] == 0) { | 639 | if (line_begin[0] == 0) { |
658 | line_begin++; | 640 | line_begin++; |
659 | if (word_mode == CHOP) | 641 | if (prefs.word_mode == CHOP) |
660 | line_end++; | 642 | line_end++; |
661 | else | 643 | else |
662 | line_len--; | 644 | line_len--; |
@@ -696,10 +678,10 @@ static void viewer_draw(int col) | |||
696 | rb->lcd_puts(left_col, i, utf8_buffer); | 678 | rb->lcd_puts(left_col, i, utf8_buffer); |
697 | } | 679 | } |
698 | } | 680 | } |
699 | else if (line_mode == REFLOW) { | 681 | else if (prefs.line_mode == REFLOW) { |
700 | if (line_begin[0] == 0) { | 682 | if (line_begin[0] == 0) { |
701 | line_begin++; | 683 | line_begin++; |
702 | if (word_mode == CHOP) | 684 | if (prefs.word_mode == CHOP) |
703 | line_end++; | 685 | line_end++; |
704 | else | 686 | else |
705 | line_len--; | 687 | line_len--; |
@@ -713,7 +695,7 @@ static void viewer_draw(int col) | |||
713 | switch (c) { | 695 | switch (c) { |
714 | case ' ': | 696 | case ' ': |
715 | case 0: | 697 | case 0: |
716 | if ((j==0) && (word_mode==WRAP)) | 698 | if ((j==0) && (prefs.word_mode==WRAP)) |
717 | /* special case: indent the paragraph, | 699 | /* special case: indent the paragraph, |
718 | * don't count spaces */ | 700 | * don't count spaces */ |
719 | indent_spaces = par_indent_spaces; | 701 | indent_spaces = par_indent_spaces; |
@@ -759,7 +741,7 @@ static void viewer_draw(int col) | |||
759 | switch (c) { | 741 | switch (c) { |
760 | case ' ': | 742 | case ' ': |
761 | case 0: | 743 | case 0: |
762 | if (j==0 && word_mode==WRAP) { /* indent paragraph */ | 744 | if (j==0 && prefs.word_mode==WRAP) { /* indent paragraph */ |
763 | for (j=0; j<par_indent_spaces; j++) | 745 | for (j=0; j<par_indent_spaces; j++) |
764 | scratch_buffer[k++] = ' '; | 746 | scratch_buffer[k++] = ' '; |
765 | j=0; | 747 | j=0; |
@@ -788,7 +770,7 @@ static void viewer_draw(int col) | |||
788 | rb->lcd_puts(left_col, i, utf8_buffer); | 770 | rb->lcd_puts(left_col, i, utf8_buffer); |
789 | } | 771 | } |
790 | } | 772 | } |
791 | else { /* line_mode != JOIN && line_mode != REFLOW */ | 773 | else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */ |
792 | if (col != -1) | 774 | if (col != -1) |
793 | if (line_len > col) { | 775 | if (line_len > col) { |
794 | c = line_end[0]; | 776 | c = line_end[0]; |
@@ -812,9 +794,9 @@ static void viewer_draw(int col) | |||
812 | next_screen_ptr = NULL; | 794 | next_screen_ptr = NULL; |
813 | 795 | ||
814 | #ifdef HAVE_LCD_BITMAP | 796 | #ifdef HAVE_LCD_BITMAP |
815 | next_screen_to_draw_ptr = page_mode==OVERLAP? line_begin: next_screen_ptr; | 797 | next_screen_to_draw_ptr = prefs.page_mode==OVERLAP? line_begin: next_screen_ptr; |
816 | 798 | ||
817 | if (need_scrollbar) | 799 | if (prefs.need_scrollbar) |
818 | viewer_scrollbar(); | 800 | viewer_scrollbar(); |
819 | 801 | ||
820 | if (col != -1) | 802 | if (col != -1) |
@@ -834,6 +816,7 @@ static void viewer_top(void) | |||
834 | fill_buffer(0, buffer, BUFFER_SIZE); | 816 | fill_buffer(0, buffer, BUFFER_SIZE); |
835 | } | 817 | } |
836 | 818 | ||
819 | #ifdef HAVE_LCD_BITMAP | ||
837 | static void viewer_bottom(void) | 820 | static void viewer_bottom(void) |
838 | { | 821 | { |
839 | /* Read bottom of file into buffer | 822 | /* Read bottom of file into buffer |
@@ -855,13 +838,12 @@ static void viewer_bottom(void) | |||
855 | fill_buffer(last_sectors, buffer, BUFFER_SIZE); | 838 | fill_buffer(last_sectors, buffer, BUFFER_SIZE); |
856 | } | 839 | } |
857 | 840 | ||
858 | #ifdef HAVE_LCD_BITMAP | ||
859 | static void init_need_scrollbar(void) { | 841 | static void init_need_scrollbar(void) { |
860 | /* Call viewer_draw in quiet mode to initialize next_screen_ptr, | 842 | /* Call viewer_draw in quiet mode to initialize next_screen_ptr, |
861 | and thus ONE_SCREEN_FITS_ALL(), and thus NEED_SCROLLBAR() */ | 843 | and thus ONE_SCREEN_FITS_ALL(), and thus NEED_SCROLLBAR() */ |
862 | viewer_draw(-1); | 844 | viewer_draw(-1); |
863 | need_scrollbar = NEED_SCROLLBAR(); | 845 | prefs.need_scrollbar = NEED_SCROLLBAR(); |
864 | draw_columns = need_scrollbar? display_columns-glyph_width['o'] : display_columns; | 846 | draw_columns = prefs.need_scrollbar? display_columns-glyph_width['o'] : display_columns; |
865 | par_indent_spaces = draw_columns/(5*glyph_width[' ']); | 847 | par_indent_spaces = draw_columns/(5*glyph_width[' ']); |
866 | } | 848 | } |
867 | #else | 849 | #else |
@@ -875,6 +857,7 @@ static bool viewer_init(void) | |||
875 | struct font *pf; | 857 | struct font *pf; |
876 | 858 | ||
877 | pf = rb->font_get(FONT_UI); | 859 | pf = rb->font_get(FONT_UI); |
860 | |||
878 | if (pf->width != NULL) | 861 | if (pf->width != NULL) |
879 | { /* variable pitch font -- fill structure from font width data */ | 862 | { /* variable pitch font -- fill structure from font width data */ |
880 | ch = pf->defaultchar - pf->firstchar; | 863 | ch = pf->defaultchar - pf->firstchar; |
@@ -896,18 +879,6 @@ static bool viewer_init(void) | |||
896 | par_indent_spaces = 2; | 879 | par_indent_spaces = 2; |
897 | rb->memset(glyph_width, 1, 256); | 880 | rb->memset(glyph_width, 1, 256); |
898 | #endif | 881 | #endif |
899 | /********************* | ||
900 | * (Could re-initialize settings here, if you | ||
901 | * wanted viewer to start the same way every time) | ||
902 | word_mode = WRAP; | ||
903 | line_mode = NORMAL; | ||
904 | view_mode = NARROW; | ||
905 | #ifdef HAVE_LCD_BITMAP | ||
906 | page_mode = NO_OVERLAP; | ||
907 | scrollbar_mode[NARROW] = SB_OFF; | ||
908 | scrollbar_mode[WIDE] = SB_ON; | ||
909 | #endif | ||
910 | **********************/ | ||
911 | 882 | ||
912 | fd = rb->open(file_name, O_RDONLY); | 883 | fd = rb->open(file_name, O_RDONLY); |
913 | if (fd==-1) | 884 | if (fd==-1) |
@@ -924,118 +895,63 @@ static bool viewer_init(void) | |||
924 | init file_pos, buffer_end, screen_top_ptr */ | 895 | init file_pos, buffer_end, screen_top_ptr */ |
925 | viewer_top(); | 896 | viewer_top(); |
926 | 897 | ||
927 | /* Init need_scrollbar value */ | 898 | /* Init prefs.need_scrollbar value */ |
928 | init_need_scrollbar(); | 899 | init_need_scrollbar(); |
929 | 900 | ||
930 | return true; | 901 | return true; |
931 | } | 902 | } |
932 | 903 | ||
933 | /* in the viewer settings file, the line format is: | 904 | static void viewer_reset_settings(void) |
934 | * - file name (variable length) | 905 | { |
935 | * - settings (fixed length strings appended, EOL included) | 906 | prefs.word_mode = WRAP; |
936 | */ | 907 | prefs.line_mode = NORMAL; |
937 | typedef struct { | 908 | prefs.view_mode = NARROW; |
938 | char word_mode[2], line_mode[2], view_mode[2]; | 909 | prefs.scroll_mode = PAGE; |
939 | char file_pos[11], screen_top_ptr[11]; | ||
940 | #ifdef HAVE_LCD_BITMAP | 910 | #ifdef HAVE_LCD_BITMAP |
941 | char scrollbar_mode[VIEW_MODES][2], page_mode[2]; | 911 | prefs.page_mode = NO_OVERLAP; |
912 | prefs.scrollbar_mode = SB_OFF; | ||
942 | #endif | 913 | #endif |
943 | char EOL; | 914 | } |
944 | } viewer_settings_string; | ||
945 | 915 | ||
946 | static void viewer_load_settings(void) | 916 | static void viewer_load_settings(void) /* same name as global, but not the same file.. */ |
947 | { | 917 | { |
948 | int settings_fd, file_name_len, req_line_len, line_len; | 918 | int settings_fd; |
949 | char line[1024]; | ||
950 | 919 | ||
951 | settings_fd=rb->open(SETTINGS_FILE, O_RDONLY); | 920 | settings_fd=rb->open(SETTINGS_FILE, O_RDONLY); |
952 | if (settings_fd < 0) return; | 921 | if (settings_fd < 0) |
953 | 922 | { | |
954 | file_name_len = rb->strlen(file_name); | 923 | rb->splash(HZ*2, true, "No Settings File"); |
955 | req_line_len = file_name_len + sizeof(viewer_settings_string); | 924 | return; |
956 | while ((line_len = rb->read_line(settings_fd, line, sizeof(line))) > 0) { | 925 | } |
957 | if ((line_len == req_line_len) && | 926 | if (rb->filesize(settings_fd) != sizeof(struct preferences)) |
958 | (rb->strncasecmp(line, file_name, file_name_len) == 0)) { | 927 | { |
959 | /* found a match, load stored values */ | 928 | rb->splash(HZ*2, true, "Settings File Invalid"); |
960 | viewer_settings_string *prefs = (void*) &line[file_name_len]; | 929 | return; |
930 | } | ||
961 | 931 | ||
962 | #ifdef HAVE_LCD_BITMAP | 932 | rb->read(settings_fd, &prefs, sizeof(struct preferences)); |
963 | /* view mode will be initialized later anyways */ | 933 | rb->close(settings_fd); |
964 | for (view_mode=0; view_mode<VIEW_MODES; ++view_mode) | ||
965 | scrollbar_mode[view_mode] = | ||
966 | rb->atoi(prefs->scrollbar_mode[view_mode]); | ||
967 | 934 | ||
968 | page_mode = rb->atoi(prefs->page_mode); | 935 | init_need_scrollbar(); |
969 | #endif | ||
970 | 936 | ||
971 | word_mode = rb->atoi(prefs->word_mode); | 937 | file_pos=0; |
972 | line_mode = rb->atoi(prefs->line_mode); | 938 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ |
973 | view_mode = rb->atoi(prefs->view_mode); | ||
974 | |||
975 | init_need_scrollbar(); | ||
976 | /* the following settings are safety checked | ||
977 | * (file may have changed on disk) | ||
978 | */ | ||
979 | file_pos = rb->atoi(prefs->file_pos); /* should be atol() */ | ||
980 | if (file_pos > file_size) { | ||
981 | file_pos = 0; | ||
982 | break; | ||
983 | } | ||
984 | buffer_end = BUFFER_END(); /* Update whenever file_pos changes */ | ||
985 | 939 | ||
986 | screen_top_ptr = buffer + rb->atoi(prefs->screen_top_ptr); | 940 | screen_top_ptr = buffer; |
987 | if (BUFFER_OOB(screen_top_ptr)) { | 941 | if (BUFFER_OOB(screen_top_ptr)) { |
988 | screen_top_ptr = buffer; | 942 | screen_top_ptr = buffer; |
989 | break; | ||
990 | } | ||
991 | } | ||
992 | } | 943 | } |
993 | rb->close(settings_fd); | ||
994 | 944 | ||
995 | fill_buffer(file_pos, buffer, BUFFER_SIZE); | 945 | fill_buffer(file_pos, buffer, BUFFER_SIZE); |
996 | } | 946 | } |
997 | 947 | ||
998 | static void viewer_save_settings(void) | 948 | static void viewer_save_settings(void)/* same name as global, but not the same file.. */ |
999 | { | 949 | { |
1000 | int settings_fd, file_name_len, req_line_len, line_len; | 950 | int settings_fd; |
1001 | char line[1024]; | ||
1002 | viewer_settings_string prefs; | ||
1003 | |||
1004 | settings_fd=rb->open(SETTINGS_FILE, O_RDWR | O_CREAT); | ||
1005 | DEBUGF("SETTINGS_FILE: %d\n", settings_fd); | ||
1006 | if (settings_fd < 0) return; | ||
1007 | |||
1008 | file_name_len = rb->strlen(file_name); | ||
1009 | req_line_len = file_name_len + sizeof(viewer_settings_string); | ||
1010 | while ((line_len = rb->read_line(settings_fd, line, sizeof(line))) > 0) { | ||
1011 | if ((line_len == req_line_len) && | ||
1012 | (rb->strncasecmp(line, file_name, file_name_len) == 0)) { | ||
1013 | /* found a match, reposition file pointer to overwrite this line */ | ||
1014 | rb->lseek(settings_fd, -line_len, SEEK_CUR); | ||
1015 | break; | ||
1016 | } | ||
1017 | } | ||
1018 | 951 | ||
1019 | /* fill structure in order to prevent overwriting with 0s (snprintf | 952 | settings_fd = rb->creat(SETTINGS_FILE, O_WRONLY); /* create the settings file */ |
1020 | * intentionally overflows so that no terminating NULLs are written | ||
1021 | * to disk). */ | ||
1022 | rb->snprintf(prefs.word_mode, 3, "%2d", word_mode); | ||
1023 | rb->snprintf(prefs.line_mode, 3, "%2d", line_mode); | ||
1024 | rb->snprintf(prefs.view_mode, 3, "%2d", view_mode); | ||
1025 | rb->snprintf(prefs.file_pos, 12, "%11d", file_pos); | ||
1026 | rb->snprintf(prefs.screen_top_ptr, 12, "%11d", screen_top_ptr-buffer); | ||
1027 | #ifdef HAVE_LCD_BITMAP | ||
1028 | /* view_mode is not needed anymore */ | ||
1029 | for (view_mode=0; view_mode<VIEW_MODES; ++view_mode) | ||
1030 | rb->snprintf(prefs.scrollbar_mode[view_mode], 3, | ||
1031 | "%2d", scrollbar_mode[view_mode]); | ||
1032 | |||
1033 | rb->snprintf(prefs.page_mode, 3, "%2d", page_mode); | ||
1034 | #endif | ||
1035 | prefs.EOL = '\n'; | ||
1036 | 953 | ||
1037 | rb->write(settings_fd, file_name, file_name_len); | 954 | rb->write (settings_fd, &prefs, sizeof(struct preferences)); |
1038 | rb->write(settings_fd, &prefs, sizeof(prefs)); | ||
1039 | rb->close(settings_fd); | 955 | rb->close(settings_fd); |
1040 | } | 956 | } |
1041 | 957 | ||
@@ -1047,6 +963,7 @@ static void viewer_exit(void *parameter) | |||
1047 | rb->close(fd); | 963 | rb->close(fd); |
1048 | } | 964 | } |
1049 | 965 | ||
966 | #ifdef HAVE_LCD_BITMAP | ||
1050 | static int col_limit(int col) | 967 | static int col_limit(int col) |
1051 | { | 968 | { |
1052 | if (col < 0) | 969 | if (col < 0) |
@@ -1057,45 +974,155 @@ static int col_limit(int col) | |||
1057 | 974 | ||
1058 | return col; | 975 | return col; |
1059 | } | 976 | } |
977 | #endif | ||
1060 | 978 | ||
979 | static void change_options_menu(void) | ||
980 | { | ||
981 | int m, result; | ||
982 | bool done = false; | ||
983 | |||
984 | static const struct menu_item items[] = { | ||
985 | {"Word Wrap", NULL }, | ||
986 | {"Line Mode", NULL }, | ||
987 | {"Wide View", NULL }, | ||
988 | {"Overlap Pages", NULL }, | ||
989 | {"Scroll Mode", NULL}, | ||
990 | #ifdef HAVE_LCD_BITMAP | ||
991 | {"Show Scrollbar", NULL }, | ||
992 | #endif | ||
993 | {"Auto-Scroll Speed", NULL }, | ||
994 | }; | ||
995 | static const struct opt_items opt_word_mode[2] = { | ||
996 | {"On",NULL},{"Off (Chop Words)",NULL}, | ||
997 | }; | ||
998 | #ifdef HAVE_LCD_BITMAP | ||
999 | static const struct opt_items opt_line_mode[4] = { | ||
1000 | {"Normal",NULL},{"Join Lines",NULL}, | ||
1001 | {"Reflow Lines",NULL},{"Expand Lines",NULL}, | ||
1002 | #else | ||
1003 | static const struct opt_items opt_line_mode[3] = { | ||
1004 | {"Normal",NULL},{"Join Lines",NULL}, | ||
1005 | {"Expand Lines",NULL}, | ||
1006 | #endif | ||
1007 | }; | ||
1008 | static const struct opt_items opt_view_mode[2] = { | ||
1009 | {"No (Narrow)",NULL},{"Yes",NULL} | ||
1010 | }; | ||
1011 | static const struct opt_items opt_scroll_mode[2] = { | ||
1012 | {"Scroll by Page",NULL},{"Scroll by Line",NULL} | ||
1013 | }; | ||
1014 | #ifdef HAVE_LCD_BITMAP | ||
1015 | static const struct opt_items opt_scrollbar_mode[2] = { | ||
1016 | {"Off",NULL},{"On",NULL} | ||
1017 | }; | ||
1018 | static const struct opt_items opt_page_mode[2] = { | ||
1019 | {"No",NULL},{"Yes",NULL} | ||
1020 | }; | ||
1021 | #endif | ||
1022 | static const struct opt_items opt_autoscroll_speed[10] = { | ||
1023 | { "1", NULL },{ "2", NULL },{ "3", NULL },{ "4", NULL },{ "5", NULL }, | ||
1024 | { "6", NULL },{ "7", NULL },{ "8", NULL },{ "9", NULL },{ "10", NULL } | ||
1025 | }; | ||
1026 | m = rb->menu_init(items, sizeof(items) / sizeof(*items), | ||
1027 | NULL, NULL, NULL, NULL); | ||
1028 | |||
1029 | while(!done) | ||
1030 | { | ||
1031 | result=rb->menu_show(m); | ||
1032 | switch (result) | ||
1033 | { | ||
1034 | case MENU_SELECTED_EXIT: | ||
1035 | done = true; | ||
1036 | break; | ||
1061 | 1037 | ||
1062 | bool done=false; | 1038 | case 0: /* word mode */ |
1063 | int col = 0; | 1039 | rb->set_option("Word Wrap", &prefs.word_mode, INT, |
1040 | opt_word_mode , 2, NULL); | ||
1041 | break; | ||
1042 | case 1: /* line mode */ | ||
1043 | rb->set_option("Line Mode", &prefs.line_mode, INT, opt_line_mode, | ||
1044 | sizeof(opt_line_mode) / sizeof(*opt_line_mode), NULL); | ||
1045 | break; | ||
1046 | case 2: /* view mode */ | ||
1047 | rb->set_option("Wide View", &prefs.view_mode, INT, | ||
1048 | opt_view_mode , 2, NULL); | ||
1049 | break; | ||
1050 | #ifdef HAVE_LCD_BITMAP | ||
1051 | case 3: | ||
1052 | rb->set_option("Overlap Pages", &prefs.page_mode, INT, | ||
1053 | opt_page_mode , 2, NULL); | ||
1054 | break; | ||
1055 | #endif | ||
1056 | case 4: | ||
1057 | rb->set_option("Scroll Mode", &prefs.scroll_mode, INT, | ||
1058 | opt_scroll_mode , 2, NULL); | ||
1059 | break; | ||
1060 | #ifdef HAVE_LCD_BITMAP | ||
1061 | case 5: | ||
1062 | rb->set_option("Show Scrollbar", &prefs.scrollbar_mode, INT, | ||
1063 | opt_scrollbar_mode , 2, NULL); | ||
1064 | /* Show-scrollbar mode for current view-width mode */ | ||
1065 | if (!(ONE_SCREEN_FITS_ALL())) { | ||
1066 | if (prefs.scrollbar_mode == true) | ||
1067 | init_need_scrollbar(); | ||
1068 | } | ||
1069 | break; | ||
1070 | #endif | ||
1071 | case 6: | ||
1072 | rb->set_option("Auto-Scroll Speed", &prefs.autoscroll_speed, INT, | ||
1073 | opt_autoscroll_speed, sizeof(opt_autoscroll_speed) / | ||
1074 | sizeof(*opt_autoscroll_speed), NULL); | ||
1075 | break; | ||
1076 | } /* switch() */ | ||
1077 | } | ||
1078 | rb->menu_exit(m); | ||
1079 | #ifdef HAVE_LCD_BITMAP | ||
1080 | rb->lcd_setmargins(0,0); | ||
1081 | #endif | ||
1082 | } | ||
1064 | 1083 | ||
1065 | static void show_menu(void) | 1084 | static void show_menu(void) |
1066 | { | 1085 | { |
1067 | int m; | 1086 | int m; |
1068 | int result; | 1087 | int result; |
1069 | static const struct menu_item items[] = { | 1088 | static const struct menu_item items[] = { |
1070 | {"Quit", NULL }, | 1089 | {"Quit", NULL }, |
1071 | {"Show Playback menu", NULL }, | 1090 | {"Viewer Options", NULL }, |
1072 | {"Return", NULL }, | 1091 | {"Show Playback Menu", NULL }, |
1073 | }; | 1092 | {"Return", NULL }, |
1074 | m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); | 1093 | }; |
1075 | result=rb->menu_show(m); | 1094 | |
1076 | switch (result) | 1095 | m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); |
1077 | { | 1096 | result=rb->menu_show(m); |
1078 | case 0: | 1097 | switch (result) |
1079 | viewer_exit(NULL); | 1098 | { |
1080 | done = true; | 1099 | case 0: /* quit */ |
1081 | break; | 1100 | rb->splash(1, true, "Saving Settings"); |
1082 | case 1: | 1101 | rb->menu_exit(m); |
1083 | playback_control(rb); | 1102 | viewer_exit(NULL); |
1084 | break; | 1103 | done = true; |
1085 | case 2: | 1104 | break; |
1086 | rb->menu_exit(m); | 1105 | case 1: /* change settings */ |
1087 | viewer_draw(col); | 1106 | change_options_menu(); |
1088 | break; | 1107 | break; |
1089 | } | 1108 | case 2: /* playback control */ |
1090 | viewer_draw(col); | 1109 | playback_control(rb); |
1091 | } | 1110 | break; |
1111 | case 3: /* return */ | ||
1112 | break; | ||
1113 | } | ||
1114 | rb->menu_exit(m); | ||
1115 | #ifdef HAVE_LCD_BITMAP | ||
1116 | rb->lcd_setmargins(0,0); | ||
1117 | #endif | ||
1118 | viewer_draw(col); | ||
1119 | } | ||
1092 | 1120 | ||
1093 | enum plugin_status plugin_start(struct plugin_api* api, void* file) | 1121 | enum plugin_status plugin_start(struct plugin_api* api, void* file) |
1094 | { | 1122 | { |
1095 | 1123 | int button, i, ok; | |
1096 | int button; | 1124 | bool autoscroll = false; |
1097 | int i; | 1125 | int old_tick = *rb->current_tick; |
1098 | int ok; | ||
1099 | 1126 | ||
1100 | rb = api; | 1127 | rb = api; |
1101 | 1128 | ||
@@ -1110,177 +1137,97 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
1110 | return PLUGIN_OK; | 1137 | return PLUGIN_OK; |
1111 | } | 1138 | } |
1112 | 1139 | ||
1113 | viewer_load_settings(); | 1140 | viewer_reset_settings(); /* load defaults first */ |
1141 | viewer_load_settings(); /* .. then try to load from disk */ | ||
1114 | 1142 | ||
1115 | viewer_draw(col); | 1143 | viewer_draw(col); |
1116 | 1144 | ||
1117 | while (!done) { | 1145 | while (!done) { |
1118 | button = rb->button_get(true); | ||
1119 | switch (button) { | ||
1120 | case VIEWER_MENU: | ||
1121 | show_menu(); | ||
1122 | break; | ||
1123 | |||
1124 | case VIEWER_MODE_WRAP: | ||
1125 | /* Word-wrap mode: WRAP or CHOP */ | ||
1126 | if (++word_mode == WORD_MODES) | ||
1127 | word_mode = 0; | ||
1128 | |||
1129 | init_need_scrollbar(); | ||
1130 | 1146 | ||
1147 | if(autoscroll) | ||
1148 | { | ||
1149 | if(old_tick <= *rb->current_tick - (110-prefs.autoscroll_speed*10)) | ||
1150 | { | ||
1151 | viewer_scroll_down(); | ||
1131 | viewer_draw(col); | 1152 | viewer_draw(col); |
1153 | old_tick = *rb->current_tick; | ||
1154 | } | ||
1155 | } | ||
1132 | 1156 | ||
1133 | rb->splash(HZ, true, "%s %s", | 1157 | button = rb->button_get_w_tmo(HZ/10); |
1134 | word_mode_str[word_mode], | 1158 | switch (button) { |
1135 | word_mode_str[WORD_MODES]); | 1159 | case VIEWER_MENU: |
1136 | 1160 | show_menu(); | |
1137 | viewer_draw(col); | ||
1138 | break; | 1161 | break; |
1139 | 1162 | ||
1140 | case VIEWER_MODE_LINE: | 1163 | case VIEWER_AUTOSCROLL: |
1141 | /* Line-paragraph mode: NORMAL, JOIN, REFLOW or EXPAND */ | 1164 | autoscroll = !autoscroll; |
1142 | if (++line_mode == LINE_MODES) | ||
1143 | line_mode = 0; | ||
1144 | |||
1145 | if (view_mode == WIDE) { | ||
1146 | if (line_mode == JOIN) | ||
1147 | if (++line_mode == LINE_MODES) | ||
1148 | line_mode = 0; | ||
1149 | if (line_mode == REFLOW) | ||
1150 | if (++line_mode == LINE_MODES) | ||
1151 | line_mode = 0; | ||
1152 | } | ||
1153 | |||
1154 | init_need_scrollbar(); | ||
1155 | |||
1156 | viewer_draw(col); | ||
1157 | |||
1158 | rb->splash(HZ, true, "%s %s", | ||
1159 | line_mode_str[line_mode], | ||
1160 | line_mode_str[LINE_MODES]); | ||
1161 | |||
1162 | viewer_draw(col); | ||
1163 | break; | ||
1164 | |||
1165 | case VIEWER_MODE_WIDTH: | ||
1166 | /* View-width mode: NARROW or WIDE */ | ||
1167 | if ((line_mode == JOIN) || (line_mode == REFLOW)) | ||
1168 | rb->splash(HZ, true, "(no %s %s)", | ||
1169 | view_mode_str[WIDE], | ||
1170 | line_mode_str[line_mode]); | ||
1171 | else | ||
1172 | if (++view_mode == VIEW_MODES) | ||
1173 | view_mode = 0; | ||
1174 | |||
1175 | col = 0; | ||
1176 | |||
1177 | /***** Could do this after change of word-wrap mode | ||
1178 | * and after change of view-width mode, to normalize | ||
1179 | * view: | ||
1180 | if (screen_top_ptr > buffer + BUFFER_SIZE/2) { | ||
1181 | screen_top_ptr = find_prev_line(screen_top_ptr); | ||
1182 | screen_top_ptr = find_next_line(screen_top_ptr); | ||
1183 | } | ||
1184 | else { | ||
1185 | screen_top_ptr = find_next_line(screen_top_ptr); | ||
1186 | screen_top_ptr = find_prev_line(screen_top_ptr); | ||
1187 | } | ||
1188 | ***********/ | ||
1189 | |||
1190 | init_need_scrollbar(); | ||
1191 | |||
1192 | viewer_draw(col); | ||
1193 | |||
1194 | rb->splash(HZ, true, "%s %s", | ||
1195 | view_mode_str[view_mode], | ||
1196 | view_mode_str[VIEW_MODES]); | ||
1197 | |||
1198 | viewer_draw(col); | ||
1199 | break; | 1165 | break; |
1200 | 1166 | ||
1201 | case VIEWER_PAGE_UP: | 1167 | case VIEWER_PAGE_UP: |
1202 | case VIEWER_PAGE_UP | BUTTON_REPEAT: | 1168 | case VIEWER_PAGE_UP | BUTTON_REPEAT: |
1203 | /* Page up */ | 1169 | if (prefs.scroll_mode == PAGE) |
1170 | { | ||
1171 | /* Page up */ | ||
1204 | #ifdef HAVE_LCD_BITMAP | 1172 | #ifdef HAVE_LCD_BITMAP |
1205 | for (i = page_mode==OVERLAP? 1:0; i < display_lines; i++) | 1173 | for (i = prefs.page_mode==OVERLAP? 1:0; i < display_lines; i++) |
1206 | #else | 1174 | #else |
1207 | for (i = 0; i < display_lines; i++) | 1175 | for (i = 0; i < display_lines; i++) |
1208 | #endif | 1176 | #endif |
1177 | viewer_scroll_up(); | ||
1178 | } | ||
1179 | else | ||
1209 | viewer_scroll_up(); | 1180 | viewer_scroll_up(); |
1210 | 1181 | old_tick = *rb->current_tick; | |
1211 | viewer_draw(col); | 1182 | viewer_draw(col); |
1212 | break; | 1183 | break; |
1213 | 1184 | ||
1214 | case VIEWER_PAGE_DOWN: | 1185 | case VIEWER_PAGE_DOWN: |
1215 | case VIEWER_PAGE_DOWN | BUTTON_REPEAT: | 1186 | case VIEWER_PAGE_DOWN | BUTTON_REPEAT: |
1216 | /* Page down */ | 1187 | if (prefs.scroll_mode == PAGE) |
1217 | if (next_screen_ptr != NULL) | 1188 | { |
1218 | screen_top_ptr = next_screen_to_draw_ptr; | 1189 | /* Page down */ |
1219 | 1190 | if (next_screen_ptr != NULL) | |
1191 | screen_top_ptr = next_screen_to_draw_ptr; | ||
1192 | } | ||
1193 | else | ||
1194 | viewer_scroll_down(); | ||
1195 | old_tick = *rb->current_tick; | ||
1220 | viewer_draw(col); | 1196 | viewer_draw(col); |
1221 | break; | 1197 | break; |
1222 | 1198 | ||
1199 | #ifdef VIEWER_SCREEN_LEFT | ||
1223 | case VIEWER_SCREEN_LEFT: | 1200 | case VIEWER_SCREEN_LEFT: |
1224 | case VIEWER_SCREEN_LEFT | BUTTON_REPEAT: | 1201 | case VIEWER_SCREEN_LEFT | BUTTON_REPEAT: |
1225 | if (view_mode == WIDE) { | 1202 | if (prefs.view_mode == WIDE) { |
1226 | /* Screen left */ | 1203 | /* Screen left */ |
1227 | col -= draw_columns/glyph_width['o']; | 1204 | col -= draw_columns/glyph_width['o']; |
1228 | col = col_limit(col); | 1205 | col = col_limit(col); |
1229 | } | 1206 | } |
1230 | else { /* view_mode == NARROW */ | 1207 | else { /* prefs.view_mode == NARROW */ |
1231 | /* Top of file */ | 1208 | /* Top of file */ |
1232 | viewer_top(); | 1209 | viewer_top(); |
1233 | } | 1210 | } |
1234 | 1211 | ||
1235 | viewer_draw(col); | 1212 | viewer_draw(col); |
1236 | break; | 1213 | break; |
1214 | #endif | ||
1237 | 1215 | ||
1216 | #ifdef VIEWER_SCREEN_LEFT | ||
1238 | case VIEWER_SCREEN_RIGHT: | 1217 | case VIEWER_SCREEN_RIGHT: |
1239 | case VIEWER_SCREEN_RIGHT | BUTTON_REPEAT: | 1218 | case VIEWER_SCREEN_RIGHT | BUTTON_REPEAT: |
1240 | if (view_mode == WIDE) { | 1219 | if (prefs.view_mode == WIDE) { |
1241 | /* Screen right */ | 1220 | /* Screen right */ |
1242 | col += draw_columns/glyph_width['o']; | 1221 | col += draw_columns/glyph_width['o']; |
1243 | col = col_limit(col); | 1222 | col = col_limit(col); |
1244 | } | 1223 | } |
1245 | else { /* view_mode == NARROW */ | 1224 | else { /* prefs.view_mode == NARROW */ |
1246 | /* Bottom of file */ | 1225 | /* Bottom of file */ |
1247 | viewer_bottom(); | 1226 | viewer_bottom(); |
1248 | } | 1227 | } |
1249 | 1228 | ||
1250 | viewer_draw(col); | 1229 | viewer_draw(col); |
1251 | break; | 1230 | break; |
1252 | |||
1253 | #ifdef VIEWER_MODE_PAGE | ||
1254 | case VIEWER_MODE_PAGE: | ||
1255 | /* Page-overlap mode */ | ||
1256 | if (++page_mode == PAGE_MODES) | ||
1257 | page_mode = 0; | ||
1258 | |||
1259 | rb->splash(HZ, true, "%s %s", | ||
1260 | page_mode_str[page_mode], | ||
1261 | page_mode_str[PAGE_MODES]); | ||
1262 | |||
1263 | viewer_draw(col); | ||
1264 | break; | ||
1265 | #endif | ||
1266 | #ifdef VIEWER_MODE_SCROLLBAR | ||
1267 | case VIEWER_MODE_SCROLLBAR: | ||
1268 | /* Show-scrollbar mode for current view-width mode */ | ||
1269 | if (!(ONE_SCREEN_FITS_ALL())) { | ||
1270 | if (++scrollbar_mode[view_mode] == SCROLLBAR_MODES) | ||
1271 | scrollbar_mode[view_mode] = 0; | ||
1272 | |||
1273 | init_need_scrollbar(); | ||
1274 | viewer_draw(col); | ||
1275 | |||
1276 | rb->splash(HZ, true, "%s %s (%s %s)", | ||
1277 | scrollbar_mode_str[SCROLLBAR_MODES], | ||
1278 | scrollbar_mode_str[scrollbar_mode[view_mode]], | ||
1279 | view_mode_str[view_mode], | ||
1280 | view_mode_str[VIEW_MODES]); | ||
1281 | } | ||
1282 | viewer_draw(col); | ||
1283 | break; | ||
1284 | #endif | 1231 | #endif |
1285 | 1232 | ||
1286 | #ifdef VIEWER_LINE_UP | 1233 | #ifdef VIEWER_LINE_UP |
@@ -1288,6 +1235,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
1288 | case VIEWER_LINE_UP | BUTTON_REPEAT: | 1235 | case VIEWER_LINE_UP | BUTTON_REPEAT: |
1289 | /* Scroll up one line */ | 1236 | /* Scroll up one line */ |
1290 | viewer_scroll_up(); | 1237 | viewer_scroll_up(); |
1238 | old_tick = *rb->current_tick; | ||
1291 | viewer_draw(col); | 1239 | viewer_draw(col); |
1292 | break; | 1240 | break; |
1293 | 1241 | ||
@@ -1296,7 +1244,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
1296 | /* Scroll down one line */ | 1244 | /* Scroll down one line */ |
1297 | if (next_screen_ptr != NULL) | 1245 | if (next_screen_ptr != NULL) |
1298 | screen_top_ptr = next_line_ptr; | 1246 | screen_top_ptr = next_line_ptr; |
1299 | 1247 | old_tick = *rb->current_tick; | |
1300 | viewer_draw(col); | 1248 | viewer_draw(col); |
1301 | break; | 1249 | break; |
1302 | #endif | 1250 | #endif |
@@ -1317,6 +1265,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* file) | |||
1317 | viewer_draw(col); | 1265 | viewer_draw(col); |
1318 | break; | 1266 | break; |
1319 | #endif | 1267 | #endif |
1268 | case VIEWER_QUIT: | ||
1269 | viewer_exit(NULL); | ||
1270 | done = true; | ||
1271 | break; | ||
1320 | 1272 | ||
1321 | default: | 1273 | default: |
1322 | if (rb->default_event_handler_ex(button, viewer_exit, NULL) | 1274 | if (rb->default_event_handler_ex(button, viewer_exit, NULL) |