A basic graphics package for the LPC4088 Display Module.

Dependents:   lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more

Fork of DMBasicGUI by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AppTouchCalibration.cpp Source File

AppTouchCalibration.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 "AppTouchCalibration.h"
00020 #include "lpc_swim_font.h"
00021 
00022 /******************************************************************************
00023  * Defines and typedefs
00024  *****************************************************************************/
00025  
00026 #define BTN_OFF    20
00027 
00028 /******************************************************************************
00029  * Global variables
00030  *****************************************************************************/
00031 
00032 
00033 /******************************************************************************
00034  * Private functions
00035  *****************************************************************************/
00036 
00037 static void buttonClicked(uint32_t x)
00038 {
00039   bool* done = (bool*)x;
00040   *done = true;
00041 }
00042 
00043 void AppTouchCalibration::draw()
00044 {
00045     // Prepare fullscreen
00046     swim_window_open(_win, 
00047                    _disp->width(), _disp->height(),         // full size
00048                    (COLOR_T*)_fb,
00049                    0,0,_disp->width()-1, _disp->height()-1, // window position and size
00050                    1,                                       // border
00051                    WHITE, WHITE, BLACK);                    // colors: pen, backgr, forgr
00052     swim_set_title(_win, "Touch Calibration", BLACK);
00053     
00054     // Prepare status area in the middle
00055     swim_window_open(_msg, 
00056                      _disp->width(), _disp->height(),             // full size
00057                      (COLOR_T*)_fb,
00058                      50,_disp->height()/2-15,_disp->width()-50, _disp->height()/2+15, // window position and size
00059                      0,                                           // border
00060                      BLACK, WHITE, BLACK);                        // colors: pen, backgr, forgr
00061 
00062     showStatus("Press the crosshairs in each of the corners");
00063     
00064     // Create (but don't show) the button
00065     _btn = new ImageButton(_win->fb, _win->xpmax - BTN_OFF - _resOk->width(), _win->ypmax - BTN_OFF - _resOk->height(), _resOk->width(), _resOk->height());
00066     _btn->loadImages(_resOk);
00067 }
00068 
00069 void AppTouchCalibration::drawMarker(uint16_t x, uint16_t y, bool erase)
00070 {
00071     // The markers must be drawn at exact locations to get a good calibration.
00072     // However the lpc_swim functions take the window's title bar into
00073     // consideration which will move them. To combat this the marker's
00074     // coordinates will have to be moved    
00075     x -= _win->xpvmin;
00076     y -= _win->ypvmin;
00077     
00078     swim_set_pen_color(_win, (erase ? _win->bkg : BLACK));
00079     swim_put_line(_win, x-15, y, x+15, y);
00080     swim_put_line(_win, x, y-15, x, y+15);
00081     swim_put_circle(_win, x, y, 10, false);    
00082 }
00083 
00084 bool AppTouchCalibration::calibrate()
00085 {
00086     bool morePoints = true;
00087     bool lastPoint = false;
00088     uint16_t x, y;
00089     int point = 0;
00090     
00091     do {
00092         if (_touch->calibrateStart() != TouchPanel::TouchError_Ok) {
00093             showStatus("Failed to start calibration\n");
00094             break;
00095         }  
00096         while (morePoints) {
00097             if (point++ > 0) {
00098                 // erase old location
00099                 drawMarker(x, y, true);
00100             }
00101             if (_touch->getNextCalibratePoint(&x, &y, &lastPoint) != TouchPanel::TouchError_Ok) {
00102                 showStatus("Failed to get calibration point\n");
00103                 break;
00104             }
00105             drawMarker(x, y, false);
00106             if (lastPoint) {
00107                 showStatus("Last calibration point. After this the data will");
00108                 showStatus("be saved, which can take a couple of seconds!", 1);
00109             }
00110             if (_touch->waitForCalibratePoint(&morePoints, 0) != TouchPanel::TouchError_Ok) {
00111                 showStatus("Failed to get user click\n");
00112                 break;
00113             }
00114         }
00115         if (morePoints) {
00116             // aborted calibration due to error(s)
00117             break;
00118         }
00119 
00120         // erase old location
00121         drawMarker(x, y, true);
00122     } while(0);
00123     
00124     return !morePoints;
00125 }
00126 
00127 void AppTouchCalibration::showStatus(const char* message, int line)
00128 {
00129     if (line == 0) {
00130         swim_clear_screen(_msg, _msg->bkg);
00131         swim_put_text_centered_win(_msg, message, 0);
00132     } else {
00133         swim_put_text_centered_win(_msg, message, line*swim_get_font_height(_msg));
00134     }
00135     DMBoard::instance().logger()->printf("[CALIB] %s\n", message);
00136 }
00137 
00138 /******************************************************************************
00139  * Public functions
00140  *****************************************************************************/
00141 
00142 AppTouchCalibration::AppTouchCalibration() : _disp(NULL), _touch(NULL), 
00143   _win(NULL), _fb(NULL), _btn(NULL), _resOk(NULL)
00144 {
00145 }
00146 
00147 AppTouchCalibration::~AppTouchCalibration()
00148 {
00149     teardown();
00150 }
00151 
00152 bool AppTouchCalibration::setup()
00153 {
00154     _disp = DMBoard::instance().display();
00155     _touch = DMBoard::instance().touchPanel();
00156     _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
00157     _msg = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
00158     _fb = _disp->allocateFramebuffer();
00159 
00160     return (_win != NULL && _msg != NULL && _fb != NULL);
00161 }
00162 
00163 void AppTouchCalibration::runToCompletion()
00164 {
00165     // Alternative 1: use the calling thread's context to run in
00166     bool done = false;
00167     draw();
00168     _btn->setAction(buttonClicked, (uint32_t)&done);
00169     void* oldFB = _disp->swapFramebuffer(_fb);
00170     
00171     // Run calibration
00172     if (calibrate()) {
00173         showStatus("Calibration Completed. Test to draw!");
00174         _btn->draw();
00175     } else {
00176         // Something went wrong. The error is already shown!
00177         // Without touch there is no point in continuing, ask
00178         // user to reset.
00179         
00180         swim_put_text_centered_win(_win, "Without touch there is nothing to do. Press RESET !", 2*_disp->height()/3);
00181         while(1) {
00182             ThisThread::sleep_for(5000);
00183         }
00184     }
00185     
00186     // Allow user to draw. Exit by pressing button
00187     swim_set_pen_color(_win, BLACK);
00188     touch_coordinate_t coord;
00189     while(!done) {
00190       // wait for a new touch signal (signal is sent from AppLauncher,
00191       // which listens for touch events)
00192       ThisThread::flags_wait_any(0x1);
00193         
00194       if (_touch->read(coord) == TouchPanel::TouchError_Ok) {
00195         if (coord.z > 0) {
00196             //swim_put_pixel(_win, coord.x, coord.y);
00197             swim_put_box(_win, coord.x-1, coord.y-1, coord.x+1, coord.y+1);
00198         }
00199         if (_btn->handle(coord.x, coord.y, coord.z > 0)) {
00200             _btn->draw();
00201         }
00202       }
00203     }
00204     
00205     // User has clicked the button, restore the original FB
00206     _disp->swapFramebuffer(oldFB);
00207     swim_window_close(_win);
00208     swim_window_close(_msg);
00209 }
00210 
00211 bool AppTouchCalibration::teardown()
00212 {
00213     if (_win != NULL) {
00214         free(_win);
00215         _win = NULL;
00216     }
00217     if (_msg != NULL) {
00218         free(_msg);
00219         _msg = NULL;
00220     }
00221     if (_fb != NULL) {
00222         free(_fb);
00223         _fb = NULL;
00224     }
00225     if (_btn != NULL) {
00226         delete _btn;
00227         _btn = NULL;
00228     }
00229     return true;
00230 }
00231 
00232 void AppTouchCalibration::addResource(Resources id, Resource* res)
00233 {
00234     _resOk = res;
00235 }