00001
00002
00003
00004
00005
00006
00007 #include "CmdMediator.h"
00008 #include "CmdSettingsColorFilter.h"
00009 #include "ColorFilter.h"
00010 #include "ColorFilterHistogram.h"
00011 #include "DigitizeStateContext.h"
00012 #include "DigitizeStateColorPicker.h"
00013 #include "DocumentModelColorFilter.h"
00014 #include "EngaugeAssert.h"
00015 #include "Logger.h"
00016 #include "MainWindow.h"
00017 #include <QBitmap>
00018 #include <QGraphicsPixmapItem>
00019 #include <QGraphicsScene>
00020 #include <QImage>
00021 #include <QMessageBox>
00022
00023 DigitizeStateColorPicker::DigitizeStateColorPicker (DigitizeStateContext &context) :
00024 DigitizeStateAbstractBase (context)
00025 {
00026 }
00027
00028 DigitizeStateColorPicker::~DigitizeStateColorPicker ()
00029 {
00030 }
00031
00032 QString DigitizeStateColorPicker::activeCurve () const
00033 {
00034 return context().mainWindow().selectedGraphCurve();
00035 }
00036
00037 void DigitizeStateColorPicker::begin (CmdMediator *cmdMediator,
00038 DigitizeState previousState)
00039 {
00040 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::begin";
00041
00042 setCursor(cmdMediator);
00043 context().setDragMode(QGraphicsView::NoDrag);
00044
00045
00046 m_previousDigitizeState = previousState;
00047 m_previousBackground = context().mainWindow().selectOriginal(BACKGROUND_IMAGE_ORIGINAL);
00048
00049 context().mainWindow().updateViewsOfSettings(activeCurve ());
00050 }
00051
00052 bool DigitizeStateColorPicker::canPaste (const Transformation & ,
00053 const QSize & ) const
00054 {
00055 return false;
00056 }
00057
00058 bool DigitizeStateColorPicker::computeFilterFromPixel (CmdMediator *cmdMediator,
00059 const QPointF &posScreen,
00060 const QString &curveName,
00061 DocumentModelColorFilter &modelColorFilterAfter)
00062 {
00063 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::computeFilterFromPixel";
00064
00065 bool rtn = false;
00066
00067
00068 ColorFilter filter;
00069 QImage image = cmdMediator->document().pixmap().toImage();
00070 QRgb rgbBackground = filter.marginColor(&image);
00071
00072
00073 QPointF posScreenPlusHalf = posScreen - QPointF (0.5, 0.5);
00074
00075 QColor pixel;
00076 rtn = findNearestNonBackgroundPixel (cmdMediator,
00077 image,
00078 posScreenPlusHalf,
00079 rgbBackground,
00080 pixel);
00081 if (rtn) {
00082
00083
00084
00085 int r = qRed (pixel.rgb());
00086 int g = qGreen (pixel.rgb());
00087 int b = qBlue (pixel.rgb());
00088 if (r == g && g == b) {
00089
00090
00091 modelColorFilterAfter.setColorFilterMode (curveName,
00092 COLOR_FILTER_MODE_INTENSITY);
00093
00094 } else {
00095
00096
00097 modelColorFilterAfter.setColorFilterMode (curveName,
00098 COLOR_FILTER_MODE_HUE);
00099
00100 }
00101
00102
00103 double *histogramBins = new double [ColorFilterHistogram::HISTOGRAM_BINS ()];
00104
00105 ColorFilterHistogram filterHistogram;
00106 int maxBinCount;
00107 filterHistogram.generate (filter,
00108 histogramBins,
00109 modelColorFilterAfter.colorFilterMode (curveName),
00110 image,
00111 maxBinCount);
00112
00113
00114 int pixelBin = filterHistogram.binFromPixel(filter,
00115 modelColorFilterAfter.colorFilterMode (curveName),
00116 pixel,
00117 rgbBackground);
00118
00119
00120
00121 int lowerBin = pixelBin, upperBin = pixelBin;
00122 while ((lowerBin > 0) &&
00123 (histogramBins [lowerBin - 1] <= histogramBins [lowerBin]) &&
00124 (histogramBins [lowerBin] > 0)) {
00125 --lowerBin;
00126 }
00127 while ((upperBin < ColorFilterHistogram::HISTOGRAM_BINS () - 1) &&
00128 (histogramBins [upperBin + 1] <= histogramBins [upperBin]) &&
00129 (histogramBins [upperBin] > 0)) {
00130 ++upperBin;
00131 }
00132
00133
00134 int lowerValue = filterHistogram.valueFromBin(filter,
00135 modelColorFilterAfter.colorFilterMode (curveName),
00136 lowerBin);
00137 int upperValue = filterHistogram.valueFromBin(filter,
00138 modelColorFilterAfter.colorFilterMode (curveName),
00139 upperBin);
00140
00141 saveLowerValueUpperValue (modelColorFilterAfter,
00142 curveName,
00143 lowerValue,
00144 upperValue);
00145
00146 delete [] histogramBins;
00147
00148 } else {
00149
00150 QMessageBox::warning (0,
00151 QObject::tr ("Color Picker"),
00152 QObject::tr ("Sorry, but the color picker point must be near a non-background pixel. Please try again."));
00153
00154 }
00155
00156 return rtn;
00157 }
00158
00159 QCursor DigitizeStateColorPicker::cursor(CmdMediator * ) const
00160 {
00161
00162 const int HOT_X_IN_BITMAP = 8;
00163 const int HOT_Y_IN_BITMAP = 24;
00164 LOG4CPP_DEBUG_S ((*mainCat)) << "DigitizeStateColorPicker::cursor";
00165
00166 QBitmap bitmap (":/engauge/img/cursor_eyedropper.xpm");
00167 QBitmap bitmapMask (":/engauge/img/cursor_eyedropper_mask.xpm");
00168 return QCursor (bitmap,
00169 bitmapMask,
00170 HOT_X_IN_BITMAP,
00171 HOT_Y_IN_BITMAP);
00172 }
00173
00174 void DigitizeStateColorPicker::end ()
00175 {
00176 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::end";
00177
00178
00179
00180 context().mainWindow().selectOriginal(m_previousBackground);
00181 }
00182
00183 bool DigitizeStateColorPicker::findNearestNonBackgroundPixel (CmdMediator *cmdMediator,
00184 const QImage &image,
00185 const QPointF &posScreenPlusHalf,
00186 const QRgb &rgbBackground,
00187 QColor &pixel)
00188 {
00189 QPoint pos = posScreenPlusHalf.toPoint ();
00190
00191 int maxRadiusForSearch = cmdMediator->document().modelGeneral().cursorSize();
00192
00193
00194 for (int radius = 0; radius < maxRadiusForSearch; radius++) {
00195
00196 for (int xOffset = -radius; xOffset <= radius; xOffset++) {
00197 for (int yOffset = -radius; yOffset <= radius; yOffset++) {
00198
00199
00200 pixel = image.pixel (pos.x () + xOffset, pos.y () - radius);
00201 if (pixel != rgbBackground) {
00202 return true;
00203 }
00204
00205
00206 pixel = image.pixel (pos.x () + xOffset, pos.y () + radius);
00207 if (pixel != rgbBackground) {
00208 return true;
00209 }
00210
00211
00212 pixel = image.pixel (pos.x () - radius, pos.y () - yOffset);
00213 if (pixel != rgbBackground) {
00214 return true;
00215 }
00216
00217
00218 pixel = image.pixel (pos.x () + radius, pos.y () + yOffset);
00219 if (pixel != rgbBackground) {
00220 return true;
00221 }
00222 }
00223 }
00224 }
00225
00226 return false;
00227 }
00228
00229 void DigitizeStateColorPicker::handleContextMenuEventAxis (CmdMediator * ,
00230 const QString &pointIdentifier)
00231 {
00232 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::handleContextMenuEventAxis "
00233 << " point=" << pointIdentifier.toLatin1 ().data ();
00234 }
00235
00236 void DigitizeStateColorPicker::handleContextMenuEventGraph (CmdMediator * ,
00237 const QStringList &pointIdentifiers)
00238 {
00239 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker ::handleContextMenuEventGraph "
00240 << "points=" << pointIdentifiers.join(",").toLatin1 ().data ();
00241 }
00242
00243 void DigitizeStateColorPicker::handleCurveChange(CmdMediator * )
00244 {
00245 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::handleCurveChange";
00246 }
00247
00248 void DigitizeStateColorPicker::handleKeyPress (CmdMediator * ,
00249 Qt::Key key,
00250 bool )
00251 {
00252 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::handleKeyPress"
00253 << " key=" << QKeySequence (key).toString ().toLatin1 ().data ();
00254 }
00255
00256 void DigitizeStateColorPicker::handleMouseMove (CmdMediator * ,
00257 QPointF )
00258 {
00259
00260 }
00261
00262 void DigitizeStateColorPicker::handleMousePress (CmdMediator * ,
00263 QPointF )
00264 {
00265 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::handleMousePress";
00266 }
00267
00268 void DigitizeStateColorPicker::handleMouseRelease (CmdMediator *cmdMediator,
00269 QPointF posScreen)
00270 {
00271 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::handleMouseRelease";
00272
00273 DocumentModelColorFilter modelColorFilterBefore = cmdMediator->document().modelColorFilter();
00274 DocumentModelColorFilter modelColorFilterAfter = cmdMediator->document().modelColorFilter();
00275 if (computeFilterFromPixel (cmdMediator,
00276 posScreen,
00277 context().mainWindow().selectedGraphCurve(),
00278 modelColorFilterAfter)) {
00279
00280
00281 context().requestDelayedStateTransition(m_previousDigitizeState);
00282
00283
00284 QUndoCommand *cmd = new CmdSettingsColorFilter (context ().mainWindow(),
00285 cmdMediator->document (),
00286 modelColorFilterBefore,
00287 modelColorFilterAfter);
00288 context().appendNewCmd(cmdMediator,
00289 cmd);
00290 }
00291 }
00292
00293 void DigitizeStateColorPicker::saveLowerValueUpperValue (DocumentModelColorFilter &modelColorFilterAfter,
00294 const QString &curveName,
00295 double lowerValue,
00296 double upperValue)
00297 {
00298 switch (modelColorFilterAfter.colorFilterMode (curveName)) {
00299 case COLOR_FILTER_MODE_FOREGROUND:
00300 modelColorFilterAfter.setForegroundLow(curveName,
00301 lowerValue);
00302 modelColorFilterAfter.setForegroundHigh(curveName,
00303 upperValue);
00304 break;
00305
00306 case COLOR_FILTER_MODE_HUE:
00307 modelColorFilterAfter.setHueLow(curveName,
00308 lowerValue);
00309 modelColorFilterAfter.setHueHigh(curveName,
00310 upperValue);
00311 break;
00312
00313 case COLOR_FILTER_MODE_INTENSITY:
00314 modelColorFilterAfter.setIntensityLow(curveName,
00315 lowerValue);
00316 modelColorFilterAfter.setIntensityHigh(curveName,
00317 upperValue);
00318 break;
00319
00320 case COLOR_FILTER_MODE_SATURATION:
00321 modelColorFilterAfter.setSaturationLow(curveName,
00322 lowerValue);
00323 modelColorFilterAfter.setSaturationHigh(curveName,
00324 upperValue);
00325 break;
00326
00327 case COLOR_FILTER_MODE_VALUE:
00328 modelColorFilterAfter.setValueLow(curveName,
00329 lowerValue);
00330 modelColorFilterAfter.setValueHigh(curveName,
00331 upperValue);
00332 break;
00333
00334 default:
00335 ENGAUGE_ASSERT (false);
00336 }
00337 }
00338
00339 QString DigitizeStateColorPicker::state() const
00340 {
00341 return "DigitizeStateColorPicker";
00342 }
00343
00344 void DigitizeStateColorPicker::updateAfterPointAddition ()
00345 {
00346 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::updateAfterPointAddition";
00347 }
00348
00349 void DigitizeStateColorPicker::updateModelDigitizeCurve (CmdMediator * ,
00350 const DocumentModelDigitizeCurve & )
00351 {
00352 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::updateModelDigitizeCurve";
00353 }
00354
00355 void DigitizeStateColorPicker::updateModelSegments(const DocumentModelSegments & )
00356 {
00357 LOG4CPP_INFO_S ((*mainCat)) << "DigitizeStateColorPicker::updateModelSegments";
00358 }