ArduinoLibs
TimeField.cpp
00001 /*
00002  * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020  * DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #include "TimeField.h"
00024 
00065 #define EDIT_HOUR           0
00066 #define EDIT_MINUTE_TENS    1
00067 #define EDIT_MINUTE         2
00068 #define EDIT_SECOND_TENS    3
00069 #define EDIT_SECOND         4
00070 
00082 TimeField::TimeField(const String &label)
00083     : Field(label)
00084     , _value(0)
00085     , _maxHours(24)
00086     , _printLen(0)
00087     , _readOnly(false)
00088     , editField(EDIT_HOUR)
00089 {
00090 }
00091 
00105 TimeField::TimeField(Form &form, const String &label, int maxHours, bool readOnly)
00106     : Field(form, label)
00107     , _value(0)
00108     , _maxHours(maxHours)
00109     , _printLen(0)
00110     , _readOnly(readOnly)
00111     , editField(EDIT_HOUR)
00112 {
00113 }
00114 
00115 int TimeField::dispatch(int event)
00116 {
00117     unsigned long newValue;
00118     if (_readOnly)
00119         return -1;
00120     if (event == LCD_BUTTON_UP) {
00121         newValue = _value;
00122         if (editField == EDIT_HOUR) {
00123             newValue += 60 * 60;
00124         } else if (editField == EDIT_MINUTE_TENS) {
00125             if (((newValue / 60) % 60) >= 50)
00126                 newValue -= 50 * 60;
00127             else
00128                 newValue += 10 * 60;
00129         } else if (editField == EDIT_MINUTE) {
00130             if (((newValue / 60) % 60) == 59)
00131                 newValue -= 59 * 60;
00132             else
00133                 newValue += 60;
00134         } else if (editField == EDIT_SECOND_TENS) {
00135             if ((newValue % 60) >= 50)
00136                 newValue -= 50;
00137             else
00138                 newValue += 10;
00139         } else {
00140             if ((newValue % 60) == 59)
00141                 newValue -= 59;
00142             else
00143                 newValue += 1;
00144         }
00145         setValue(newValue);
00146         return FORM_CHANGED;
00147     } else if (event == LCD_BUTTON_DOWN) {
00148         newValue = _value;
00149         if (editField == EDIT_HOUR) {
00150             if (newValue < 60 * 60)
00151                 newValue += ((unsigned long)(_maxHours - 1)) * 60 * 60;
00152             else
00153                 newValue -= 60 * 60;
00154         } else if (editField == EDIT_MINUTE_TENS) {
00155             if (((newValue / 60) % 60) < 10)
00156                 newValue += 50 * 60;
00157             else
00158                 newValue -= 10 * 60;
00159         } else if (editField == EDIT_MINUTE) {
00160             if (((newValue / 60) % 60) == 0)
00161                 newValue += 59 * 60;
00162             else
00163                 newValue -= 60;
00164         } else if (editField == EDIT_SECOND_TENS) {
00165             if ((newValue % 60) < 10)
00166                 newValue += 50;
00167             else
00168                 newValue -= 10;
00169         } else {
00170             if ((newValue % 60) == 0)
00171                 newValue += 59;
00172             else
00173                 newValue -= 1;
00174         }
00175         setValue(newValue);
00176         return FORM_CHANGED;
00177     } else if (event == LCD_BUTTON_LEFT) {
00178         if (editField != EDIT_HOUR) {
00179             --editField;
00180             printTime();
00181             return 0;
00182         }
00183     } else if (event == LCD_BUTTON_RIGHT) {
00184         if (editField != EDIT_SECOND) {
00185             ++editField;
00186             printTime();
00187             return 0;
00188         }
00189     }
00190     return -1;
00191 }
00192 
00193 void TimeField::enterField(bool reverse)
00194 {
00195     Field::enterField(reverse);
00196     if (reverse)
00197         editField = EDIT_SECOND;
00198     else
00199         editField = EDIT_HOUR;
00200     printTime();
00201     if (!_readOnly)
00202         lcd()->cursor();
00203 }
00204 
00205 void TimeField::exitField()
00206 {
00207     if (!_readOnly)
00208         lcd()->noCursor();
00209     Field::exitField();
00210 }
00211 
00227 void TimeField::setValue(unsigned long value)
00228 {
00229     unsigned long maxSecs = ((unsigned long)_maxHours) * 60 * 60;
00230     value %= maxSecs;
00231     if (value != _value) {
00232         _value = value;
00233         if (isCurrent())
00234             printTime();
00235     }
00236 }
00237 
00268 void TimeField::setReadOnly(bool value)
00269 {
00270     if (_readOnly != value) {
00271         _readOnly = value;
00272         printTime();
00273         if (isCurrent()) {
00274             if (value)
00275                 lcd()->cursor();
00276             else
00277                 lcd()->noCursor();
00278         }
00279     }
00280 }
00281 
00282 void TimeField::printTime()
00283 {
00284     lcd()->setCursor(0, 1);
00285     int col = printField(_value / (60 * 60));
00286     int hourCol = col - 1;
00287     lcd()->write(':');
00288     ++col;
00289     col += printField((_value / 60) % 60);
00290     int minuteCol = col - 1;
00291     lcd()->write(':');
00292     ++col;
00293     col += printField(_value % 60);
00294     int secondCol = col - 1;
00295     int tempCol = col;
00296     while (tempCol++ < _printLen)
00297         lcd()->write(' ');
00298     _printLen = col;
00299     if (!_readOnly) {
00300         if (editField == EDIT_HOUR)
00301             lcd()->setCursor(hourCol, 1);
00302         else if (editField == EDIT_MINUTE_TENS)
00303             lcd()->setCursor(minuteCol - 1, 1);
00304         else if (editField == EDIT_MINUTE)
00305             lcd()->setCursor(minuteCol, 1);
00306         else if (editField == EDIT_SECOND_TENS)
00307             lcd()->setCursor(secondCol - 1, 1);
00308         else
00309             lcd()->setCursor(secondCol, 1);
00310     }
00311 }
00312 
00313 int TimeField::printField(unsigned long value)
00314 {
00315     if (value < 100) {
00316         lcd()->write('0' + (int)(value / 10));
00317         lcd()->write('0' + (int)(value % 10));
00318         return 2;
00319     }
00320     unsigned long divisor = 100;
00321     while ((value / divisor) >= 10)
00322         divisor *= 10;
00323     int digits = 0;
00324     while (divisor > 0) {
00325         lcd()->write('0' + (int)((value / divisor) % 10));
00326         divisor /= 10;
00327         ++digits;
00328     }
00329     return digits;
00330 }
 All Classes Files Functions Variables Enumerations Enumerator