Example using the support package for LPC4088 DisplayModule

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AppNetworkSettings.cpp Source File

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 = 0;
00272 
00273     uint32_t maxDelay = osWaitForever; 
00274     while(!done && !abort) {
00275       ThisThread::flags_wait_all(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, "%u.%u.%u.%u", _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, "%u.%u.%u.%u", _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, "%u.%u.%u.%u", _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 }