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