krita

kis_birdeye_box.cc

00001 /*
00002  *  Copyright (c) 2004 Kivio Team
00003  *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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                             //KisColor pixelColor = mergedImage->colorAt(imageX, imageY);
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()); // The birdeye panel deletes
00190     KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject);  // The birdeye panel deletes
00191     KoCanvasAdapter * kpc = new CanvasAdapter(m_subject);  // The birdeye panel deletes
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     // Huh? Why does this cause a crash?
00233     // delete m_zoomAdapter;
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 /*w*/, Q_INT32 /*h*/)
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"
KDE Home | KDE Accessibility Home | Description of Access Keys