Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DMBasicGUI by
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 Thread::wait(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 Thread::signal_wait(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 }
Generated on Wed Jul 13 2022 03:01:50 by
1.7.2
