00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "qlayout.h"
00021 #include "qlabel.h"
00022 #include "qpixmap.h"
00023 #include "qpainter.h"
00024 #include "qimage.h"
00025 #include "config.h"
00026 #include LCMS_HEADER
00027 #include "klocale.h"
00028
00029 #include "kis_view.h"
00030 #include "kis_doc.h"
00031 #include "kis_canvas_controller.h"
00032 #include "kis_birdeye_box.h"
00033 #include "kis_double_widget.h"
00034 #include "kis_canvas.h"
00035 #include "kis_image.h"
00036 #include "kis_rect.h"
00037 #include "kis_iterators_pixel.h"
00038
00039 #include "kobirdeyepanel.h"
00040
00041 namespace {
00042
00043 class CanvasAdapter : public KoCanvasAdapter {
00044
00045 public:
00046 CanvasAdapter(KisCanvasSubject * canvasSubject) : KoCanvasAdapter(), m_canvasSubject(canvasSubject) {}
00047 virtual ~CanvasAdapter() {}
00048
00049 public:
00050
00051 virtual KoRect visibleArea()
00052 {
00053 if (!m_canvasSubject->currentImg()) return KoRect(0,0,0,0);
00054
00055 KisCanvasController * c = m_canvasSubject->canvasController();
00056
00057 if (c && c->kiscanvas())
00058 return c->viewToWindow(KisRect(0, 0, c->kiscanvas()->width(), c->kiscanvas()->height()));
00059 else
00060 return KoRect(0,0,0,0);
00061 }
00062
00063 virtual double zoomFactor()
00064 {
00065 return m_canvasSubject->zoomFactor();
00066 }
00067
00068 virtual QRect size()
00069 {
00070 if (!m_canvasSubject->currentImg()) return QRect(0,0,0,0);
00071
00072 return QRect(0, 0, m_canvasSubject->currentImg()->width(), m_canvasSubject->currentImg()->height());
00073 }
00074
00075 virtual void setViewCenterPoint(double x, double y)
00076 {
00077 m_canvasSubject->canvasController()->zoomAroundPoint(x, y, m_canvasSubject->zoomFactor());
00078 }
00079
00080 private:
00081
00082 KisCanvasSubject * m_canvasSubject;
00083
00084 };
00085
00086 class ZoomListener : public KoZoomAdapter {
00087
00088 public:
00089
00090 ZoomListener(KisCanvasController * canvasController)
00091 : KoZoomAdapter()
00092 , m_canvasController(canvasController) {}
00093 virtual ~ZoomListener() {}
00094
00095 public:
00096
00097 void zoomTo( double x, double y, double factor ) { m_canvasController->zoomAroundPoint(x, y, factor); }
00098 void zoomIn() { m_canvasController->zoomIn(); }
00099 void zoomOut() { m_canvasController->zoomOut(); }
00100 double getMinZoom() { return (1.0 / 500); }
00101 double getMaxZoom() { return 16.0; }
00102
00103 private:
00104
00105 KisCanvasController * m_canvasController;
00106
00107 };
00108
00109 class ThumbnailProvider : public KoThumbnailAdapter {
00110
00111 public:
00112 ThumbnailProvider(KisImageSP image, KisCanvasSubject* canvasSubject)
00113 : KoThumbnailAdapter()
00114 , m_image(image)
00115 , m_canvasSubject(canvasSubject) {}
00116
00117 virtual ~ThumbnailProvider() {}
00118
00119 public:
00120
00121 virtual QSize pixelSize()
00122 {
00123 if (!m_image) return QSize(0, 0);
00124 return QSize(m_image->width(), m_image->height());
00125 }
00126
00127 virtual QImage image(QRect r, QSize thumbnailSize)
00128 {
00129 if (!m_image || r.isEmpty() || thumbnailSize.width() == 0 || thumbnailSize.height() == 0) {
00130 return QImage();
00131 }
00132
00133 KisPaintDevice thumbnailRect(m_image->colorSpace(), "thumbnailRect");
00134 KisPaintDeviceSP mergedImage = m_image->projection();
00135
00136 Q_INT32 imageWidth = m_image->width();
00137 Q_INT32 imageHeight = m_image->height();
00138 Q_UINT32 pixelSize = m_image->colorSpace()->pixelSize();
00139
00140 for (Q_INT32 y = 0; y < r.height(); ++y) {
00141
00142 KisHLineIterator it = thumbnailRect.createHLineIterator(0, y, r.width(), true);
00143 Q_INT32 thumbnailY = r.y() + y;
00144 Q_INT32 thumbnailX = r.x();
00145 Q_INT32 imageY = (thumbnailY * imageHeight) / thumbnailSize.height();
00146
00147 while (!it.isDone()) {
00148
00149 Q_INT32 imageX = (thumbnailX * imageWidth) / thumbnailSize.width();
00150
00151 KisColor pixelColor = mergedImage->colorAt(imageX, imageY);
00152 memcpy(it.rawData(), pixelColor.data(), pixelSize);
00153
00154 ++it;
00155 ++thumbnailX;
00156 }
00157 }
00158
00159 return thumbnailRect.convertToQImage(m_canvasSubject->monitorProfile(), 0, 0, r.width(), r.height(),
00160 m_canvasSubject->HDRExposure());
00161 }
00162
00163 void setImage(KisImageSP image)
00164 {
00165 m_image = image;
00166 }
00167 private:
00168
00169 KisImageSP m_image;
00170 KisCanvasSubject * m_canvasSubject;
00171
00172 };
00173
00174 }
00175
00176 KisBirdEyeBox::KisBirdEyeBox(KisView * view, QWidget* parent, const char* name)
00177 : QWidget(parent, name)
00178 , m_view(view)
00179 , m_subject(view->canvasSubject())
00180 {
00181 QVBoxLayout * l = new QVBoxLayout(this);
00182
00183 m_image = m_subject->currentImg();
00184
00185 m_zoomAdapter = new ZoomListener(m_subject->canvasController());
00186 KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject);
00187 KoCanvasAdapter * kpc = new CanvasAdapter(m_subject);
00188
00189 m_birdEyePanel = new KoBirdEyePanel(m_zoomAdapter, ktp, kpc, this);
00190
00191 connect(view, SIGNAL(cursorPosition( Q_INT32, Q_INT32 )), m_birdEyePanel, SLOT(cursorPosChanged( Q_INT32, Q_INT32 )));
00192 connect(view, SIGNAL(viewTransformationsChanged()), m_birdEyePanel, SLOT(slotViewTransformationChanged()));
00193
00194 l->addWidget(m_birdEyePanel);
00195
00196 QHBoxLayout * hl = new QHBoxLayout(l);
00197
00198 m_exposureLabel = new QLabel(i18n("Exposure:"), this);
00199 hl->addWidget(m_exposureLabel);
00200
00201 m_exposureDoubleWidget = new KisDoubleWidget(-10, 10, this);
00202 m_exposureDoubleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00203 hl->addWidget(m_exposureDoubleWidget);
00204
00205 l->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding));
00206
00207 m_exposureDoubleWidget->setPrecision(1);
00208 m_exposureDoubleWidget->setValue(0);
00209 m_exposureDoubleWidget->setLineStep(0.1);
00210 m_exposureDoubleWidget->setPageStep(1);
00211
00212 connect(m_exposureDoubleWidget, SIGNAL(valueChanged(double)), SLOT(exposureValueChanged(double)));
00213 connect(m_exposureDoubleWidget, SIGNAL(sliderPressed()), SLOT(exposureSliderPressed()));
00214 connect(m_exposureDoubleWidget, SIGNAL(sliderReleased()), SLOT(exposureSliderReleased()));
00215
00216 m_draggingExposureSlider = false;
00217
00218 Q_ASSERT(m_subject->document() != 0);
00219 connect(m_subject->document(), SIGNAL(sigCommandExecuted()), SLOT(slotDocCommandExecuted()));
00220
00221 if (m_image) {
00222 connect(m_image, SIGNAL(sigImageUpdated(QRect)), SLOT(slotImageUpdated(QRect)));
00223 }
00224 }
00225
00226 KisBirdEyeBox::~KisBirdEyeBox()
00227 {
00228
00229
00230 }
00231
00232 void KisBirdEyeBox::setImage(KisImageSP image)
00233 {
00234 if (m_image) {
00235 m_image->disconnect(this);
00236 }
00237
00238 m_image = image;
00239
00240 KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject);
00241 m_birdEyePanel->setThumbnailProvider(ktp);
00242
00243 if (m_image) {
00244 connect(m_image, SIGNAL(sigImageUpdated(QRect)), SLOT(slotImageUpdated(QRect)));
00245 connect(m_image, SIGNAL(sigSizeChanged(Q_INT32, Q_INT32)), SLOT(slotImageSizeChanged(Q_INT32, Q_INT32)));
00246 connect(m_image, SIGNAL(sigColorSpaceChanged(KisColorSpace *)), SLOT(slotImageColorSpaceChanged(KisColorSpace *)));
00247 m_birdEyePanel->slotUpdate(m_image->bounds());
00248 slotImageColorSpaceChanged(m_image->colorSpace());
00249 }
00250 }
00251
00252 void KisBirdEyeBox::slotDocCommandExecuted()
00253 {
00254 if (m_image) {
00255 if (!m_dirtyRect.isEmpty()) {
00256 m_birdEyePanel->slotUpdate(m_dirtyRect);
00257 }
00258 m_dirtyRect = QRect();
00259 }
00260 }
00261
00262 void KisBirdEyeBox::slotImageUpdated(QRect r)
00263 {
00264 m_dirtyRect |= r;
00265 }
00266
00267 void KisBirdEyeBox::slotImageSizeChanged(Q_INT32 , Q_INT32 )
00268 {
00269 if (m_image) {
00270 m_birdEyePanel->slotUpdate(m_image->bounds());
00271 }
00272 }
00273
00274 void KisBirdEyeBox::slotImageColorSpaceChanged(KisColorSpace *cs)
00275 {
00276 if (cs->hasHighDynamicRange()) {
00277 m_exposureDoubleWidget->show();
00278 m_exposureLabel->show();
00279 } else {
00280 m_exposureDoubleWidget->hide();
00281 m_exposureLabel->hide();
00282 }
00283 }
00284
00285 void KisBirdEyeBox::exposureValueChanged(double exposure)
00286 {
00287 if (!m_draggingExposureSlider) {
00288 m_subject->setHDRExposure(exposure);
00289
00290 if (m_image && m_image->colorSpace()->hasHighDynamicRange()) {
00291 m_birdEyePanel->slotUpdate(m_image->bounds());
00292 }
00293 }
00294 }
00295
00296 void KisBirdEyeBox::exposureSliderPressed()
00297 {
00298 m_draggingExposureSlider = true;
00299 }
00300
00301 void KisBirdEyeBox::exposureSliderReleased()
00302 {
00303 m_draggingExposureSlider = false;
00304 exposureValueChanged(m_exposureDoubleWidget->value());
00305 }
00306
00307 #include "kis_birdeye_box.moc"