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.
Dependents: lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI lpc4088_displaymodule_fs_aid ... more
Fork of DMBasicGUI by
Application/AppTouchCalibration.cpp
- Committer:
- embeddedartists
- Date:
- 2015-02-19
- Revision:
- 12:53601973f7eb
- Parent:
- 8:19a6b70d42b1
- Child:
- 17:6e2abf107800
File content as of revision 12:53601973f7eb:
/*
* Copyright 2014 Embedded Artists AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include "AppTouchCalibration.h"
#include "lpc_swim_font.h"
/******************************************************************************
* Defines and typedefs
*****************************************************************************/
#define BTN_WIDTH 65
#define BTN_HEIGHT 40
#define BTN_OFF 20
/******************************************************************************
* Global variables
*****************************************************************************/
/******************************************************************************
* Private functions
*****************************************************************************/
static void buttonClicked(uint32_t x)
{
bool* done = (bool*)x;
*done = true;
}
void AppTouchCalibration::draw()
{
// Prepare fullscreen
swim_window_open(_win,
_disp->width(), _disp->height(), // full size
(COLOR_T*)_fb,
0,0,_disp->width()-1, _disp->height()-1, // window position and size
1, // border
WHITE, WHITE, BLACK); // colors: pen, backgr, forgr
swim_set_title(_win, "Touch Calibration", BLACK);
// Prepare status area in the middle
swim_window_open(_msg,
_disp->width(), _disp->height(), // full size
(COLOR_T*)_fb,
50,_disp->height()/2-15,_disp->width()-50, _disp->height()/2+15, // window position and size
0, // border
BLACK, WHITE, BLACK); // colors: pen, backgr, forgr
showStatus("Press the crosshairs in each of the corners");
// Create (but don't show) the button
_btn = new Button("Done", _win->fb, _win->xpmax - BTN_OFF - BTN_WIDTH, _win->ypmax - BTN_OFF - BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT);
}
void AppTouchCalibration::drawMarker(uint16_t x, uint16_t y, bool erase)
{
// The markers must be drawn at exact locations to get a good calibration.
// However the lpc_swim functions take the window's title bar into
// consideration which will move them. To combat this the marker's
// coordinates will have to be moved
x -= _win->xpvmin;
y -= _win->ypvmin;
swim_set_pen_color(_win, (erase ? _win->bkg : BLACK));
swim_put_line(_win, x-15, y, x+15, y);
swim_put_line(_win, x, y-15, x, y+15);
swim_put_circle(_win, x, y, 10, false);
}
bool AppTouchCalibration::calibrate()
{
bool morePoints = true;
bool lastPoint = false;
uint16_t x, y;
int point = 0;
do {
if (_touch->calibrateStart() != TouchPanel::TouchError_Ok) {
showStatus("Failed to start calibration\n");
break;
}
while (morePoints) {
if (point++ > 0) {
// erase old location
drawMarker(x, y, true);
}
if (_touch->getNextCalibratePoint(&x, &y, &lastPoint) != TouchPanel::TouchError_Ok) {
showStatus("Failed to get calibration point\n");
break;
}
drawMarker(x, y, false);
if (lastPoint) {
showStatus("Last calibration point. After this the data will");
showStatus("be saved, which can take a couple of seconds!", 1);
}
if (_touch->waitForCalibratePoint(&morePoints, 0) != TouchPanel::TouchError_Ok) {
showStatus("Failed to get user click\n");
break;
}
}
if (morePoints) {
// aborted calibration due to error(s)
break;
}
// erase old location
drawMarker(x, y, true);
} while(0);
return !morePoints;
}
void AppTouchCalibration::showStatus(const char* message, int line)
{
if (line == 0) {
swim_clear_screen(_msg, _msg->bkg);
swim_put_text_centered_win(_msg, message, 0);
} else {
swim_put_text_centered_win(_msg, message, line*swim_get_font_height(_msg));
}
DMBoard::instance().logger()->printf("[CALIB] %s\n", message);
}
/******************************************************************************
* Public functions
*****************************************************************************/
AppTouchCalibration::AppTouchCalibration() : _disp(NULL), _touch(NULL), _win(NULL), _fb(NULL), _btn(NULL)
{
}
AppTouchCalibration::~AppTouchCalibration()
{
teardown();
}
bool AppTouchCalibration::setup()
{
_disp = DMBoard::instance().display();
_touch = DMBoard::instance().touchPanel();
_win = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
_msg = (SWIM_WINDOW_T*)malloc(sizeof(SWIM_WINDOW_T));
_fb = _disp->allocateFramebuffer();
return (_win != NULL && _msg != NULL && _fb != NULL);
}
void AppTouchCalibration::runToCompletion()
{
// Alternative 1: use the calling thread's context to run in
bool done = false;
draw();
_btn->setAction(buttonClicked, (uint32_t)&done);
void* oldFB = _disp->swapFramebuffer(_fb);
// Run calibration
if (calibrate()) {
showStatus("Calibration Completed. Test to draw!");
_btn->draw();
} else {
// Something went wrong. The error is already shown!
// Without touch there is no point in continuing, ask
// user to reset.
swim_put_text_centered_win(_win, "Without touch there is nothing to do. Press RESET !", 2*_disp->height()/3);
while(1) {
Thread::wait(5000);
}
}
// Allow user to draw. Exit by pressing button
swim_set_pen_color(_win, BLACK);
touch_coordinate_t coord;
while(!done) {
// wait for a new touch signal (signal is sent from AppLauncher,
// which listens for touch events)
Thread::signal_wait(0x1);
if (_touch->read(coord) == TouchPanel::TouchError_Ok) {
if (coord.z > 0) {
//swim_put_pixel(_win, coord.x, coord.y);
swim_put_box(_win, coord.x-1, coord.y-1, coord.x+1, coord.y+1);
}
if (_btn->handle(coord.x, coord.y, coord.z > 0)) {
_btn->draw();
}
}
}
// User has clicked the button, restore the original FB
_disp->swapFramebuffer(oldFB);
swim_window_close(_win);
swim_window_close(_msg);
}
bool AppTouchCalibration::teardown()
{
if (_win != NULL) {
free(_win);
_win = NULL;
}
if (_msg != NULL) {
free(_msg);
_msg = NULL;
}
if (_fb != NULL) {
free(_fb);
_fb = NULL;
}
if (_btn != NULL) {
delete _btn;
_btn = NULL;
}
return true;
}
