ArduinoLibs
|
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 }