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