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
AppLauncher.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 "AppLauncher.h" 00020 #include "lpc_swim_font.h" 00021 #include "Button.h" 00022 #include "ImageButton.h" 00023 00024 /****************************************************************************** 00025 * Defines and typedefs 00026 *****************************************************************************/ 00027 00028 #define APP_PREFIX "[Launcher] " 00029 00030 #define NO_APPLICATION (-1) 00031 00032 #define APP_SIGID_TOUCH 0x1 00033 00034 /****************************************************************************** 00035 * Private variables 00036 *****************************************************************************/ 00037 00038 static int appToLaunch = NO_APPLICATION; 00039 static osThreadId appThread; 00040 00041 /****************************************************************************** 00042 * Private functions 00043 *****************************************************************************/ 00044 00045 static void buttonClicked(uint32_t x) 00046 { 00047 if (appToLaunch == NO_APPLICATION) { 00048 appToLaunch = (int)x; 00049 } 00050 } 00051 00052 void AppLauncher::draw() 00053 { 00054 // Prepare fullscreen 00055 swim_window_open(_win, 00056 _disp->width(), _disp->height(), // full size 00057 (COLOR_T*)_fb, 00058 0,0,_disp->width()-1, _disp->height()-1, // window position and size 00059 1, // border 00060 WHITE, BLACK, BLACK); // colors: pen, backgr, forgr 00061 swim_set_title(_win, "Demo Program", BLACK); 00062 00063 if (_supportsCalibration) { 00064 const char* msg = "(Press physical UserButton >2s to calibrate touch)"; 00065 int w, h; 00066 swim_get_string_bounds(_win, msg, &w, &h); 00067 swim_put_text_xy(_win, msg, (_disp->width()-w)/2, _disp->height()-h*4); 00068 } 00069 00070 for (int i = 0; i < _usedButtons; i++) { 00071 _buttons[i]->draw(); 00072 } 00073 } 00074 00075 void AppLauncher::onTouchEvent() 00076 { 00077 _newTouchEvent = true; 00078 osSignalSet(appThread, APP_SIGID_TOUCH); 00079 } 00080 00081 void AppLauncher::onButtonEvent() 00082 { 00083 _newButtonEvent = true; 00084 osSignalSet(appThread, APP_SIGID_TOUCH); 00085 } 00086 00087 static void onTimeoutEvent(void const* arg) 00088 { 00089 *((bool*)arg) = true; 00090 osSignalSet(appThread, APP_SIGID_TOUCH); 00091 } 00092 00093 /****************************************************************************** 00094 * Public functions 00095 *****************************************************************************/ 00096 00097 AppLauncher::AppLauncher() : _disp(NULL), _win(NULL), _fb(NULL), _usedButtons(0) 00098 { 00099 for (int i = 0; i < NumberOfButtons; i++) { 00100 _buttons[i] = NULL; 00101 } 00102 bool r; 00103 int n; 00104 if (DMBoard::instance().touchPanel()->info(&r, &n, &_supportsCalibration) != TouchPanel::TouchError_Ok) { 00105 _supportsCalibration = false; 00106 } 00107 } 00108 00109 AppLauncher::~AppLauncher() 00110 { 00111 teardown(); 00112 } 00113 00114 bool AppLauncher::setup() 00115 { 00116 RtosLog* log = DMBoard::instance().logger(); 00117 00118 _disp = DMBoard::instance().display(); 00119 _win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T)); 00120 _fb = _disp->allocateFramebuffer(); 00121 00122 if (_win == NULL || _fb == NULL) { 00123 log->printf(APP_PREFIX"Failed to allocate memory for framebuffer\r\n"); 00124 return false; 00125 } 00126 00127 return true; 00128 } 00129 00130 void AppLauncher::runToCompletion() 00131 { 00132 DMBoard* board = &DMBoard::instance(); 00133 RtosLog* log = board->logger(); 00134 00135 appThread = osThreadGetId(); 00136 00137 // Draw something on the framebuffer before using it so that it doesn't look garbled 00138 draw(); 00139 00140 // Start display in default mode (16-bit) 00141 Display::DisplayError disperr = _disp->powerUp(_fb); 00142 if (disperr != Display::DisplayError_Ok) { 00143 log->printf(APP_PREFIX"Failed to initialize the display, got error %d\r\n", disperr); 00144 return; 00145 } 00146 00147 // To keep track of the button pushes 00148 bool buttonPressed = false; 00149 bool buttonTimeout = false; 00150 InterruptIn button(P2_10); 00151 button.rise(callback(this, &AppLauncher::onButtonEvent)); 00152 button.fall(callback(this, &AppLauncher::onButtonEvent)); 00153 //RtosTimer buttonTimer(onTimeoutEvent, osTimerOnce, &buttonTimeout); 00154 EventQueue buttonTimer(4*EVENTS_EVENT_SIZE); 00155 int buttonTimerId = buttonTimer.call_in(2000, onTimeoutEvent, &buttonTimeout); 00156 00157 // Wait for touches 00158 TouchPanel* touch = board->touchPanel(); 00159 //FunctionPointer* fpOld = touch->setListener(new FunctionPointer(this, &AppLauncher::onTouchEvent)); 00160 touch->setListener(callback(this, &AppLauncher::onTouchEvent)); 00161 touch_coordinate_t coord; 00162 while (true) { 00163 ThisThread::flags_wait_any(APP_SIGID_TOUCH); 00164 if (_newTouchEvent) { 00165 if (buttonPressed) { 00166 // cancel 00167 buttonPressed = false; 00168 //buttonTimer.stop(); 00169 buttonTimer.cancel(buttonTimerId); 00170 } 00171 _newTouchEvent = false; 00172 if (touch->read(coord) != TouchPanel::TouchError_Ok) { 00173 log->printf("Failed to read touch coordinate\n"); 00174 continue; 00175 } 00176 // Process the touch coordinate for each button 00177 for (int i = 0; i < NumberOfButtons; i++) { 00178 if (_buttons[i] != NULL) { 00179 if (_buttons[i]->handle(coord.x, coord.y, coord.z > 0)) { 00180 _buttons[i]->draw(); 00181 } 00182 } 00183 } 00184 } else if (buttonTimeout) { 00185 if (board->buttonPressed()) { 00186 appToLaunch = CalibrationApp; 00187 } 00188 buttonPressed = false; 00189 buttonTimeout = false; 00190 } else if (_newButtonEvent) { 00191 _newButtonEvent = false; 00192 if (board->buttonPressed()) { 00193 buttonPressed = true; 00194 //buttonTimer.start(2000); 00195 buttonTimer.dispatch(0); 00196 } else { 00197 buttonPressed = false; 00198 //buttonTimer.stop(); 00199 buttonTimer.cancel(buttonTimerId); 00200 } 00201 continue; 00202 } 00203 00204 if (appToLaunch != NO_APPLICATION) { 00205 App* a = NULL; 00206 if (_callback != NULL) { 00207 a = _callback(appToLaunch); 00208 } 00209 if (a != NULL) { 00210 if (a->setup()) { 00211 a->runToCompletion(); 00212 a->teardown(); 00213 } 00214 delete a; 00215 } 00216 appToLaunch = NO_APPLICATION; 00217 } 00218 } 00219 00220 // restore old touch listener (get our listener in return) 00221 //fpOld = touch->setListener(fpOld); 00222 //delete fpOld; 00223 } 00224 00225 bool AppLauncher::teardown() 00226 { 00227 if (_win != NULL) { 00228 free(_win); 00229 _win = NULL; 00230 } 00231 if (_fb != NULL) { 00232 free(_fb); 00233 _fb = NULL; 00234 } 00235 for (int i = 0; i < NumberOfButtons; i++) { 00236 _buttons[i] = NULL; 00237 if (_buttons[i] != NULL) { 00238 delete _buttons[i]; 00239 _buttons[i] = NULL; 00240 } 00241 } 00242 return true; 00243 } 00244 00245 void AppLauncher::setAppCreatorFunc(App*(*callback)(uint32_t buttonID)) 00246 { 00247 _callback = callback; 00248 } 00249 00250 bool AppLauncher::addButton(uint32_t buttonID, const char* caption) 00251 { 00252 int idx = _usedButtons++; 00253 int xspace = ((_disp->width() - ButtonColumns * ButtonWidth) / (ButtonColumns + 1)); 00254 int yspace = ((_disp->height() - TitleHeight - ButtonRows * ButtonHeight) / (ButtonRows + 1)); 00255 00256 _buttons[idx] = new Button(caption, (COLOR_T*)_fb, 00257 xspace + (ButtonWidth + xspace)*(idx%ButtonColumns), 00258 TitleHeight + yspace + (ButtonHeight + yspace)*(idx/ButtonColumns), 00259 ButtonWidth, ButtonHeight); 00260 _buttons[idx]->setAction(buttonClicked, buttonID); 00261 //_buttons[idx]->draw(); 00262 return true; 00263 } 00264 00265 bool AppLauncher::addImageButton(uint32_t buttonID, const char* imgUp, const char* imgDown) 00266 { 00267 return addImageButton(buttonID, NULL, BLACK, imgUp, imgDown); 00268 } 00269 00270 bool AppLauncher::addImageButton(uint32_t buttonID, const char* caption, COLOR_T color, const char* imgUp, const char* imgDown) 00271 { 00272 int idx = _usedButtons++; 00273 int xspace = ((_disp->width() - ButtonColumns * 64) / (ButtonColumns + 1)); 00274 int yspace = ((_disp->height() - TitleHeight - ButtonRows * 64) / (ButtonRows + 1)); 00275 int yoff = (caption == NULL) ? 0 : -15; // compensate for caption taking up space 00276 00277 ImageButton* img = new ImageButton((COLOR_T*)_fb, 00278 xspace + (64 + xspace)*(idx%ButtonColumns), 00279 TitleHeight + yspace + (64 + yspace)*(idx/ButtonColumns) + yoff, 00280 64, 64, caption, color); 00281 if (img->loadImages(imgUp, imgDown)) { 00282 _buttons[idx] = img; 00283 _buttons[idx]->setAction(buttonClicked, buttonID); 00284 //_buttons[idx]->draw(); 00285 return true; 00286 } else { 00287 //DMBoard::instance().logger()->printf("Failed to load image for buttonID %u, %s[%s]\n", buttonID, imgUp, imgDown==NULL?"":imgDown); 00288 return false; 00289 } 00290 } 00291 00292 bool AppLauncher::addImageButton(uint32_t buttonID, const unsigned char* imgUp, unsigned int imgUpSize, const unsigned char* imgDown, unsigned int imgDownSize) 00293 { 00294 return addImageButton(buttonID, NULL, BLACK, imgUp, imgUpSize, imgDown, imgDownSize); 00295 } 00296 00297 bool AppLauncher::addImageButton(uint32_t buttonID, const char* caption, COLOR_T color, const unsigned char* imgUp, unsigned int imgUpSize, const unsigned char* imgDown, unsigned int imgDownSize) 00298 { 00299 int idx = _usedButtons++; 00300 int xspace = ((_disp->width() - ButtonColumns * 64) / (ButtonColumns + 1)); 00301 int yspace = ((_disp->height() - TitleHeight - ButtonRows * 64) / (ButtonRows + 1)); 00302 int yoff = (caption == NULL) ? 0 : -15; // compensate for caption taking up space 00303 00304 ImageButton* img = new ImageButton((COLOR_T*)_fb, 00305 xspace + (64 + xspace)*(idx%ButtonColumns), 00306 TitleHeight + yspace + (64 + yspace)*(idx/ButtonColumns) + yoff, 00307 64, 64, caption, color); 00308 if (img->loadImages(imgUp, imgUpSize, imgDown, imgDownSize)) { 00309 _buttons[idx] = img; 00310 _buttons[idx]->setAction(buttonClicked, buttonID); 00311 //_buttons[idx]->draw(); 00312 return true; 00313 } else { 00314 //DMBoard::instance().logger()->printf("Failed to load image for buttonID %u, %s[%s]\n", buttonID, imgUp, imgDown==NULL?"":imgDown); 00315 return false; 00316 } 00317 }
Generated on Tue Jul 12 2022 21:27:03 by 1.7.2