/* * Copyright (c) 2004 Kivio Team * Copyright (c) 2004 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tqlayout.h" #include "tqlabel.h" #include "tqpixmap.h" #include "tqpainter.h" #include "tqimage.h" #include "config.h" #include LCMS_HEADER #include "klocale.h" #include "tqtooltip.h" #include "kis_view.h" #include "kis_doc.h" #include "kis_canvas_controller.h" #include "kis_birdeye_box.h" #include "kis_double_widget.h" #include "kis_canvas.h" #include "kis_image.h" #include "kis_rect.h" #include "kis_iterators_pixel.h" #include "kobirdeyepanel.h" namespace { class CanvasAdapter : public KoCanvasAdapter { public: CanvasAdapter(KisCanvasSubject * canvasSubject) : KoCanvasAdapter(), m_canvasSubject(canvasSubject) {} virtual ~CanvasAdapter() {} public: virtual KoRect visibleArea() { if (!m_canvasSubject->currentImg()) return KoRect(0,0,0,0); KisCanvasController * c = m_canvasSubject->canvasController(); if (c && c->kiscanvas()) return c->viewToWindow(KisRect(0, 0, c->kiscanvas()->width(), c->kiscanvas()->height())); else return KoRect(0,0,0,0); } virtual double zoomFactor() { return m_canvasSubject->zoomFactor(); } virtual TQRect size() { if (!m_canvasSubject->currentImg()) return TQRect(0,0,0,0); return TQRect(0, 0, m_canvasSubject->currentImg()->width(), m_canvasSubject->currentImg()->height()); } virtual void setViewCenterPoint(double x, double y) { m_canvasSubject->canvasController()->zoomAroundPoint(x, y, m_canvasSubject->zoomFactor()); } private: KisCanvasSubject * m_canvasSubject; }; class ZoomListener : public KoZoomAdapter { public: ZoomListener(KisCanvasController * canvasController) : KoZoomAdapter() , m_canvasController(canvasController) {} virtual ~ZoomListener() {} public: void zoomTo( double x, double y, double factor ) { m_canvasController->zoomAroundPoint(x, y, factor); } void zoomIn() { m_canvasController->zoomIn(); } void zoomOut() { m_canvasController->zoomOut(); } double getMinZoom() { return (1.0 / 500); } double getMaxZoom() { return 16.0; } private: KisCanvasController * m_canvasController; }; class ThumbnailProvider : public KoThumbnailAdapter { public: ThumbnailProvider(KisImageSP image, KisCanvasSubject* canvasSubject) : KoThumbnailAdapter() , m_image(image) , m_canvasSubject(canvasSubject) {} virtual ~ThumbnailProvider() {} public: virtual TQSize pixelSize() { if (!m_image) return TQSize(0, 0); return TQSize(m_image->width(), m_image->height()); } virtual TQImage image(TQRect r, TQSize thumbnailSize) { if (!m_image || r.isEmpty() || thumbnailSize.width() == 0 || thumbnailSize.height() == 0) { return TQImage(); } KisPaintDevice thumbnailRect(m_image->colorSpace(), "thumbnailRect"); KisPaintDeviceSP mergedImage = m_image->projection(); TQ_INT32 imageWidth = m_image->width(); TQ_INT32 imageHeight = m_image->height(); TQ_UINT32 pixelSize = m_image->colorSpace()->pixelSize(); for (TQ_INT32 y = 0; y < r.height(); ++y) { KisHLineIteratorPixel it = thumbnailRect.createHLineIterator(0, y, r.width(), true); TQ_INT32 thumbnailY = r.y() + y; TQ_INT32 thumbnailX = r.x(); TQ_INT32 imageY = (thumbnailY * imageHeight) / thumbnailSize.height(); KisHLineIteratorPixel srcIt = mergedImage -> createHLineIterator(0, imageY, imageWidth, false); while (!it.isDone()) { TQ_INT32 imageX = (thumbnailX * imageWidth) / thumbnailSize.width(); TQ_INT32 dx = imageX - srcIt.x(); srcIt += dx; //KisColor pixelColor = mergedImage->colorAt(imageX, imageY); memcpy(it.rawData(), srcIt.rawData(), pixelSize); ++it; ++thumbnailX; } } return thumbnailRect.convertToTQImage(m_canvasSubject->monitorProfile(), 0, 0, r.width(), r.height(), m_canvasSubject->HDRExposure()); } void setImage(KisImageSP image) { m_image = image; } private: KisImageSP m_image; KisCanvasSubject * m_canvasSubject; }; } KisBirdEyeBox::KisBirdEyeBox(KisView * view, TQWidget* parent, const char* name) : TQWidget(parent, name) , m_view(view) , m_subject(view->canvasSubject()) { TQVBoxLayout * l = new TQVBoxLayout(this); m_image = m_subject->currentImg(); m_zoomAdapter = new ZoomListener(m_subject->canvasController()); // The birdeye panel deletes KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject); // The birdeye panel deletes KoCanvasAdapter * kpc = new CanvasAdapter(m_subject); // The birdeye panel deletes m_birdEyePanel = new KoBirdEyePanel(m_zoomAdapter, ktp, kpc, this); connect(view, TQT_SIGNAL(cursorPosition( TQ_INT32, TQ_INT32 )), m_birdEyePanel, TQT_SLOT(cursorPosChanged( TQ_INT32, TQ_INT32 ))); connect(view, TQT_SIGNAL(viewTransformationsChanged()), m_birdEyePanel, TQT_SLOT(slotViewTransformationChanged())); l->addWidget(m_birdEyePanel); TQHBoxLayout * hl = new TQHBoxLayout(l); m_exposureLabel = new TQLabel(i18n("Exposure:"), this); hl->addWidget(m_exposureLabel); m_exposureDoubleWidget = new KisDoubleWidget(-10, 10, this); m_exposureDoubleWidget->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed); hl->addWidget(m_exposureDoubleWidget); TQToolTip::add(m_exposureDoubleWidget, i18n("Select the exposure (stops) for HDR images")); l->addItem(new TQSpacerItem(0, 1, TQSizePolicy::Minimum, TQSizePolicy::MinimumExpanding)); m_exposureDoubleWidget->setPrecision(1); m_exposureDoubleWidget->setValue(0); m_exposureDoubleWidget->setLineStep(0.1); m_exposureDoubleWidget->setPageStep(1); connect(m_exposureDoubleWidget, TQT_SIGNAL(valueChanged(double)), TQT_SLOT(exposureValueChanged(double))); connect(m_exposureDoubleWidget, TQT_SIGNAL(sliderPressed()), TQT_SLOT(exposureSliderPressed())); connect(m_exposureDoubleWidget, TQT_SIGNAL(sliderReleased()), TQT_SLOT(exposureSliderReleased())); m_draggingExposureSlider = false; Q_ASSERT(m_subject->document() != 0); connect(m_subject->document(), TQT_SIGNAL(sigCommandExecuted()), TQT_SLOT(slotDocCommandExecuted())); if (m_image) { connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(slotImageUpdated(TQRect))); } } KisBirdEyeBox::~KisBirdEyeBox() { // Huh? Why does this cause a crash? // delete m_zoomAdapter; } void KisBirdEyeBox::setImage(KisImageSP image) { if (m_image) { m_image->disconnect(this); } m_image = image; KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject); m_birdEyePanel->setThumbnailProvider(ktp); if (m_image) { connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(slotImageUpdated(TQRect))); connect(m_image, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQT_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32))); connect(m_image, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace *)), TQT_SLOT(slotImageColorSpaceChanged(KisColorSpace *))); m_birdEyePanel->slotUpdate(m_image->bounds()); slotImageColorSpaceChanged(m_image->colorSpace()); } } void KisBirdEyeBox::slotDocCommandExecuted() { if (m_image) { if (!m_dirtyRect.isEmpty()) { m_birdEyePanel->slotUpdate(m_dirtyRect); } m_dirtyRect = TQRect(); } } void KisBirdEyeBox::slotImageUpdated(TQRect r) { m_dirtyRect |= r; } void KisBirdEyeBox::slotImageSizeChanged(TQ_INT32 /*w*/, TQ_INT32 /*h*/) { if (m_image) { m_birdEyePanel->slotUpdate(m_image->bounds()); } } void KisBirdEyeBox::slotImageColorSpaceChanged(KisColorSpace *cs) { if (cs->hasHighDynamicRange()) { m_exposureDoubleWidget->show(); m_exposureLabel->show(); } else { m_exposureDoubleWidget->hide(); m_exposureLabel->hide(); } } void KisBirdEyeBox::exposureValueChanged(double exposure) { if (!m_draggingExposureSlider) { m_subject->setHDRExposure(exposure); if (m_image && m_image->colorSpace()->hasHighDynamicRange()) { m_birdEyePanel->slotUpdate(m_image->bounds()); } } } void KisBirdEyeBox::exposureSliderPressed() { m_draggingExposureSlider = true; } void KisBirdEyeBox::exposureSliderReleased() { m_draggingExposureSlider = false; exposureValueChanged(m_exposureDoubleWidget->value()); } #include "kis_birdeye_box.moc"