Demo for Embedded World 2015.
Dependencies: DMBasicGUI DMSupport
AppNetworkSettings.cpp
00001 /* 00002 * Copyright 2014 Embedded Artists AB 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 #include "mbed.h" 00019 #include "EthernetInterface.h" 00020 #include "AppNetworkSettings.h" 00021 #include "lpc_swim_font.h" 00022 #include "image_data.h" 00023 00024 /****************************************************************************** 00025 * Defines and typedefs 00026 *****************************************************************************/ 00027 00028 #define BTN_WIDTH 40 00029 #define BTN_HEIGHT 40 00030 #define BTN_OFF 20 00031 00032 #define ARROW_WIDTH 52 00033 #define ARROW_HEIGHT 52 00034 00035 /****************************************************************************** 00036 * Private variables 00037 *****************************************************************************/ 00038 00039 // Ugly but needed for callbacks 00040 static AppNetworkSettings* theApp = NULL; 00041 00042 /****************************************************************************** 00043 * Private functions 00044 *****************************************************************************/ 00045 00046 static void buttonClicked(uint32_t x) 00047 { 00048 bool* done = (bool*)x; 00049 *done = true; 00050 } 00051 00052 static void fieldClicked(uint32_t x) 00053 { 00054 if (theApp != NULL) { 00055 theApp->setActiveField(x); 00056 } 00057 } 00058 00059 static void increaseValue(uint32_t x) 00060 { 00061 AppNetworkSettings* app = (AppNetworkSettings*)x; 00062 app->modifyValue(1); 00063 } 00064 00065 static void decreaseValue(uint32_t x) 00066 { 00067 AppNetworkSettings* app = (AppNetworkSettings*)x; 00068 app->modifyValue(-1); 00069 } 00070 00071 static void nextField(uint32_t x) 00072 { 00073 AppNetworkSettings* app = (AppNetworkSettings*)x; 00074 app->changeActiveField(true); 00075 } 00076 00077 static void prevField(uint32_t x) 00078 { 00079 AppNetworkSettings* app = (AppNetworkSettings*)x; 00080 app->changeActiveField(false); 00081 } 00082 00083 void AppNetworkSettings::draw() 00084 { 00085 // Prepare fullscreen 00086 swim_window_open(_win, 00087 _disp->width(), _disp->height(), // full size 00088 (COLOR_T*)_fb, 00089 0,0,_disp->width()-1, _disp->height()-1, // window position and size 00090 1, // border 00091 RED,WHITE,BLACK);/*WHITE, RED, BLACK);*/ // colors: pen, backgr, forgr 00092 swim_set_pen_color(_win, WHITE); 00093 swim_set_title(_win, "Network Settings", RED); 00094 swim_set_pen_color(_win, RED); 00095 00096 //_buttons[ButtonDone] = new Button("Done", _win->fb, _win->xpmax - BTN_OFF - BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT); 00097 00098 ImageButton* ib; 00099 00100 ib = new ImageButton(_win->fb, _win->xpmax - 2*BTN_OFF - 2*BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT); 00101 ib->loadImages(img_ok, img_size_ok); 00102 ib->draw(); 00103 _buttons[ButtonOk] = ib; 00104 ib = new ImageButton(_win->fb, _win->xpmax - BTN_OFF - BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT); 00105 ib->loadImages(img_cancel, img_size_cancel); 00106 ib->draw(); 00107 _buttons[ButtonCancel] = ib; 00108 00109 ib = new ImageButton(_win->fb, 300, 40, ARROW_WIDTH, ARROW_HEIGHT); 00110 ib->loadImages(img_arrow_up, img_size_arrow_up); 00111 ib->setAction(increaseValue, (uint32_t)this); 00112 ib->draw(); 00113 _buttons[ButtonUp] = ib; 00114 ib = new ImageButton(_win->fb, 300, 40+ARROW_HEIGHT+ARROW_HEIGHT, ARROW_WIDTH, ARROW_HEIGHT); 00115 ib->loadImages(img_arrow_down, img_size_arrow_down); 00116 ib->setAction(decreaseValue, (uint32_t)this); 00117 ib->draw(); 00118 _buttons[ButtonDown] = ib; 00119 ib = new ImageButton(_win->fb, 300-ARROW_WIDTH/2-10, 40+ARROW_HEIGHT, ARROW_WIDTH, ARROW_HEIGHT); 00120 ib->loadImages(img_arrow_left, img_size_arrow_left); 00121 ib->setAction(prevField, (uint32_t)this); 00122 ib->draw(); 00123 _buttons[ButtonLeft] = ib; 00124 ib = new ImageButton(_win->fb, 300+ARROW_WIDTH/2+10, 40+ARROW_HEIGHT, ARROW_WIDTH, ARROW_HEIGHT); 00125 ib->loadImages(img_arrow_right, img_size_arrow_right); 00126 ib->setAction(nextField, (uint32_t)this); 00127 ib->draw(); 00128 _buttons[ButtonRight] = ib; 00129 00130 // To avoid having each DigitButton deallocate the shared image 00131 void* pointerToFree = _digitImage.pointerToFree; 00132 _digitImage.pointerToFree = NULL; 00133 00134 addIPField(20, ButtonIp0, "IP Address:"); 00135 addIPField(20+65, ButtonMask0, "Net Mask:"); 00136 addIPField(20+65+65, ButtonGw0, "Gateway:"); 00137 00138 // Restore shared image so that it will be deallocated during teardown 00139 _digitImage.pointerToFree = pointerToFree; 00140 00141 for (int i = 0; i < NumButtons; i++) { 00142 _buttons[i]->draw(); 00143 } 00144 00145 markField(_activeField, true); 00146 } 00147 00148 void AppNetworkSettings::addIPField(int y, int idx, const char* lbl) 00149 { 00150 DigitButton* db; 00151 00152 swim_put_text_xy(_win, lbl, 10, y); 00153 y += 15; 00154 int btny = y-7; 00155 y += _win->ypvmin; // compensate for title bar 00156 int x = 20; 00157 00158 00159 db = new DigitButton(_win->fb, x, y, 55, 34); 00160 db->loadImages(&_digitImage);//img_numbers, img_size_numbers); 00161 db->setNumDigits(3); 00162 db->setValue(_values[idx]); 00163 db->setAction(fieldClicked, idx); 00164 _buttons[idx++] = db; 00165 00166 x += 60; 00167 db = new DigitButton(_win->fb, x, y, 55, 34); 00168 db->loadImages(&_digitImage);//img_numbers, img_size_numbers); 00169 db->setNumDigits(3); 00170 db->setValue(_values[idx]); 00171 db->setAction(fieldClicked, idx); 00172 _buttons[idx++] = db; 00173 swim_put_box(_win, x-7, btny+31, x-4, btny+34); 00174 00175 x += 60; 00176 db = new DigitButton(_win->fb, x, y, 55, 34); 00177 db->loadImages(&_digitImage);//img_numbers, img_size_numbers); 00178 db->setNumDigits(3); 00179 db->setValue(_values[idx]); 00180 db->setAction(fieldClicked, idx); 00181 _buttons[idx++] = db; 00182 swim_put_box(_win, x-7, btny+31, x-4, btny+34); 00183 00184 x += 60; 00185 db = new DigitButton(_win->fb, x, y, 55, 34); 00186 db->loadImages(&_digitImage);//img_numbers, img_size_numbers); 00187 db->setNumDigits(3); 00188 db->setValue(_values[idx]); 00189 db->setAction(fieldClicked, idx); 00190 _buttons[idx++] = db; 00191 swim_put_box(_win, x-7, btny+31, x-4, btny+34); 00192 } 00193 00194 void AppNetworkSettings::markField(int field, bool active) 00195 { 00196 COLOR_T oldPen = _win->pen; 00197 COLOR_T oldFill = _win->fill; 00198 _win->fill = active ? BLACK : _win->bkg; 00199 _win->pen = active ? BLACK : _win->bkg; 00200 if (field >= 0 && field < NumFields) { 00201 int x0, y0, x1, y1; 00202 _buttons[field]->bounds(x0,y0,x1,y1); 00203 y1 -= _win->ypvmin+1; 00204 x0--; 00205 swim_put_box(_win, x0, y1, x1, y1+3); 00206 } 00207 _win->fill = oldFill; 00208 _win->pen = oldPen; 00209 } 00210 00211 /****************************************************************************** 00212 * Public functions 00213 *****************************************************************************/ 00214 00215 AppNetworkSettings::AppNetworkSettings() : _disp(NULL), _win(NULL), _fb(NULL), _activeField(0) 00216 { 00217 for (int i = 0; i < NumButtons; i++) { 00218 _buttons[i] = NULL; 00219 } 00220 _values[0] = 192; 00221 _values[1] = 168; 00222 _values[2] = 5; 00223 _values[3] = 220; 00224 _values[4] = 255; 00225 _values[5] = 255; 00226 _values[6] = 255; 00227 _values[7] = 0; 00228 _values[8] = 192; 00229 _values[9] = 168; 00230 _values[10] = 5; 00231 _values[11] = 1; 00232 00233 _digitImage.pointerToFree = NULL; 00234 00235 theApp = this; 00236 } 00237 00238 AppNetworkSettings::~AppNetworkSettings() 00239 { 00240 theApp = NULL; 00241 teardown(); 00242 } 00243 00244 bool AppNetworkSettings::setup() 00245 { 00246 _disp = DMBoard::instance().display(); 00247 _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T)); 00248 _fb = _disp->allocateFramebuffer(); 00249 int res = Image::decode(img_numbers, img_size_numbers, Image::RES_16BIT, &_digitImage); 00250 00251 return (_win != NULL && _fb != NULL && res == 0); 00252 } 00253 00254 void AppNetworkSettings::runToCompletion() 00255 { 00256 // Alternative 1: use the calling thread's context to run in 00257 bool done = false; 00258 bool abort = false; 00259 draw(); 00260 _buttons[ButtonOk]->setAction(buttonClicked, (uint32_t)&done); 00261 _buttons[ButtonCancel]->setAction(buttonClicked, (uint32_t)&abort); 00262 void* oldFB = _disp->swapFramebuffer(_fb); 00263 00264 // Wait for touches 00265 TouchPanel* touch = DMBoard::instance().touchPanel(); 00266 touch_coordinate_t coord; 00267 00268 int lastPressed = NumButtons; 00269 Timer t; 00270 t.start(); 00271 int repeatAt; 00272 00273 uint32_t maxDelay = osWaitForever; 00274 while(!done && !abort) { 00275 Thread::signal_wait(0x1, maxDelay); 00276 if (touch->read(coord) == TouchPanel::TouchError_Ok) { 00277 for (int i = 0; i < NumButtons; i++) { 00278 if (_buttons[i]->handle(coord.x, coord.y, coord.z > 0)) { 00279 _buttons[i]->draw(); 00280 if (_buttons[i]->pressed()) { 00281 lastPressed = i; // new button pressed 00282 t.reset(); 00283 repeatAt = 1000; 00284 } 00285 } 00286 } 00287 if (lastPressed == ButtonUp || lastPressed == ButtonDown) { 00288 maxDelay = 10; 00289 if (_buttons[lastPressed]->pressed() && t.read_ms() > repeatAt) { 00290 modifyValue((lastPressed == ButtonUp) ? 1 : -1); 00291 repeatAt = t.read_ms()+(200/(t.read_ms()/1000)); 00292 } 00293 } else { 00294 maxDelay = osWaitForever; 00295 } 00296 } 00297 } 00298 00299 if (!abort) { 00300 #if defined(DM_BOARD_USE_REGISTRY) 00301 Registry* reg = DMBoard::instance().registry(); 00302 RtosLog* log = DMBoard::instance().logger(); 00303 char buf[16] = {0}; 00304 sprintf(buf, "%lu.%lu.%lu.%lu", _values[0], _values[1], _values[2], _values[3]); 00305 reg->setValue("IP Address", buf); 00306 log->printf("New STATIC IP Address: %s\n", buf); 00307 sprintf(buf, "%lu.%lu.%lu.%lu", _values[4], _values[5], _values[6], _values[7]); 00308 reg->setValue("Net Mask", buf); 00309 log->printf("New STATIC Net Mask: %s\n", buf); 00310 sprintf(buf, "%lu.%lu.%lu.%lu", _values[8], _values[9], _values[10], _values[11]); 00311 reg->setValue("Gateway", buf); 00312 log->printf("New STATIC Gateway: %s\n", buf); 00313 reg->store(); 00314 #endif 00315 } 00316 00317 // User has clicked the button, restore the original FB 00318 _disp->swapFramebuffer(oldFB); 00319 swim_window_close(_win); 00320 } 00321 00322 bool AppNetworkSettings::teardown() 00323 { 00324 if (_win != NULL) { 00325 free(_win); 00326 _win = NULL; 00327 } 00328 if (_fb != NULL) { 00329 free(_fb); 00330 _fb = NULL; 00331 } 00332 for (int i = 0; i < NumButtons; i++) { 00333 if (_buttons[i] != NULL) { 00334 delete _buttons[i]; 00335 _buttons[i] = NULL; 00336 } 00337 } 00338 if (_digitImage.pointerToFree != NULL) { 00339 free(_digitImage.pointerToFree); 00340 _digitImage.pointerToFree = NULL; 00341 } 00342 return true; 00343 } 00344 00345 void AppNetworkSettings::modifyValue(int mod) 00346 { 00347 _values[_activeField] = (mod + _values[_activeField]) % 256; 00348 ((DigitButton*)_buttons[_activeField])->setValue(_values[_activeField]); 00349 } 00350 00351 void AppNetworkSettings::changeActiveField(bool next) 00352 { 00353 markField(_activeField, false); 00354 if (next) { 00355 _activeField = (_activeField+1) % NumFields; 00356 } else { 00357 _activeField = (_activeField+NumFields-1) % NumFields; 00358 } 00359 markField(_activeField, true); 00360 } 00361 00362 void AppNetworkSettings::setActiveField(uint32_t newField) 00363 { 00364 if (_activeField != newField && newField < NumFields) { 00365 markField(_activeField, false); 00366 _activeField = newField; 00367 markField(_activeField, true); 00368 } 00369 } 00370
Generated on Wed Jul 13 2022 18:24:58 by 1.7.2