SpikeStream Application Library  0.2
AbstractGraphWidget.cpp
Go to the documentation of this file.
00001 //SpikeStream includes
00002 #include "Globals.h"
00003 #include "AbstractGraphWidget.h"
00004 #include "SpikeStreamException.h"
00005 #include "Util.h"
00006 using namespace spikestream;
00007 
00008 //Qt includes
00009 #include <QFileDialog>
00010 #include <QMessageBox>
00011 #include <QPainter>
00012 #include <QResizeEvent>
00013 #include <QDebug>
00014 
00015 
00017 AbstractGraphWidget::AbstractGraphWidget(QWidget* parent) : QWidget(parent){
00018         //Initialize with empty default values
00019         numTimeSteps = 1000;
00020         minTimeStep = 0;
00021         setYRange(-10, 10);
00022         xAxisTickLength = 2;
00023         yAxisTickLength = 2;
00024         axesLabelFontSize = 10;
00025         labelFontSize = 10;
00026         backgroundColor = qRgb(255,255,255);
00027         axesColor = qRgb(0,0,0);
00028         bufferImage = NULL;
00029 
00030         //Build default buffer image
00031         buildBufferImage();
00032 
00033         //Painting attributes
00034         setAttribute(Qt::WA_OpaquePaintEvent);
00035         setAttribute(Qt::WA_PaintOnScreen);
00036 }
00037 
00038 
00040 AbstractGraphWidget::~AbstractGraphWidget(){
00041         if(bufferImage != NULL)
00042                 delete bufferImage;
00043 }
00044 
00045 
00046 /*----------------------------------------------------------*/
00047 /*------               PUBLIC METHODS                 ------*/
00048 /*----------------------------------------------------------*/
00049 
00051 void AbstractGraphWidget::setYRange(int minY, int maxY){
00052         if(minY >= maxY)
00053                 throw SpikeStreamException("MinY must be less than maxY.");
00054         this->minY = minY;
00055         this->maxY = maxY;
00056 }
00057 
00058 
00059 
00060 /*----------------------------------------------------------*/
00061 /*------              PROTECTED METHODS               ------*/
00062 /*----------------------------------------------------------*/
00063 
00066 void AbstractGraphWidget::buildBufferImage(){
00067         if(bufferImage != NULL)
00068                 delete bufferImage;
00069 
00070         yAxisPadding = yAxisTickLength + 10 + axesLabelFontSize * QString::number(maxY-minY).length();
00071         xAxisPadding = xAxisTickLength + 1 + axesLabelFontSize;
00072         imageWidth = numTimeSteps + yAxisPadding + 1;
00073         imageHeight = maxY - minY;
00074         bufferImage = new QImage(imageWidth, imageHeight, QImage::Format_RGB32);
00075         bufferImage->fill(backgroundColor);
00076         updateAxes = true;
00077 
00078         //Set up widget graphic properties
00079         if(imageWidth > 500)
00080                 setMinimumWidth(500);
00081         else
00082                 setMinimumWidth(imageWidth);
00083         if(imageHeight > 500)
00084                 setMinimumHeight(500);
00085         else
00086                 setMinimumHeight(imageHeight);
00087 
00088         widgetWidth = this->size().width();
00089         widgetHeight = this->size().height();
00090 }
00091 
00092 
00094 void AbstractGraphWidget::mouseDoubleClickEvent (QMouseEvent*){
00095         QString fileType = "BMP";
00096         QString filePath = getFilePath("*." + fileType.toLower());
00097 
00098         //Fix extension
00099         if(!filePath.endsWith(fileType.toLower()))
00100                 filePath += "." + fileType.toLower();
00101 
00102         //If file exists, check to see if user wants to overwrite file
00103         if(QFile::exists(filePath)){
00104                 int response = QMessageBox::warning(this, "Overwrite File?", filePath + " already exists.\nAre you sure that you want to overwrite it?", QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
00105                 if(response != QMessageBox::Ok)
00106                         return;
00107         }
00108 
00109         //Save file
00110         bufferImage->save(filePath, fileType.toAscii(), 100);
00111 }
00112 
00113 
00114 //Inherited from QWidget
00115 void AbstractGraphWidget::paintEvent(QPaintEvent*){
00116         QPainter painter(this);
00117         if(bufferImage != NULL){
00118                 QPainter imagePainter(bufferImage);
00119                 if(updateAxes){
00120                         paintAxes(imagePainter);
00121                         paintLabels(imagePainter);
00122                 }
00123                 paintData(imagePainter);
00124                 painter.drawImage(0, 0, bufferImage->scaled(widgetWidth, widgetHeight));
00125         }
00126         painter.end();
00127 }
00128 
00129 
00130 //Inherited from QWidget
00131 void AbstractGraphWidget::resizeEvent(QResizeEvent*) {
00132         widgetWidth = this->size().width();
00133         widgetHeight = this->size().height();
00134 }
00135 
00136 
00137 /*----------------------------------------------------------*/
00138 /*------              PRIVATE METHODS                 ------*/
00139 /*----------------------------------------------------------*/
00140 
00142 QString AbstractGraphWidget::getFilePath(QString fileFilter){
00143         QFileDialog dialog(this);
00144         dialog.setDirectory(Globals::getWorkingDirectory());
00145         dialog.setFileMode(QFileDialog::AnyFile);
00146         dialog.setNameFilter( QString("Image file (" + fileFilter + ")") );
00147         dialog.setWindowTitle("Save");
00148         dialog.setViewMode(QFileDialog::Detail);
00149         QStringList fileNames;
00150         if (dialog.exec())
00151                 fileNames = dialog.selectedFiles();
00152         if(fileNames.size() > 0)
00153                 return fileNames[0];
00154         else
00155                 return QString("");
00156 }
00157 
00158 
00160 void AbstractGraphWidget::increaseTimeStep(int currentTimeStep){
00161         //Check to see if we have moved out of the X axis range
00162         if( ((currentTimeStep /numTimeSteps) * numTimeSteps) != minTimeStep){
00163                 minTimeStep = (currentTimeStep/numTimeSteps) * numTimeSteps;
00164                 bufferImage->fill(backgroundColor);
00165                 updateAxes = true;
00166         }
00167 }
00168 
00169 
00171 void AbstractGraphWidget::paintAxes(QPainter& painter) {
00172         //Set up drawing attributes
00173         painter.setPen( QPen(axesColor) );
00174         QFont font;
00175         font.setFamily("Helvetica");
00176         font.setWeight(QFont::Light);
00177         font.setPixelSize(axesLabelFontSize);
00178         painter.setFont(font);
00179 
00180         //Paint axes
00181         paintYAxis(painter);
00182         paintXAxis(painter);
00183 
00184         //Set flag recording that axes are updated
00185         updateAxes = false;
00186 }
00187 
00188 
00190 void AbstractGraphWidget::paintXAxis(QPainter& painter) {
00191         //Draw X axis line
00192         if(minY < 0 && Util::toPositive(minY) > xAxisPadding)
00193                 painter.drawLine(0, imageHeight + minY, imageWidth, imageHeight + minY);
00194         else
00195                 painter.drawLine(0, imageHeight - xAxisPadding, imageWidth, imageHeight - xAxisPadding);
00196 
00197         //Draw ticks
00198         for(int i=0; i<numTimeSteps; i += numTimeSteps/10)
00199                 paintXAxisTick(painter, i + yAxisPadding, minTimeStep + i);
00200 }
00201 
00202 
00204 void AbstractGraphWidget::paintXAxisTick(QPainter& painter, int xPos, int labelX) {
00205         int xAxisLocation;
00206         if(minY < 0 && Util::toPositive(minY) > xAxisPadding)
00207                 xAxisLocation = imageHeight + minY;
00208         else
00209                 xAxisLocation = imageHeight - xAxisPadding;
00210 
00211         painter.drawLine(xPos,
00212                                          xAxisLocation,
00213                                          xPos,
00214                                          xAxisLocation + xAxisTickLength
00215         );
00216         int textW = axesLabelFontSize*5;
00217         painter.drawText(
00218                         xPos - textW/2, xAxisLocation + xAxisTickLength,
00219                         textW, axesLabelFontSize,
00220                         Qt::AlignHCenter,
00221                         QString::number(labelX) + "ms"
00222         );
00223 }
00224 
00225 
00227 void AbstractGraphWidget::paintYAxisTick(QPainter& painter, int yPos, int label) {
00228         painter.drawLine(yAxisPadding, yPos, yAxisPadding - yAxisTickLength, yPos);
00229         painter.drawText(
00230                         0, yPos + axesLabelFontSize/2,
00231                         QString::number(label)
00232         );
00233 }
00234 
00235 
00237 void AbstractGraphWidget::paintYAxis(QPainter& painter){
00238         //Draw Y axis line
00239         painter.drawLine(yAxisPadding, 0, yAxisPadding, imageHeight);
00240 
00241         //Draw ticks
00242         for(int i=0; i< maxY-minY; i += (maxY - minY)/10){
00243                 paintYAxisTick(painter, imageHeight - i, i+minY);
00244         }
00245 }
00246 
00247 
 All Classes Files Functions Variables Typedefs Friends Defines