SpikeStream Application Library
0.2
|
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