root/modules/gui_read.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gui_read_draw_batt
  2. gui_read_draw_clock
  3. gui_read_draw_scroll_indicator
  4. gui_read_init
  5. read_goto_next_line
  6. read_fit_next_char
  7. gui_read_draw
  8. gui_read_kbd_process
  9. gui_read_kbd_process_menu_btn
  10. gui_read_kbd_leave
  11. _module_unloader
  12. _module_can_unload
  13. _module_exit_alt

   1 #include "camera_info.h"
   2 #include "stdlib.h"
   3 #include "keyboard.h"
   4 #include "clock.h"
   5 #include "conf.h"
   6 #include "gui.h"
   7 #include "font.h"
   8 #include "gui_draw.h"
   9 #include "gui_batt.h"
  10 #include "gui_lang.h"
  11 
  12 #include "gui_read.h"
  13 #include "module_def.h"
  14 
  15 //-------------------------------------------------------------------
  16 
  17 extern void gui_read_kbd_process_menu_btn();
  18 int gui_read_kbd_process();
  19 void gui_read_draw();
  20 void gui_read_kbd_leave();
  21 
  22 gui_handler GUI_MODE_READ = 
  23 /*GUI_MODE_READ*/   { GUI_MODE_MODULE, gui_read_draw, gui_read_kbd_process, gui_read_kbd_process_menu_btn, 0, 0 };
  24 
  25 gui_handler *old_mode;
  26 
  27 //-------------------------------------------------------------------
  28 static int running = 0;
  29 static int read_file;
  30 static int read_file_size;
  31 static int read_on_screen;
  32 static int read_to_draw;
  33 static coord x, y, h, w;
  34 #define READ_BUFFER_SIZE  100
  35 static char buffer[READ_BUFFER_SIZE+1];
  36 static long last_time;
  37 static int xx, yy;
  38 static int pause;
  39 static int busy_drawing = 0;
  40 static int do_not_draw = 0;
  41 
  42 static int reader_is_active;    // Flag raised when reader is succesfully runned
  43                                                                 // purpose: we shouldn't process "leave" sequence if we call unload module but reader was not runed yet
  44 
  45 //-------------------------------------------------------------------
  46 static void gui_read_draw_batt() {
  47     sprintf(buffer, "Batt:%3d%%", get_batt_perc());
  48     draw_string(camera_screen.disp_right-11*FONT_WIDTH, 0, buffer, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE));
  49 }
  50 
  51 //-------------------------------------------------------------------
  52 static void gui_read_draw_clock() {
  53     static struct tm *ttm;
  54 
  55     ttm = get_localtime();
  56     sprintf(buffer, "%2u:%02u", ttm->tm_hour, ttm->tm_min);
  57     draw_string(camera_screen.disp_right-17*FONT_WIDTH, 0, buffer, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE));
  58 }
  59 
  60 //-------------------------------------------------------------------
  61 static void gui_read_draw_scroll_indicator() {
  62     draw_char(camera_screen.disp_right-FONT_WIDTH, 0,
  63                   (conf.reader_autoscroll)?((pause)?'\x05':'\x04'):'\x03', MAKE_COLOR(COLOR_BLACK, COLOR_WHITE)); //title infoline
  64 }
  65 
  66 //-------------------------------------------------------------------
  67 int gui_read_init(const char* file)
  68 {
  69     running = 1;
  70 
  71     static struct stat   st;
  72 
  73     read_file = open(file, O_RDONLY, 0777);
  74     if (strcmp(file, conf.reader_file)!=0) {
  75         conf.reader_pos = 0;
  76         strcpy(conf.reader_file, file);
  77     }
  78     read_on_screen = 0;
  79     read_file_size = (read_file>=0 && stat((char*)file, &st)==0)?st.st_size:0;
  80     if (read_file_size<=conf.reader_pos) {
  81         conf.reader_pos = 0;
  82     }
  83     pause = 0;
  84     read_to_draw = 1;
  85     x=camera_screen.disp_left+6; 
  86     y=FONT_HEIGHT;
  87     w=camera_screen.disp_width-6-6-8;
  88     h=camera_screen.height-y;
  89     last_time = get_tick_count();
  90     
  91         reader_is_active=1;    
  92     old_mode = gui_set_mode(&GUI_MODE_READ);
  93 
  94     return (read_file >= 0);
  95 }
  96 
  97 //-------------------------------------------------------------------
  98 static void read_goto_next_line() {
  99     twoColors col = user_color(conf.reader_color);
 100     draw_rectangle(xx, yy, x+w-1, yy+rbf_font_height()-1, MAKE_COLOR(BG_COLOR(col), BG_COLOR(col)), RECT_BORDER0|DRAW_FILLED);
 101     xx  = x;
 102     yy += rbf_font_height();
 103 }
 104 
 105 //-------------------------------------------------------------------
 106 static int read_fit_next_char(int ch) {
 107     return (xx+rbf_char_width(ch) < x+w);
 108 }
 109 
 110 //-------------------------------------------------------------------
 111 void gui_read_draw(int force_redraw)
 112 {
 113     if (do_not_draw)
 114         return;
 115     busy_drawing = 1;
 116     twoColors col = user_color(conf.reader_color);
 117 
 118     static int first_draw = 1;
 119     if (first_draw || force_redraw)
 120     {
 121         if (first_draw)
 122         {
 123             // font has to be loaded from here (SpyTask)
 124             rbf_load_from_file(conf.reader_rbf_file, conf.reader_codepage);
 125         }
 126         draw_rectangle(camera_screen.disp_left, 0,
 127                        camera_screen.disp_right, y-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
 128         draw_rectangle(camera_screen.disp_left, y,
 129                        camera_screen.disp_right, camera_screen.height-1, MAKE_COLOR(BG_COLOR(col), BG_COLOR(col)), RECT_BORDER0|DRAW_FILLED);
 130         gui_read_draw_scroll_indicator();
 131         read_to_draw = 1;
 132         first_draw = 0;
 133     }
 134 
 135     if (conf.reader_autoscroll && !pause && get_tick_count()-last_time >= conf.reader_autoscroll_delay*1000 && (conf.reader_pos+read_on_screen)<read_file_size)
 136     {
 137         conf.reader_pos += read_on_screen;
 138         read_to_draw = 1;
 139     }
 140     if (read_to_draw)
 141     {
 142         int n, m, i, ii, ll, new_word=1;
 143 
 144         xx=x; yy=y;
 145 
 146         lseek(read_file, conf.reader_pos, SEEK_SET);
 147         read_on_screen=0;
 148 
 149         while (yy<=y+h-rbf_font_height()) {
 150             n=read(read_file, buffer, READ_BUFFER_SIZE);
 151             if (n==0) {
 152                  read_goto_next_line();
 153                  if (yy < y+h)
 154                      draw_rectangle(x, yy, x+w-1, y+h-1, MAKE_COLOR(BG_COLOR(col), BG_COLOR(col)), RECT_BORDER0|DRAW_FILLED);
 155                  break;
 156             }
 157             else if (n<0) {
 158                 // read failed
 159                 do_not_draw = 1;
 160                 busy_drawing = 0;
 161                 return;
 162             }
 163             i=0;
 164             while (i<n && yy<=y+h-rbf_font_height()) {
 165                 switch (buffer[i]) {
 166                     case '\r':
 167                         new_word = 1;
 168                         break;
 169                     case '\n':
 170                         read_goto_next_line();
 171                         new_word = 1;
 172                         break;
 173                     case '\t':
 174                         buffer[i] = ' ';
 175                         // no break here
 176                     default:
 177                         if (conf.reader_wrap_by_words) {
 178                             if (buffer[i] == ' ') {
 179                                 new_word = 1;
 180                                 if (xx==x) //ignore leading spaces
 181                                     break;
 182                             } else if (new_word) {
 183                                 new_word = 0;
 184                                 for (ii=i, ll=0; ii<n && buffer[ii]!=' ' && buffer[ii]!='\t' && buffer[ii]!='\r' && buffer[ii]!='\n'; ++ii) {
 185                                     ll+=rbf_char_width(buffer[ii]);
 186                                 }
 187                                 if (ii==n) {
 188                                     memcpy(buffer, buffer+i, n-i);
 189                                     n=ii=n-i;
 190                                     read_on_screen+=i;
 191                                     i=0;
 192                                     m=read(read_file, buffer+n, READ_BUFFER_SIZE-n);
 193                                     if (m<0) {
 194                                         // read failed
 195                                         do_not_draw = 1;
 196                                         busy_drawing = 0;
 197                                         return;
 198                                     }
 199                                     n+=m;
 200                                     for (; ii<n && buffer[ii]!=' ' && buffer[ii]!='\t' && buffer[ii]!='\r' && buffer[ii]!='\n'; ++ii) {
 201                                         ll+=rbf_char_width(buffer[ii]);
 202                                     }
 203                                 }
 204                                 if (xx+ll>=x+w && ll<w) {
 205                                     read_goto_next_line();
 206                                     continue;
 207                                 }
 208                             }
 209                         }
 210                         if (!read_fit_next_char(buffer[i])) {
 211                             read_goto_next_line();
 212                             continue;
 213                         }
 214                         xx+=rbf_draw_char(xx, yy, buffer[i], col);
 215                         break;
 216                 }
 217                 ++i;
 218                 if (xx >= x+w) {
 219                     xx  = x;
 220                     yy += rbf_font_height();
 221                 }
 222             }
 223             read_on_screen+=i;
 224         }
 225     
 226         sprintf(buffer, "(%3d%%) %d/%d", (read_file_size)?(conf.reader_pos*100/read_file_size):0, conf.reader_pos, read_file_size);
 227         draw_string_justified(camera_screen.disp_left, 0, buffer, MAKE_COLOR(COLOR_BLACK, COLOR_WHITE), 0, 20*FONT_WIDTH, TEXT_LEFT|TEXT_FILL); //title infoline
 228 
 229         // scrollbar
 230         if (read_file_size) {
 231             i=h-1 -1;           // full height
 232             n=i*read_on_screen/read_file_size;           // bar height
 233             if (n<20) n=20;
 234             i=(i-n)*conf.reader_pos/read_file_size;   // top pos
 235             draw_rectangle(x+w+6+2, y+1,   x+w+6+6, y+1+i,   MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
 236             draw_rectangle(x+w+6+2, y+i+n, x+w+6+6, y+h-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
 237             draw_rectangle(x+w+6+2, y+1+i, x+w+6+6, y+i+n,   MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER0|DRAW_FILLED);
 238         } else {
 239             draw_rectangle((x+w)*FONT_WIDTH+2, y*FONT_HEIGHT+1,
 240                            (x+w)*FONT_WIDTH+6, (y+h)*FONT_HEIGHT-1-1, MAKE_COLOR(COLOR_BLACK, COLOR_BLACK), RECT_BORDER0|DRAW_FILLED);
 241         }
 242 
 243         read_to_draw = 0;
 244         last_time = get_tick_count();
 245     }
 246     gui_read_draw_batt();
 247     gui_read_draw_clock();
 248     busy_drawing = 0;
 249 }
 250 
 251 //-------------------------------------------------------------------
 252 int gui_read_kbd_process() {
 253     switch (kbd_get_autoclicked_key() | get_jogdial_direction()) {
 254         case JOGDIAL_LEFT:
 255         case KEY_ZOOM_OUT:
 256         case KEY_UP:
 257         case KEY_LEFT:
 258             if (conf.reader_pos>0) {
 259                 conf.reader_pos -= 45*15;
 260                 if (conf.reader_pos<0) conf.reader_pos=0;
 261                 read_to_draw = 1;
 262             }
 263             break;
 264         case JOGDIAL_RIGHT:
 265         case KEY_ZOOM_IN:
 266         case KEY_DOWN:
 267         case KEY_RIGHT:
 268         case KEY_SHOOT_HALF:
 269             if ((conf.reader_pos+read_on_screen)<read_file_size) {
 270                 conf.reader_pos += read_on_screen;
 271                 read_to_draw = 1;
 272             }
 273             break;
 274         case KEY_SET:
 275             break;
 276         case KEY_DISPLAY:
 277             pause = !pause;
 278             gui_read_draw_scroll_indicator();
 279             last_time = get_tick_count();
 280             break;
 281         case KEY_MENU:
 282                         gui_read_kbd_leave();
 283             break;
 284     }
 285     return 0;
 286 }
 287 
 288 // =========  MODULE INIT =================
 289 
 290 //-------------------------------------------------------------------
 291 // Menu button handled for text reader
 292 void gui_read_kbd_process_menu_btn()
 293 {
 294     gui_read_kbd_process();
 295     gui_set_mode(old_mode);
 296 }
 297 
 298 void gui_read_kbd_leave()
 299 {
 300     if ( !reader_is_active )
 301         return;
 302 
 303     reader_is_active = 0;
 304 
 305     do_not_draw = 1;
 306 
 307     while (busy_drawing)
 308     {
 309         msleep(10);
 310     }
 311 
 312     if (read_file >= 0)
 313     {
 314         close(read_file);
 315         read_file=-1;
 316     }
 317     rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
 318 
 319     running = 0;
 320 }
 321 
 322 // =========  MODULE INIT =================
 323 
 324 /***************** BEGIN OF AUXILARY PART *********************
 325 ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 326 **************************************************************/
 327 
 328 //---------------------------------------------------------
 329 // PURPOSE: Finalize module operations (close allocs, etc)
 330 // RETURN VALUE: 0-ok, 1-fail
 331 //---------------------------------------------------------
 332 int _module_unloader()
 333 {
 334     // We should make "leave sequence" to restore font settings
 335     gui_read_kbd_leave();
 336 
 337     return 0;
 338 }
 339 
 340 int _module_can_unload()
 341 {
 342     return running == 0;
 343 }
 344 
 345 int _module_exit_alt()
 346 {
 347     running = 0;
 348     return 0;
 349 }
 350 
 351 /******************** Module Information structure ******************/
 352 
 353 libtxtread_sym _libtxtread =
 354 {
 355     {
 356          0, _module_unloader, _module_can_unload, _module_exit_alt, 0
 357     },
 358 
 359     gui_read_init
 360 };
 361 
 362 ModuleInfo _module_info =
 363 {
 364     MODULEINFO_V1_MAGICNUM,
 365     sizeof(ModuleInfo),
 366     GUI_READ_VERSION,                   // Module version
 367 
 368     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 369     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 370 
 371     (int32_t)"Text reader",
 372     MTYPE_EXTENSION,
 373 
 374     &_libtxtread.base,
 375 
 376     CONF_VERSION,               // CONF version
 377     CAM_SCREEN_VERSION,         // CAM SCREEN version
 378     ANY_VERSION,                // CAM SENSOR version
 379     ANY_VERSION,                // CAM INFO version
 380 };
 381 
 382 /*************** END OF AUXILARY PART *******************/

/* [<][>][^][v][top][bottom][index][help] */