Bible eBook Prototype More details at: http://mbed.org/users/davervw/notebook/ebible-abstract/

Dependencies:   SDHCFileSystem TextLCD mbed BibleIO

Committer:
davervw
Date:
Sun Feb 27 18:54:37 2011 +0000
Revision:
0:b9d9145827e2
NXP mbed Design Challenge Entry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davervw 0:b9d9145827e2 1 /* Bible UI Class Implementation - KJV Bible eBook Browser
davervw 0:b9d9145827e2 2 *
davervw 0:b9d9145827e2 3 * Copyright (c) 2011 David R. Van Wagner davervw@yahoo.com
davervw 0:b9d9145827e2 4 *
davervw 0:b9d9145827e2 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
davervw 0:b9d9145827e2 6 * of this software and associated documentation files (the "Software"), to deal
davervw 0:b9d9145827e2 7 * in the Software without restriction, including without limitation the rights
davervw 0:b9d9145827e2 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
davervw 0:b9d9145827e2 9 * copies of the Software, and to permit persons to whom the Software is
davervw 0:b9d9145827e2 10 * furnished to do so, subject to the following conditions:
davervw 0:b9d9145827e2 11 *
davervw 0:b9d9145827e2 12 * The above copyright notice and this permission notice shall be included in
davervw 0:b9d9145827e2 13 * all copies or substantial portions of the Software.
davervw 0:b9d9145827e2 14 *
davervw 0:b9d9145827e2 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
davervw 0:b9d9145827e2 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
davervw 0:b9d9145827e2 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
davervw 0:b9d9145827e2 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
davervw 0:b9d9145827e2 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
davervw 0:b9d9145827e2 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
davervw 0:b9d9145827e2 21 * THE SOFTWARE.
davervw 0:b9d9145827e2 22 */
davervw 0:b9d9145827e2 23
davervw 0:b9d9145827e2 24 #include "BibleUI.h"
davervw 0:b9d9145827e2 25
davervw 0:b9d9145827e2 26 //extern Serial console;
davervw 0:b9d9145827e2 27
davervw 0:b9d9145827e2 28 BibleUI::BibleUI(BibleIO &bible, TextLCD &textlcd, DigitalIn& left, DigitalIn& right)
davervw 0:b9d9145827e2 29 :HolyBible(bible), lcd(textlcd), lb(left), rb(right), led1(LED1), led2(LED2), led3(LED3), led4(LED4)
davervw 0:b9d9145827e2 30 {
davervw 0:b9d9145827e2 31 //console.printf("\n\n" "Bible LCD\n\n");
davervw 0:b9d9145827e2 32 lcd.cls();
davervw 0:b9d9145827e2 33 lcd.printf("BibleLCD");
davervw 0:b9d9145827e2 34
davervw 0:b9d9145827e2 35 wait(0.5);
davervw 0:b9d9145827e2 36
davervw 0:b9d9145827e2 37 show_title();
davervw 0:b9d9145827e2 38
davervw 0:b9d9145827e2 39 book = 0;
davervw 0:b9d9145827e2 40 chapter = 0;
davervw 0:b9d9145827e2 41 verse = 0;
davervw 0:b9d9145827e2 42 offset = 0;
davervw 0:b9d9145827e2 43 disp_len = 0;
davervw 0:b9d9145827e2 44 }
davervw 0:b9d9145827e2 45
davervw 0:b9d9145827e2 46 void BibleUI::start()
davervw 0:b9d9145827e2 47 {
davervw 0:b9d9145827e2 48 main();
davervw 0:b9d9145827e2 49 }
davervw 0:b9d9145827e2 50
davervw 0:b9d9145827e2 51 void BibleUI::display_nav()
davervw 0:b9d9145827e2 52 {
davervw 0:b9d9145827e2 53 lcd.cls();
davervw 0:b9d9145827e2 54 char* book_name = HolyBible.title_book(book);
davervw 0:b9d9145827e2 55 if (strlen(book_name) >= lcd.columns())
davervw 0:b9d9145827e2 56 book_name[lcd.columns()] = 0;
davervw 0:b9d9145827e2 57 lcd.printf("%s%s%d:%d", book_name, strlen(book_name)==lcd.columns()?"":"\n", chapter+1, verse+1);
davervw 0:b9d9145827e2 58 //console.printf("%s %d:%d", abbrev, chapter+1, verse+1);
davervw 0:b9d9145827e2 59 delete [] book_name;
davervw 0:b9d9145827e2 60 }
davervw 0:b9d9145827e2 61
davervw 0:b9d9145827e2 62 bool BibleUI::append_next_verse(char*& text, short len, short book, short chapter, short verse)
davervw 0:b9d9145827e2 63 {
davervw 0:b9d9145827e2 64 int size = 0;
davervw 0:b9d9145827e2 65 do
davervw 0:b9d9145827e2 66 {
davervw 0:b9d9145827e2 67 // get next verse
davervw 0:b9d9145827e2 68 char* next_verse = HolyBible.text_verse(book, chapter, ++verse);
davervw 0:b9d9145827e2 69 if (next_verse == 0)
davervw 0:b9d9145827e2 70 return size>0; // stop at end of chapter, return true if text has lengthened at all
davervw 0:b9d9145827e2 71 size += strlen(next_verse);
davervw 0:b9d9145827e2 72
davervw 0:b9d9145827e2 73 // combine
davervw 0:b9d9145827e2 74 char* new_verse = new char[strlen(text)+strlen(next_verse)+2]; // add room for space delimiter and nul
davervw 0:b9d9145827e2 75 strcpy(new_verse, text);
davervw 0:b9d9145827e2 76 strcat(new_verse, " ");
davervw 0:b9d9145827e2 77 strcat(new_verse, next_verse);
davervw 0:b9d9145827e2 78 delete [] text;
davervw 0:b9d9145827e2 79 delete [] next_verse;
davervw 0:b9d9145827e2 80 text = new_verse;
davervw 0:b9d9145827e2 81 } while (size < len); // repeat until enough characters added
davervw 0:b9d9145827e2 82
davervw 0:b9d9145827e2 83 return size>0;
davervw 0:b9d9145827e2 84 }
davervw 0:b9d9145827e2 85
davervw 0:b9d9145827e2 86 void BibleUI::display_verse()
davervw 0:b9d9145827e2 87 {
davervw 0:b9d9145827e2 88 // fix positioning, check ranges
davervw 0:b9d9145827e2 89 char* text = 0;
davervw 0:b9d9145827e2 90 if (offset < 0)
davervw 0:b9d9145827e2 91 {
davervw 0:b9d9145827e2 92 if (offset > -lcd.rows()*lcd.columns())
davervw 0:b9d9145827e2 93 offset = 0; // be sure to show beginning of verse
davervw 0:b9d9145827e2 94 else
davervw 0:b9d9145827e2 95 {
davervw 0:b9d9145827e2 96 if (verse > 0) // previous verse
davervw 0:b9d9145827e2 97 --verse;
davervw 0:b9d9145827e2 98 else
davervw 0:b9d9145827e2 99 {
davervw 0:b9d9145827e2 100 if (chapter > 0) // last verse in previous chapter
davervw 0:b9d9145827e2 101 {
davervw 0:b9d9145827e2 102 --chapter;
davervw 0:b9d9145827e2 103 verse = HolyBible.get_num_verses(book, chapter)-1;
davervw 0:b9d9145827e2 104 }
davervw 0:b9d9145827e2 105 else if (book > 0) // last verse in previous book
davervw 0:b9d9145827e2 106 {
davervw 0:b9d9145827e2 107 --book;
davervw 0:b9d9145827e2 108 chapter = HolyBible.get_num_chapters(book)-1;
davervw 0:b9d9145827e2 109 verse = HolyBible.get_num_verses(book, chapter)-1;
davervw 0:b9d9145827e2 110 }
davervw 0:b9d9145827e2 111 else //end of bible
davervw 0:b9d9145827e2 112 {
davervw 0:b9d9145827e2 113 book = HolyBible.get_num_books() - 1;
davervw 0:b9d9145827e2 114 chapter = HolyBible.get_num_chapters(book)-1;
davervw 0:b9d9145827e2 115 verse = HolyBible.get_num_verses(book, chapter)-1;
davervw 0:b9d9145827e2 116 }
davervw 0:b9d9145827e2 117 display_nav();
davervw 0:b9d9145827e2 118 wait(0.5);
davervw 0:b9d9145827e2 119 }
davervw 0:b9d9145827e2 120 }
davervw 0:b9d9145827e2 121 text = HolyBible.text_verse(book, chapter, verse);
davervw 0:b9d9145827e2 122 if (offset < 0)
davervw 0:b9d9145827e2 123 {
davervw 0:b9d9145827e2 124 int len = strlen(text);
davervw 0:b9d9145827e2 125 if (len > lcd.rows()*lcd.columns())
davervw 0:b9d9145827e2 126 offset = len-lcd.rows()*lcd.columns();
davervw 0:b9d9145827e2 127 else
davervw 0:b9d9145827e2 128 offset = 0;
davervw 0:b9d9145827e2 129 }
davervw 0:b9d9145827e2 130 }
davervw 0:b9d9145827e2 131 else
davervw 0:b9d9145827e2 132 text = HolyBible.text_verse(book, chapter, verse);
davervw 0:b9d9145827e2 133 if (offset == 0)
davervw 0:b9d9145827e2 134 {
davervw 0:b9d9145827e2 135 char* text_start = strchr(text, ' ');
davervw 0:b9d9145827e2 136 //console.printf("%s\n", text_start);
davervw 0:b9d9145827e2 137 }
davervw 0:b9d9145827e2 138 if (offset >= strlen(text))
davervw 0:b9d9145827e2 139 {
davervw 0:b9d9145827e2 140 offset = 0;
davervw 0:b9d9145827e2 141 delete [] text;
davervw 0:b9d9145827e2 142 text = HolyBible.text_verse(book, chapter, ++verse); // next verse
davervw 0:b9d9145827e2 143 if (text == 0)
davervw 0:b9d9145827e2 144 {
davervw 0:b9d9145827e2 145 text = HolyBible.text_verse(book, ++chapter, verse=0); // next chapter
davervw 0:b9d9145827e2 146 if (text == 0)
davervw 0:b9d9145827e2 147 text = HolyBible.text_verse(++book, chapter=0, verse=0); // next book
davervw 0:b9d9145827e2 148 if (text == 0)
davervw 0:b9d9145827e2 149 text = HolyBible.text_verse(book=0, chapter=0, verse=0); // end
davervw 0:b9d9145827e2 150 display_nav();
davervw 0:b9d9145827e2 151 wait(0.5);
davervw 0:b9d9145827e2 152 }
davervw 0:b9d9145827e2 153 }
davervw 0:b9d9145827e2 154
davervw 0:b9d9145827e2 155 // append enough text to fill screen and then some
davervw 0:b9d9145827e2 156 append_next_verse(text, lcd.rows()*(lcd.columns()+1), book, chapter, verse);
davervw 0:b9d9145827e2 157
davervw 0:b9d9145827e2 158 // find current position within verse(s)
davervw 0:b9d9145827e2 159 char* verse_text = text + offset;
davervw 0:b9d9145827e2 160
davervw 0:b9d9145827e2 161 // make a copy starting at offset so it can be modified
davervw 0:b9d9145827e2 162 char* copy = new char[strlen(verse_text)+1];
davervw 0:b9d9145827e2 163 strcpy(copy, verse_text);
davervw 0:b9d9145827e2 164 delete [] text; // note: text was allocated, verse_text was just pointed into it
davervw 0:b9d9145827e2 165 text = 0;
davervw 0:b9d9145827e2 166 verse_text = 0;
davervw 0:b9d9145827e2 167
davervw 0:b9d9145827e2 168 // word wrap
davervw 0:b9d9145827e2 169 disp_len = word_wrap(copy);
davervw 0:b9d9145827e2 170 /*
davervw 0:b9d9145827e2 171 if (strlen(copy) > lcd.rows()*lcd.columns())
davervw 0:b9d9145827e2 172 copy[lcd.rows()*lcd.columns()] = 0;
davervw 0:b9d9145827e2 173 disp_len = strlen(copy);
davervw 0:b9d9145827e2 174 */
davervw 0:b9d9145827e2 175
davervw 0:b9d9145827e2 176 // display
davervw 0:b9d9145827e2 177 lcd.locate(0, 0);
davervw 0:b9d9145827e2 178 lcd.printf("%s", copy);
davervw 0:b9d9145827e2 179
davervw 0:b9d9145827e2 180 // pad with spaces (avoids cls which can cause some flashing)
davervw 0:b9d9145827e2 181 int max_len = lcd.rows()*lcd.columns();
davervw 0:b9d9145827e2 182 for (int i=strlen(copy); i<max_len; ++i)
davervw 0:b9d9145827e2 183 lcd.printf(" ");
davervw 0:b9d9145827e2 184
davervw 0:b9d9145827e2 185 // free up storage
davervw 0:b9d9145827e2 186 delete [] copy;
davervw 0:b9d9145827e2 187 copy = 0;
davervw 0:b9d9145827e2 188 }
davervw 0:b9d9145827e2 189
davervw 0:b9d9145827e2 190 static bool alphanumeric(char c)
davervw 0:b9d9145827e2 191 {
davervw 0:b9d9145827e2 192 return c >= '0' && c <= '9'
davervw 0:b9d9145827e2 193 || c >= 'A' && c <= 'Z'
davervw 0:b9d9145827e2 194 || c >= 'a' && c <= 'z';
davervw 0:b9d9145827e2 195 }
davervw 0:b9d9145827e2 196
davervw 0:b9d9145827e2 197 static bool punc_or_space(char c)
davervw 0:b9d9145827e2 198 {
davervw 0:b9d9145827e2 199 return !alphanumeric(c);
davervw 0:b9d9145827e2 200 }
davervw 0:b9d9145827e2 201
davervw 0:b9d9145827e2 202 int BibleUI::word_wrap(char* &text)
davervw 0:b9d9145827e2 203 {
davervw 0:b9d9145827e2 204 // make copy of original text for later comparison
davervw 0:b9d9145827e2 205 char* orig = new char[strlen(text)+1];
davervw 0:b9d9145827e2 206 strcpy(orig, text);
davervw 0:b9d9145827e2 207
davervw 0:b9d9145827e2 208 // remove unwanted strings
davervw 0:b9d9145827e2 209 remove_string(text, "# ");
davervw 0:b9d9145827e2 210 remove_string(text, "[");
davervw 0:b9d9145827e2 211 remove_string(text, "]");
davervw 0:b9d9145827e2 212
davervw 0:b9d9145827e2 213 // scan each line
davervw 0:b9d9145827e2 214 for (int row=0; row<lcd.rows(); ++row)
davervw 0:b9d9145827e2 215 {
davervw 0:b9d9145827e2 216 int start = row * lcd.columns();
davervw 0:b9d9145827e2 217 int end = start + lcd.columns();
davervw 0:b9d9145827e2 218
davervw 0:b9d9145827e2 219 // remove spaces at start of line
davervw 0:b9d9145827e2 220 while (start < strlen(text) && text[start]==' ')
davervw 0:b9d9145827e2 221 {
davervw 0:b9d9145827e2 222 // delete one character
davervw 0:b9d9145827e2 223 int left = start;
davervw 0:b9d9145827e2 224 int right = strlen(text+left+1);
davervw 0:b9d9145827e2 225 char* new_text = new char[left+right+1];
davervw 0:b9d9145827e2 226 memcpy(new_text, text, left);
davervw 0:b9d9145827e2 227 new_text[left] = 0;
davervw 0:b9d9145827e2 228 strcat(new_text, text+left+1);
davervw 0:b9d9145827e2 229 delete [] text;
davervw 0:b9d9145827e2 230 text = new_text;
davervw 0:b9d9145827e2 231 }
davervw 0:b9d9145827e2 232
davervw 0:b9d9145827e2 233 // insert spaces to wrap words
davervw 0:b9d9145827e2 234 if (strlen(text) > end && !punc_or_space(text[end]))
davervw 0:b9d9145827e2 235 {
davervw 0:b9d9145827e2 236 int left;
davervw 0:b9d9145827e2 237 for (left=end-1; left>=start && !punc_or_space(text[left]); --left)
davervw 0:b9d9145827e2 238 ;
davervw 0:b9d9145827e2 239 if (left > start && left < end)
davervw 0:b9d9145827e2 240 {
davervw 0:b9d9145827e2 241 ++left;
davervw 0:b9d9145827e2 242 int right=strlen(text+left);
davervw 0:b9d9145827e2 243 int spaces=end-left;
davervw 0:b9d9145827e2 244 //printf("row=%d total=%d left=%d spaces=%d right=%d\n", row, strlen(text), left, spaces, right);
davervw 0:b9d9145827e2 245 char* new_text = new char[left+spaces+right+1];
davervw 0:b9d9145827e2 246 memcpy(new_text, text, left);
davervw 0:b9d9145827e2 247 new_text[left] = 0;
davervw 0:b9d9145827e2 248 for (int i=0; i<spaces; ++i)
davervw 0:b9d9145827e2 249 strcat(new_text, " ");
davervw 0:b9d9145827e2 250 strcat(new_text, text+left);
davervw 0:b9d9145827e2 251 delete [] text;
davervw 0:b9d9145827e2 252 text = new_text;
davervw 0:b9d9145827e2 253 }
davervw 0:b9d9145827e2 254 }
davervw 0:b9d9145827e2 255 }
davervw 0:b9d9145827e2 256
davervw 0:b9d9145827e2 257 // truncate to screen size
davervw 0:b9d9145827e2 258 int max_len = lcd.rows()*lcd.columns();
davervw 0:b9d9145827e2 259 if (strlen(text)>=max_len)
davervw 0:b9d9145827e2 260 text[max_len] = 0;
davervw 0:b9d9145827e2 261
davervw 0:b9d9145827e2 262 // make copy with non-spaces
davervw 0:b9d9145827e2 263 char* nospaces = new char[strlen(text)+1];
davervw 0:b9d9145827e2 264 int len = 0;
davervw 0:b9d9145827e2 265 for (int i=0; i<strlen(text); ++i)
davervw 0:b9d9145827e2 266 if (text[i] != ' ')
davervw 0:b9d9145827e2 267 nospaces[len++] = text[i];
davervw 0:b9d9145827e2 268 nospaces[len] = 0;
davervw 0:b9d9145827e2 269
davervw 0:b9d9145827e2 270 // calculate the number of characters displayed
davervw 0:b9d9145827e2 271 int src=0;
davervw 0:b9d9145827e2 272 for (int dest=0; dest<len; ++dest)
davervw 0:b9d9145827e2 273 {
davervw 0:b9d9145827e2 274 // non-space character must be there, advance in original until find it
davervw 0:b9d9145827e2 275 while (orig[src++] != nospaces[dest])
davervw 0:b9d9145827e2 276 ;
davervw 0:b9d9145827e2 277 }
davervw 0:b9d9145827e2 278
davervw 0:b9d9145827e2 279 // free up storage
davervw 0:b9d9145827e2 280 delete [] nospaces;
davervw 0:b9d9145827e2 281 nospaces = 0;
davervw 0:b9d9145827e2 282 delete [] orig;
davervw 0:b9d9145827e2 283 orig = 0;
davervw 0:b9d9145827e2 284
davervw 0:b9d9145827e2 285 // return length of source string that matches wrapped text, so know how to advance to next portion of verse
davervw 0:b9d9145827e2 286 return src;
davervw 0:b9d9145827e2 287 }
davervw 0:b9d9145827e2 288
davervw 0:b9d9145827e2 289 void BibleUI::remove_string(char* &text, char* find)
davervw 0:b9d9145827e2 290 {
davervw 0:b9d9145827e2 291 while (true)
davervw 0:b9d9145827e2 292 {
davervw 0:b9d9145827e2 293 char* p = strstr(text, find);
davervw 0:b9d9145827e2 294 if (p == 0)
davervw 0:b9d9145827e2 295 return;
davervw 0:b9d9145827e2 296 int left = p-text;
davervw 0:b9d9145827e2 297 int right = strlen(p+strlen(find));
davervw 0:b9d9145827e2 298 char* new_text = new char[left+right+1];
davervw 0:b9d9145827e2 299 memcpy(new_text, text, left);
davervw 0:b9d9145827e2 300 new_text[left] = 0;
davervw 0:b9d9145827e2 301 strcat(new_text, p+strlen(find));
davervw 0:b9d9145827e2 302 delete [] text;
davervw 0:b9d9145827e2 303 text = new_text;
davervw 0:b9d9145827e2 304 }
davervw 0:b9d9145827e2 305 }
davervw 0:b9d9145827e2 306
davervw 0:b9d9145827e2 307 void BibleUI::show_title()
davervw 0:b9d9145827e2 308 {
davervw 0:b9d9145827e2 309 lcd.cls();
davervw 0:b9d9145827e2 310 char* title = HolyBible.title();
davervw 0:b9d9145827e2 311 lcd.printf("%s", title);
davervw 0:b9d9145827e2 312 //console.printf("%s\n", title);
davervw 0:b9d9145827e2 313 delete [] title;
davervw 0:b9d9145827e2 314 title = 0;
davervw 0:b9d9145827e2 315 }
davervw 0:b9d9145827e2 316
davervw 0:b9d9145827e2 317 void BibleUI::main()
davervw 0:b9d9145827e2 318 {
davervw 0:b9d9145827e2 319 enum emode { MODE_OFFSET=0, MODE_VERSE=1, MODE_CHAPTER=2, MODE_BOOK=3, MODE_4xBOOK=4, MODE_BOOKMARK=5 };
davervw 0:b9d9145827e2 320
davervw 0:b9d9145827e2 321 emode mode = MODE_OFFSET;
davervw 0:b9d9145827e2 322
davervw 0:b9d9145827e2 323 display_nav();
davervw 0:b9d9145827e2 324 wait(0.5);
davervw 0:b9d9145827e2 325 display_verse();
davervw 0:b9d9145827e2 326
davervw 0:b9d9145827e2 327 // debug: display all text
davervw 0:b9d9145827e2 328 /*
davervw 0:b9d9145827e2 329 int last_book = book;
davervw 0:b9d9145827e2 330 int pages = -1;
davervw 0:b9d9145827e2 331 while (book >= last_book)
davervw 0:b9d9145827e2 332 {
davervw 0:b9d9145827e2 333 ++pages;
davervw 0:b9d9145827e2 334 last_book = book;
davervw 0:b9d9145827e2 335
davervw 0:b9d9145827e2 336 display_verse();
davervw 0:b9d9145827e2 337
davervw 0:b9d9145827e2 338 char* book_name = HolyBible.title_book(book);
davervw 0:b9d9145827e2 339 console.printf("%s %hd:%hd \r", book_name, chapter+1, verse+1);
davervw 0:b9d9145827e2 340 delete [] book_name;
davervw 0:b9d9145827e2 341
davervw 0:b9d9145827e2 342 //wait(0.025);
davervw 0:b9d9145827e2 343 offset += disp_len;
davervw 0:b9d9145827e2 344 }
davervw 0:b9d9145827e2 345 lcd.cls();
davervw 0:b9d9145827e2 346 lcd.printf("%d", pages);
davervw 0:b9d9145827e2 347 return;
davervw 0:b9d9145827e2 348 */
davervw 0:b9d9145827e2 349
davervw 0:b9d9145827e2 350 Timer timer;
davervw 0:b9d9145827e2 351 int old_buttons = 0; // start assuming nothing pressed
davervw 0:b9d9145827e2 352 while (true)
davervw 0:b9d9145827e2 353 {
davervw 0:b9d9145827e2 354 // wait for something to happen
davervw 0:b9d9145827e2 355 int new_buttons = rb + 2*lb;
davervw 0:b9d9145827e2 356 if (new_buttons != old_buttons)
davervw 0:b9d9145827e2 357 {
davervw 0:b9d9145827e2 358 // simple debounce logic, wait for 25ms of steady state else start over
davervw 0:b9d9145827e2 359 bool debounce = false;
davervw 0:b9d9145827e2 360 int buttons = new_buttons;
davervw 0:b9d9145827e2 361 timer.reset();
davervw 0:b9d9145827e2 362 timer.start();
davervw 0:b9d9145827e2 363
davervw 0:b9d9145827e2 364 led1 = lb;
davervw 0:b9d9145827e2 365 led2 = rb;
davervw 0:b9d9145827e2 366
davervw 0:b9d9145827e2 367 while (timer.read_ms() < 25)
davervw 0:b9d9145827e2 368 {
davervw 0:b9d9145827e2 369 int new_buttons = rb + 2*lb;
davervw 0:b9d9145827e2 370 if (new_buttons != buttons)
davervw 0:b9d9145827e2 371 {
davervw 0:b9d9145827e2 372 debounce = false;
davervw 0:b9d9145827e2 373 break;
davervw 0:b9d9145827e2 374 }
davervw 0:b9d9145827e2 375 else
davervw 0:b9d9145827e2 376 debounce = true;
davervw 0:b9d9145827e2 377 }
davervw 0:b9d9145827e2 378 //console.printf("debounce: %d\n", new_buttons);
davervw 0:b9d9145827e2 379
davervw 0:b9d9145827e2 380 if (debounce && new_buttons == 0)
davervw 0:b9d9145827e2 381 {
davervw 0:b9d9145827e2 382 while (true)
davervw 0:b9d9145827e2 383 {
davervw 0:b9d9145827e2 384 int new_buttons = rb + 2*lb;
davervw 0:b9d9145827e2 385 led1 = lb;
davervw 0:b9d9145827e2 386 led2 = rb;
davervw 0:b9d9145827e2 387
davervw 0:b9d9145827e2 388 if (new_buttons != 0)
davervw 0:b9d9145827e2 389 break;
davervw 0:b9d9145827e2 390 if (timer.read_ms() > 2000)
davervw 0:b9d9145827e2 391 {
davervw 0:b9d9145827e2 392 mode = MODE_OFFSET;
davervw 0:b9d9145827e2 393 display_verse();
davervw 0:b9d9145827e2 394 break;
davervw 0:b9d9145827e2 395 }
davervw 0:b9d9145827e2 396 }
davervw 0:b9d9145827e2 397 buttons = new_buttons = 0; // pretend we didn't see a change yet
davervw 0:b9d9145827e2 398 }
davervw 0:b9d9145827e2 399 else if (debounce && new_buttons != 0)
davervw 0:b9d9145827e2 400 {
davervw 0:b9d9145827e2 401 timer.reset();
davervw 0:b9d9145827e2 402 timer.start();
davervw 0:b9d9145827e2 403
davervw 0:b9d9145827e2 404 emode next_mode = mode;
davervw 0:b9d9145827e2 405
davervw 0:b9d9145827e2 406 int start_ms = 0;
davervw 0:b9d9145827e2 407 while(true)
davervw 0:b9d9145827e2 408 {
davervw 0:b9d9145827e2 409 int new_buttons = rb + 2*lb;
davervw 0:b9d9145827e2 410 led1 = lb;
davervw 0:b9d9145827e2 411 led2 = rb;
davervw 0:b9d9145827e2 412
davervw 0:b9d9145827e2 413 if (buttons != new_buttons)
davervw 0:b9d9145827e2 414 {
davervw 0:b9d9145827e2 415 mode = next_mode;
davervw 0:b9d9145827e2 416 if (mode == MODE_OFFSET || mode == MODE_VERSE)
davervw 0:b9d9145827e2 417 display_verse();
davervw 0:b9d9145827e2 418 break;
davervw 0:b9d9145827e2 419 }
davervw 0:b9d9145827e2 420
davervw 0:b9d9145827e2 421 {
davervw 0:b9d9145827e2 422 int elapsed = timer.read_ms();
davervw 0:b9d9145827e2 423 int inc_elapsed = elapsed - start_ms;
davervw 0:b9d9145827e2 424 if (elapsed >= 4000 && inc_elapsed >= 250 || mode == MODE_4xBOOK && inc_elapsed >= 25 && (start_ms == 0 || inc_elapsed >= 500) )
davervw 0:b9d9145827e2 425 {
davervw 0:b9d9145827e2 426 //console.printf("4xBOOK elapsed=%d inc_elapsed=%d\n", elapsed, inc_elapsed);
davervw 0:b9d9145827e2 427 if (buttons == 3)
davervw 0:b9d9145827e2 428 {
davervw 0:b9d9145827e2 429 }
davervw 0:b9d9145827e2 430 if (buttons == 2)
davervw 0:b9d9145827e2 431 {
davervw 0:b9d9145827e2 432 book-=4;
davervw 0:b9d9145827e2 433 if (book < 0)
davervw 0:b9d9145827e2 434 book = 0;
davervw 0:b9d9145827e2 435 }
davervw 0:b9d9145827e2 436 if (buttons == 1)
davervw 0:b9d9145827e2 437 {
davervw 0:b9d9145827e2 438 book+=4;
davervw 0:b9d9145827e2 439 if (book >= HolyBible.get_num_books())
davervw 0:b9d9145827e2 440 book = HolyBible.get_num_books()-1;
davervw 0:b9d9145827e2 441 }
davervw 0:b9d9145827e2 442 if (buttons != 3)
davervw 0:b9d9145827e2 443 {
davervw 0:b9d9145827e2 444 chapter = 0;
davervw 0:b9d9145827e2 445 verse = 0;
davervw 0:b9d9145827e2 446 offset = 0;
davervw 0:b9d9145827e2 447 display_nav();
davervw 0:b9d9145827e2 448 next_mode = MODE_4xBOOK;
davervw 0:b9d9145827e2 449 }
davervw 0:b9d9145827e2 450 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 451 }
davervw 0:b9d9145827e2 452 else if (elapsed >= 3000 && inc_elapsed >= 250 || mode == MODE_BOOK && inc_elapsed >= 25 && (start_ms == 0 || inc_elapsed >= 500) )
davervw 0:b9d9145827e2 453 {
davervw 0:b9d9145827e2 454 //console.printf("BOOK elapsed=%d inc_elapsed=%d\n", elapsed, inc_elapsed);
davervw 0:b9d9145827e2 455 if (buttons == 3)
davervw 0:b9d9145827e2 456 {
davervw 0:b9d9145827e2 457 }
davervw 0:b9d9145827e2 458 if (buttons == 2)
davervw 0:b9d9145827e2 459 {
davervw 0:b9d9145827e2 460 if (chapter == 0 && --book < 0)
davervw 0:b9d9145827e2 461 book = 0;
davervw 0:b9d9145827e2 462 chapter = 0;
davervw 0:b9d9145827e2 463 verse = 0;
davervw 0:b9d9145827e2 464 offset = 0;
davervw 0:b9d9145827e2 465 }
davervw 0:b9d9145827e2 466 if (buttons == 1)
davervw 0:b9d9145827e2 467 {
davervw 0:b9d9145827e2 468 if (++book >= HolyBible.get_num_books())
davervw 0:b9d9145827e2 469 {
davervw 0:b9d9145827e2 470 book = HolyBible.get_num_books()-1;
davervw 0:b9d9145827e2 471 chapter = HolyBible.get_num_chapters(book)-1;
davervw 0:b9d9145827e2 472 verse = HolyBible.get_num_verses(book, chapter)-1;
davervw 0:b9d9145827e2 473 offset = 0;
davervw 0:b9d9145827e2 474 }
davervw 0:b9d9145827e2 475 else
davervw 0:b9d9145827e2 476 {
davervw 0:b9d9145827e2 477 chapter = 0;
davervw 0:b9d9145827e2 478 verse = 0;
davervw 0:b9d9145827e2 479 offset = 0;
davervw 0:b9d9145827e2 480 }
davervw 0:b9d9145827e2 481 }
davervw 0:b9d9145827e2 482 if (buttons != 3)
davervw 0:b9d9145827e2 483 {
davervw 0:b9d9145827e2 484 display_nav();
davervw 0:b9d9145827e2 485 next_mode = MODE_BOOK;
davervw 0:b9d9145827e2 486 }
davervw 0:b9d9145827e2 487 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 488 }
davervw 0:b9d9145827e2 489 else if (elapsed >= 2000 && inc_elapsed >= 250 || mode == MODE_CHAPTER && inc_elapsed >= 25 && (start_ms == 0 || inc_elapsed >= 500) )
davervw 0:b9d9145827e2 490 {
davervw 0:b9d9145827e2 491 //console.printf("CHAPTER elapsed=%d inc_elapsed=%d\n", elapsed, inc_elapsed);
davervw 0:b9d9145827e2 492 if (buttons == 3)
davervw 0:b9d9145827e2 493 {
davervw 0:b9d9145827e2 494 }
davervw 0:b9d9145827e2 495 if (buttons == 2)
davervw 0:b9d9145827e2 496 {
davervw 0:b9d9145827e2 497 if (verse == 0 && --chapter < 0)
davervw 0:b9d9145827e2 498 {
davervw 0:b9d9145827e2 499 if (--book < 0)
davervw 0:b9d9145827e2 500 {
davervw 0:b9d9145827e2 501 book = 0;
davervw 0:b9d9145827e2 502 chapter = 0;
davervw 0:b9d9145827e2 503 }
davervw 0:b9d9145827e2 504 else
davervw 0:b9d9145827e2 505 chapter = HolyBible.get_num_chapters(book)-1;
davervw 0:b9d9145827e2 506 }
davervw 0:b9d9145827e2 507 }
davervw 0:b9d9145827e2 508 if (buttons == 1)
davervw 0:b9d9145827e2 509 {
davervw 0:b9d9145827e2 510 if (++chapter >= HolyBible.get_num_chapters(book))
davervw 0:b9d9145827e2 511 {
davervw 0:b9d9145827e2 512 if (++book >= HolyBible.get_num_books())
davervw 0:b9d9145827e2 513 {
davervw 0:b9d9145827e2 514 book = HolyBible.get_num_books()-1;
davervw 0:b9d9145827e2 515 chapter = HolyBible.get_num_chapters(book)-1;
davervw 0:b9d9145827e2 516 }
davervw 0:b9d9145827e2 517 else
davervw 0:b9d9145827e2 518 chapter = 0;
davervw 0:b9d9145827e2 519 }
davervw 0:b9d9145827e2 520 }
davervw 0:b9d9145827e2 521 if (buttons != 3)
davervw 0:b9d9145827e2 522 {
davervw 0:b9d9145827e2 523 verse = 0;
davervw 0:b9d9145827e2 524 offset = 0;
davervw 0:b9d9145827e2 525 display_nav();
davervw 0:b9d9145827e2 526 next_mode = MODE_CHAPTER;
davervw 0:b9d9145827e2 527 }
davervw 0:b9d9145827e2 528 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 529 }
davervw 0:b9d9145827e2 530 else if (elapsed >= 1000 && inc_elapsed >= 250 || mode == MODE_VERSE && inc_elapsed >= 25 && (start_ms == 0 || inc_elapsed >= 500) )
davervw 0:b9d9145827e2 531 {
davervw 0:b9d9145827e2 532 //console.printf("VERSE elapsed=%d inc_elapsed=%d\n", elapsed, inc_elapsed);
davervw 0:b9d9145827e2 533 if (buttons == 3 && next_mode == MODE_BOOKMARK)
davervw 0:b9d9145827e2 534 {
davervw 0:b9d9145827e2 535 if (!HolyBible.bookmark_add(book, chapter, verse))
davervw 0:b9d9145827e2 536 HolyBible.bookmark_del(book, chapter, verse);
davervw 0:b9d9145827e2 537 for (int i=0; i<3; ++i)
davervw 0:b9d9145827e2 538 {
davervw 0:b9d9145827e2 539 led4 = 1;
davervw 0:b9d9145827e2 540 wait(0.2);
davervw 0:b9d9145827e2 541 led4 = 0;
davervw 0:b9d9145827e2 542 wait(0.2);
davervw 0:b9d9145827e2 543 }
davervw 0:b9d9145827e2 544
davervw 0:b9d9145827e2 545 next_mode = MODE_OFFSET;
davervw 0:b9d9145827e2 546 }
davervw 0:b9d9145827e2 547 if (buttons == 2)
davervw 0:b9d9145827e2 548 {
davervw 0:b9d9145827e2 549 if (offset > 0)
davervw 0:b9d9145827e2 550 offset = 0;
davervw 0:b9d9145827e2 551 else if (--verse < 0)
davervw 0:b9d9145827e2 552 {
davervw 0:b9d9145827e2 553 verse = 0;
davervw 0:b9d9145827e2 554 offset = -lcd.rows()*lcd.columns();
davervw 0:b9d9145827e2 555 }
davervw 0:b9d9145827e2 556 else
davervw 0:b9d9145827e2 557 offset = 0;
davervw 0:b9d9145827e2 558 }
davervw 0:b9d9145827e2 559 if (buttons == 1)
davervw 0:b9d9145827e2 560 {
davervw 0:b9d9145827e2 561 char* text = HolyBible.text_verse(book, chapter, verse);
davervw 0:b9d9145827e2 562 offset = strlen(text);
davervw 0:b9d9145827e2 563 delete [] text;
davervw 0:b9d9145827e2 564 }
davervw 0:b9d9145827e2 565 display_verse();
davervw 0:b9d9145827e2 566 next_mode = MODE_VERSE;
davervw 0:b9d9145827e2 567 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 568 }
davervw 0:b9d9145827e2 569 else if (mode == MODE_OFFSET && elapsed >= 25 && elapsed < 1000 && (start_ms == 0 || inc_elapsed >= 500))
davervw 0:b9d9145827e2 570 {
davervw 0:b9d9145827e2 571 //console.printf("OFFSET elapsed=%d inc_elapsed=%d\n", elapsed, inc_elapsed);
davervw 0:b9d9145827e2 572 if (buttons == 3)
davervw 0:b9d9145827e2 573 next_mode = MODE_BOOKMARK;
davervw 0:b9d9145827e2 574 if (buttons == 2)
davervw 0:b9d9145827e2 575 offset -= lcd.rows()*lcd.columns();
davervw 0:b9d9145827e2 576 if (buttons == 1)
davervw 0:b9d9145827e2 577 offset += disp_len;
davervw 0:b9d9145827e2 578 if (buttons != 3)
davervw 0:b9d9145827e2 579 {
davervw 0:b9d9145827e2 580 display_verse();
davervw 0:b9d9145827e2 581 next_mode = MODE_OFFSET;
davervw 0:b9d9145827e2 582 }
davervw 0:b9d9145827e2 583 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 584 }
davervw 0:b9d9145827e2 585 else if (mode == MODE_BOOKMARK && elapsed >= 25 && (start_ms == 0 || inc_elapsed >= 500))
davervw 0:b9d9145827e2 586 {
davervw 0:b9d9145827e2 587 if (buttons == 2)
davervw 0:b9d9145827e2 588 {
davervw 0:b9d9145827e2 589 if (HolyBible.bookmark_prev(book, chapter, verse))
davervw 0:b9d9145827e2 590 {
davervw 0:b9d9145827e2 591 offset = 0;
davervw 0:b9d9145827e2 592 display_nav();
davervw 0:b9d9145827e2 593 }
davervw 0:b9d9145827e2 594 }
davervw 0:b9d9145827e2 595 if (buttons == 1)
davervw 0:b9d9145827e2 596 {
davervw 0:b9d9145827e2 597 if (HolyBible.bookmark_next(book, chapter, verse))
davervw 0:b9d9145827e2 598 {
davervw 0:b9d9145827e2 599 offset = 0;
davervw 0:b9d9145827e2 600 display_nav();
davervw 0:b9d9145827e2 601 }
davervw 0:b9d9145827e2 602 }
davervw 0:b9d9145827e2 603 start_ms += inc_elapsed;
davervw 0:b9d9145827e2 604 }
davervw 0:b9d9145827e2 605 }
davervw 0:b9d9145827e2 606 }
davervw 0:b9d9145827e2 607 }
davervw 0:b9d9145827e2 608 old_buttons = new_buttons;
davervw 0:b9d9145827e2 609 }
davervw 0:b9d9145827e2 610 }
davervw 0:b9d9145827e2 611 }
davervw 0:b9d9145827e2 612
davervw 0:b9d9145827e2 613 void BibleUI::indexing(int progress, void* context)
davervw 0:b9d9145827e2 614 {
davervw 0:b9d9145827e2 615 //console.printf("Indexing %d%%\n", progress);
davervw 0:b9d9145827e2 616 TextLCD& lcd = *(TextLCD*)context;
davervw 0:b9d9145827e2 617 lcd.cls();
davervw 0:b9d9145827e2 618 lcd.printf("Indexing");
davervw 0:b9d9145827e2 619 lcd.locate(0,1);
davervw 0:b9d9145827e2 620 lcd.printf("%d%%", progress);
davervw 0:b9d9145827e2 621 }