The out-of-the-box demo application flashed on all display modules before they are shipped.

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers <title>AppNetworkSettings.cpp Source File</title>

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 
00023 /******************************************************************************
00024  * Defines and typedefs
00025  *****************************************************************************/
00026  
00027 #define BTN_OFF    20
00028  
00029 /******************************************************************************
00030  * Private variables
00031  *****************************************************************************/
00032 
00033 // Ugly but needed for callbacks
00034 static AppNetworkSettings* theApp = NULL;
00035 
00036 /******************************************************************************
00037  * Private functions
00038  *****************************************************************************/
00039 
00040 static void buttonClicked(uint32_t x)
00041 {
00042   bool* done = (bool*)x;
00043   *done = true;
00044 }
00045 
00046 static void fieldClicked(uint32_t x)
00047 {
00048   if (theApp != NULL) {
00049     theApp->setActiveField(x);
00050   }
00051 }
00052 
00053 static void increaseValue(uint32_t x)
00054 {
00055   AppNetworkSettings* app = (AppNetworkSettings*)x;
00056   app->modifyValue(1);
00057 }
00058 
00059 static void decreaseValue(uint32_t x)
00060 {
00061   AppNetworkSettings* app = (AppNetworkSettings*)x;
00062   app->modifyValue(-1);
00063 }
00064 
00065 static void nextField(uint32_t x)
00066 {
00067   AppNetworkSettings* app = (AppNetworkSettings*)x;
00068   app->changeActiveField(true);
00069 }
00070 
00071 static void prevField(uint32_t x)
00072 {
00073   AppNetworkSettings* app = (AppNetworkSettings*)x;
00074   app->changeActiveField(false);
00075 }
00076 
00077 void AppNetworkSettings::draw()
00078 {
00079     // Prepare fullscreen
00080     swim_window_open(_win, 
00081                    _disp->width(), _disp->height(),         // full size
00082                    (COLOR_T*)_fb,
00083                    0,0,_disp->width()-1, _disp->height()-1, // window position and size
00084                    1,                                       // border
00085                    RED,WHITE,BLACK);/*WHITE, RED,  BLACK);*/                     // colors: pen, backgr, forgr
00086     swim_set_pen_color(_win, WHITE);
00087     swim_set_title(_win, "Network Settings", RED);
00088     swim_set_pen_color(_win, RED);
00089 
00090     //_buttons[ButtonDone] = new Button("Done", _win->fb, _win->xpmax - BTN_OFF - BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT);
00091   
00092     ImageButton* ib;
00093     
00094     Resource* rOk = _res[Resource_Ok_button];
00095     Resource* rCancel = _res[Resource_Cancel_button];
00096     ib =  new ImageButton(_win->fb, _win->xpmax - 2*BTN_OFF - rCancel->width() -rOk->width(), _win->ypmax - BTN_OFF - rOk->height(), rOk->width(), rOk->height());
00097     ib->loadImages(rOk);
00098     ib->draw();
00099     _buttons[ButtonOk] = ib;    
00100     ib =  new ImageButton(_win->fb, _win->xpmax - BTN_OFF - rCancel->width(), _win->ypmax - BTN_OFF - rCancel->height(), rCancel->width(), rCancel->height());
00101     ib->loadImages(rCancel);
00102     ib->draw();
00103     _buttons[ButtonCancel] = ib;    
00104 
00105     int arrowW = _res[Resource_ArrowUp_button]->width();
00106     int arrowH = _res[Resource_ArrowUp_button]->height();
00107     int arrowCenter = 260 + arrowW;
00108     ib =  new ImageButton(_win->fb, arrowCenter, 40, arrowW, arrowH);
00109     ib->loadImages( _res[Resource_ArrowUp_button]);
00110     ib->setAction(increaseValue, (uint32_t)this);
00111     ib->draw();
00112     _buttons[ButtonUp] = ib;    
00113     ib =  new ImageButton(_win->fb, arrowCenter, 40+arrowH+arrowH, arrowW, arrowH);
00114     ib->loadImages( _res[Resource_ArrowDown_button]);
00115     ib->setAction(decreaseValue, (uint32_t)this);
00116     ib->draw();
00117     _buttons[ButtonDown] = ib;
00118     ib =  new ImageButton(_win->fb, arrowCenter-(arrowW/2)-10, 40+arrowH, arrowW, arrowH);
00119     ib->loadImages(_res[Resource_ArrowLeft_button]);
00120     ib->setAction(prevField, (uint32_t)this);
00121     ib->draw();
00122     _buttons[ButtonLeft] = ib;
00123     ib =  new ImageButton(_win->fb, arrowCenter+(arrowW/2)+10, 40+arrowH, arrowW, arrowH);
00124     ib->loadImages(_res[Resource_ArrowRight_button]);
00125     ib->setAction(nextField, (uint32_t)this);
00126     ib->draw();
00127     _buttons[ButtonRight] = ib;
00128     
00129     // To avoid having each DigitButton deallocate the shared image
00130     void* pointerToFree = _digitImage.pointerToFree;
00131     _digitImage.pointerToFree = NULL;
00132     
00133     addIPField(20, ButtonIp0, "IP Address:");
00134     addIPField(20+65, ButtonMask0, "Net Mask:");
00135     addIPField(20+65+65, ButtonGw0, "Gateway:");
00136     
00137     // Restore shared image so that it will be deallocated during teardown
00138     _digitImage.pointerToFree = pointerToFree;
00139     
00140   for (int i = 0; i < NumButtons; i++) {
00141     _buttons[i]->draw();
00142   }
00143   
00144   markField(_activeField, true);
00145 }
00146 
00147 void AppNetworkSettings::addIPField(int y, int idx, const char* lbl)
00148 {
00149     DigitButton* db;
00150     
00151     swim_put_text_xy(_win, lbl, 10, y);
00152     y += 15;
00153     int btny = y-7;
00154     y += _win->ypvmin; // compensate for title bar 
00155     int x = 20;
00156     
00157     
00158     db =  new DigitButton(_win->fb, x, y, 55, 34);
00159     db->loadImages(&_digitImage);//img_numbers, img_size_numbers);
00160     db->setNumDigits(3);
00161     db->setValue(_values[idx]);
00162     db->setAction(fieldClicked, idx);
00163     _buttons[idx++] = db;
00164     
00165     x += 60;    
00166     db =  new DigitButton(_win->fb, x, y, 55, 34);
00167     db->loadImages(&_digitImage);//img_numbers, img_size_numbers);
00168     db->setNumDigits(3);
00169     db->setValue(_values[idx]);
00170     db->setAction(fieldClicked, idx);
00171     _buttons[idx++] = db;
00172     swim_put_box(_win, x-7, btny+31, x-4, btny+34);    
00173     
00174     x += 60;    
00175     db =  new DigitButton(_win->fb, x, y, 55, 34);
00176     db->loadImages(&_digitImage);//img_numbers, img_size_numbers);
00177     db->setNumDigits(3);
00178     db->setValue(_values[idx]);
00179     db->setAction(fieldClicked, idx);
00180     _buttons[idx++] = db;
00181     swim_put_box(_win, x-7, btny+31, x-4, btny+34);    
00182     
00183     x += 60;    
00184     db =  new DigitButton(_win->fb, x, y, 55, 34);
00185     db->loadImages(&_digitImage);//img_numbers, img_size_numbers);
00186     db->setNumDigits(3);
00187     db->setValue(_values[idx]);
00188     db->setAction(fieldClicked, idx);
00189     _buttons[idx++] = db;
00190     swim_put_box(_win, x-7, btny+31, x-4, btny+34);    
00191 }
00192 
00193 void AppNetworkSettings::markField(int field, bool active)
00194 {
00195   COLOR_T oldPen = _win->pen;
00196   COLOR_T oldFill = _win->fill;
00197   _win->fill = active ? BLACK : _win->bkg;
00198   _win->pen = active ? BLACK : _win->bkg;
00199   if (field >= 0 && field < NumFields) {
00200     int x0, y0, x1, y1;
00201     _buttons[field]->bounds(x0,y0,x1,y1);
00202     y1 -= _win->ypvmin+1;
00203     x0--;
00204     swim_put_box(_win, x0, y1, x1, y1+3);
00205   }
00206   _win->fill = oldFill;
00207   _win->pen = oldPen;
00208 }
00209 
00210 /******************************************************************************
00211  * Public functions
00212  *****************************************************************************/
00213 
00214 AppNetworkSettings::AppNetworkSettings() : _disp(NULL), _win(NULL), _fb(NULL), _activeField(0)
00215 {
00216   for (int i = 0; i < NumButtons; i++) {
00217     _buttons[i] = NULL;
00218   }
00219   for (int i = 0; i < NumResources; i++) {
00220     _res[i] = NULL;
00221   }
00222   _values[0] = 192;
00223   _values[1] = 168;
00224   _values[2] = 5;
00225   _values[3] = 220;
00226   _values[4] = 255;
00227   _values[5] = 255;
00228   _values[6] = 255;
00229   _values[7] = 0;
00230   _values[8] = 192;
00231   _values[9] = 168;
00232   _values[10] = 5;
00233   _values[11] = 1;
00234   
00235   _digitImage.pointerToFree = NULL;
00236   
00237   theApp = this;
00238 }
00239 
00240 AppNetworkSettings::~AppNetworkSettings()
00241 {
00242     theApp = NULL;
00243     teardown();
00244 }
00245 
00246 bool AppNetworkSettings::setup()
00247 {
00248     _disp = DMBoard::instance().display();
00249     _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
00250     _fb = _disp->allocateFramebuffer();
00251     int res = Image::decode(_res[Resource_Digits], Image::RES_16BIT, &_digitImage);
00252 
00253     return (_win != NULL && _fb != NULL && res == 0);
00254 }
00255 
00256 void AppNetworkSettings::runToCompletion()
00257 {
00258     // Alternative 1: use the calling thread's context to run in
00259     bool done = false;
00260     bool abort = false;
00261     draw();
00262     _buttons[ButtonOk]->setAction(buttonClicked, (uint32_t)&done);
00263     _buttons[ButtonCancel]->setAction(buttonClicked, (uint32_t)&abort);
00264     void* oldFB = _disp->swapFramebuffer(_fb);
00265     
00266     // Wait for touches
00267     TouchPanel* touch = DMBoard::instance().touchPanel();
00268     touch_coordinate_t coord;
00269 
00270     int lastPressed = NumButtons;
00271     Timer t;
00272     t.start();
00273     int repeatAt = 0;
00274 
00275     uint32_t maxDelay = osWaitForever; 
00276     while(!done && !abort) {
00277       ThisThread::flags_wait_all_for(0x1, maxDelay);
00278       if (touch->read(coord) == TouchPanel::TouchError_Ok) {
00279         for (int i = 0; i < NumButtons; i++) {
00280           if (_buttons[i]->handle(coord.x, coord.y, coord.z > 0)) {
00281             _buttons[i]->draw();
00282             if (_buttons[i]->pressed()) {
00283               lastPressed = i; // new button pressed
00284               t.reset();
00285               repeatAt = 1000;
00286             }
00287           }
00288         }
00289         if (lastPressed == ButtonUp || lastPressed == ButtonDown) {
00290           maxDelay = 10;
00291           if (_buttons[lastPressed]->pressed() && t.read_ms() > repeatAt) {
00292             modifyValue((lastPressed == ButtonUp) ? 1 : -1);
00293             repeatAt = t.read_ms()+(200/(t.read_ms()/1000));
00294           }
00295         } else {
00296           maxDelay = osWaitForever;
00297         }
00298       }
00299     }
00300 
00301     if (!abort) {
00302 #if defined(DM_BOARD_USE_REGISTRY)
00303       Registry* reg = DMBoard::instance().registry();
00304       RtosLog* log = DMBoard::instance().logger();
00305       char buf[16] = {0};
00306       sprintf(buf, "%u.%u.%u.%u", _values[0], _values[1], _values[2], _values[3]);
00307       reg->setValue("IP Address", buf);
00308       log->printf("New STATIC IP Address: %s\n", buf);
00309       sprintf(buf, "%u.%u.%u.%u", _values[4], _values[5], _values[6], _values[7]);
00310       reg->setValue("Net Mask", buf);
00311       log->printf("New STATIC Net Mask:   %s\n", buf);
00312       sprintf(buf, "%u.%u.%u.%u", _values[8], _values[9], _values[10], _values[11]);
00313       reg->setValue("Gateway", buf);
00314       log->printf("New STATIC Gateway:    %s\n", buf);
00315       reg->store();
00316 #endif
00317     }
00318     
00319     // User has clicked the button, restore the original FB
00320     _disp->swapFramebuffer(oldFB);
00321     swim_window_close(_win);
00322 }
00323 
00324 bool AppNetworkSettings::teardown()
00325 {
00326     if (_win != NULL) {
00327         free(_win);
00328         _win = NULL;
00329     }
00330     if (_fb != NULL) {
00331         free(_fb);
00332         _fb = NULL;
00333     }
00334     for (int i = 0; i < NumButtons; i++) {
00335         if (_buttons[i] != NULL) {
00336             delete _buttons[i];
00337             _buttons[i] = NULL;
00338         }
00339     }
00340     if (_digitImage.pointerToFree != NULL) {
00341         free(_digitImage.pointerToFree);
00342         _digitImage.pointerToFree = NULL;
00343     }
00344     return true;
00345 }
00346 
00347 void AppNetworkSettings::modifyValue(int mod)
00348 {
00349   _values[_activeField] = (mod + _values[_activeField]) % 256;
00350   ((DigitButton*)_buttons[_activeField])->setValue(_values[_activeField]);
00351 }
00352 
00353 void AppNetworkSettings::changeActiveField(bool next)
00354 {
00355   markField(_activeField, false);
00356   if (next) {
00357     _activeField = (_activeField+1) % NumFields;
00358   } else {
00359     _activeField = (_activeField+NumFields-1) % NumFields;
00360   }
00361   markField(_activeField, true);
00362 }
00363 
00364 void AppNetworkSettings::setActiveField(uint32_t newField)
00365 {
00366   if (_activeField != newField && newField < NumFields) {
00367     markField(_activeField, false);
00368     _activeField = newField;
00369     markField(_activeField, true);
00370   }
00371 }
00372 
00373 void AppNetworkSettings::addResource(Resources id, Resource* res)
00374 {
00375     _res[id] = res;
00376 }
00377 
00378