diff options
Diffstat (limited to 'src/libs/widgets/imageplugins')
-rw-r--r-- | src/libs/widgets/imageplugins/Makefile.am | 22 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imageguidewidget.cpp | 625 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imageguidewidget.h | 132 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepanelwidget.cpp | 335 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepanelwidget.h | 117 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepaniconwidget.cpp | 198 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepaniconwidget.h | 68 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepannelwidget.cpp | 477 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagepannelwidget.h | 123 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imageregionwidget.cpp | 473 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imageregionwidget.h | 115 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagewidget.cpp | 347 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/imagewidget.h | 106 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/listboxpreviewitem.cpp | 62 | ||||
-rw-r--r-- | src/libs/widgets/imageplugins/listboxpreviewitem.h | 80 |
15 files changed, 3280 insertions, 0 deletions
diff --git a/src/libs/widgets/imageplugins/Makefile.am b/src/libs/widgets/imageplugins/Makefile.am new file mode 100644 index 00000000..d223cb05 --- /dev/null +++ b/src/libs/widgets/imageplugins/Makefile.am @@ -0,0 +1,22 @@ +METASOURCES = AUTO + +noinst_LTLIBRARIES = libimagepluginswidgets.la + +libimagepluginswidgets_la_SOURCES = imageregionwidget.cpp imagepaniconwidget.cpp imageguidewidget.cpp \ + imagewidget.cpp listboxpreviewitem.cpp imagepanelwidget.cpp + +libimagepluginswidgets_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TQT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/digikam \ + $(LIBKDCRAW_CFLAGS) \ + $(all_includes) + +digikaminclude_HEADERS = imageregionwidget.h imagepaniconwidget.h \ + imagepanelwidget.h imageguidewidget.h \ + listboxpreviewitem.h imagewidget.h + +digikamincludedir = $(includedir)/digikam diff --git a/src/libs/widgets/imageplugins/imageguidewidget.cpp b/src/libs/widgets/imageplugins/imageguidewidget.cpp new file mode 100644 index 00000000..4ed7f254 --- /dev/null +++ b/src/libs/widgets/imageplugins/imageguidewidget.cpp @@ -0,0 +1,625 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-11-16 + * Description : a widget to display an image with guides + * + * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqregion.h> +#include <tqpainter.h> +#include <tqpen.h> +#include <tqpixmap.h> +#include <tqtooltip.h> +#include <tqtimer.h> +#include <tqrect.h> +#include <tqbrush.h> +#include <tqfont.h> +#include <tqfontmetrics.h> + +// KDE includes. + +#include <kstandarddirs.h> +#include <kcursor.h> +#include <tdeglobal.h> + +// Local includes. + +#include "ddebug.h" +#include "dimg.h" +#include "imageiface.h" +#include "imageguidewidget.h" +#include "imageguidewidget.moc" + +namespace Digikam +{ + +class ImageGuideWidgetPriv +{ +public: + + ImageGuideWidgetPriv() + { + pixmap = 0; + iface = 0; + flicker = 0; + timerID = 0; + focus = false; + onMouseMovePreviewToggled = true; + renderingPreviewMode = ImageGuideWidget::NoPreviewMode; + underExposureIndicator = false; + overExposureIndicator = false; + } + + bool sixteenBit; + bool focus; + bool spotVisible; + bool onMouseMovePreviewToggled; + bool underExposureIndicator; + bool overExposureIndicator; + + int width; + int height; + int timerID; + int guideMode; + int guideSize; + int flicker; + int renderingPreviewMode; + + // Current spot position in preview coordinates. + TQPoint spot; + + TQRect rect; + + TQColor guideColor; + + TQPixmap *pixmap; + + ImageIface *iface; + + DImg preview; +}; + +ImageGuideWidget::ImageGuideWidget(int w, int h, TQWidget *parent, + bool spotVisible, int guideMode, + const TQColor& guideColor, int guideSize, + bool blink, bool useImageSelection) + : TQWidget(parent, 0, TQt::WDestructiveClose) +{ + d = new ImageGuideWidgetPriv; + d->spotVisible = spotVisible; + d->guideMode = guideMode; + d->guideColor = guideColor; + d->guideSize = guideSize; + + setBackgroundMode(TQt::NoBackground); + setMinimumSize(w, h); + setMouseTracking(true); + + d->iface = new ImageIface(w, h); + d->iface->setPreviewType(useImageSelection); + uchar *data = d->iface->getPreviewImage(); + d->width = d->iface->previewWidth(); + d->height = d->iface->previewHeight(); + bool sixteenBit = d->iface->previewSixteenBit(); + bool hasAlpha = d->iface->previewHasAlpha(); + d->preview = DImg(d->width, d->height, sixteenBit, hasAlpha, data); + d->preview.setICCProfil( d->iface->getOriginalImg()->getICCProfil() ); + + delete [] data; + + d->pixmap = new TQPixmap(w, h); + d->rect = TQRect(w/2-d->width/2, h/2-d->height/2, d->width, d->height); + + resetSpotPosition(); + setSpotVisible(d->spotVisible, blink); +} + +ImageGuideWidget::~ImageGuideWidget() +{ + delete d->iface; + + if (d->timerID) + killTimer(d->timerID); + + if (d->pixmap) + delete d->pixmap; + + delete d; +} + +ImageIface* ImageGuideWidget::imageIface() +{ + return d->iface; +} + +void ImageGuideWidget::slotToggleUnderExposure(bool u) +{ + d->underExposureIndicator = u; + updatePreview(); +} + +void ImageGuideWidget::slotToggleOverExposure(bool o) +{ + d->overExposureIndicator = o; + updatePreview(); +} + +void ImageGuideWidget::resetSpotPosition() +{ + d->spot.setX( d->width / 2 ); + d->spot.setY( d->height / 2 ); + updatePreview(); +} + +void ImageGuideWidget::slotChangeRenderingPreviewMode(int mode) +{ + d->renderingPreviewMode = mode; + updatePreview(); +} + +int ImageGuideWidget::getRenderingPreviewMode() +{ + return (d->renderingPreviewMode); +} + +TQPoint ImageGuideWidget::getSpotPosition() +{ + return (TQPoint( (int)((float)d->spot.x() * (float)d->iface->originalWidth() / (float)d->width), + (int)((float)d->spot.y() * (float)d->iface->originalHeight() / (float)d->height))); +} + +DColor ImageGuideWidget::getSpotColor(int getColorFrom) +{ + if (getColorFrom == OriginalImage) // Get point color from full original image + return (d->iface->getColorInfoFromOriginalImage(getSpotPosition())); + else if (getColorFrom == PreviewImage) // Get point color from full preview image + return (d->iface->getColorInfoFromPreviewImage(d->spot)); + + // In other cases, get point color from preview target image + return (d->iface->getColorInfoFromTargetPreviewImage(d->spot)); +} + +void ImageGuideWidget::setSpotVisible(bool spotVisible, bool blink) +{ + d->spotVisible = spotVisible; + + if (blink) + { + if (d->spotVisible) + d->timerID = startTimer(800); + else + { + killTimer(d->timerID); + d->timerID = 0; + } + } + + updatePreview(); +} + +void ImageGuideWidget::slotChangeGuideColor(const TQColor &color) +{ + d->guideColor = color; + updatePreview(); +} + +void ImageGuideWidget::slotChangeGuideSize(int size) +{ + d->guideSize = size; + updatePreview(); +} + +void ImageGuideWidget::updatePixmap() +{ + TQPainter p(d->pixmap); + TQString text; + TQRect textRect, fontRect; + TQFontMetrics fontMt = p.fontMetrics(); + p.setPen(TQPen(TQt::red, 1)) ; + + d->pixmap->fill(colorGroup().background()); + + if (d->renderingPreviewMode == PreviewOriginalImage || + (d->renderingPreviewMode == PreviewToggleOnMouseOver && d->onMouseMovePreviewToggled == false )) + { + p.drawPixmap(d->rect, d->iface->convertToPixmap(d->preview)); + + text = i18n("Original"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + 20, d->rect.y() + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + } + else if (d->renderingPreviewMode == PreviewTargetImage || d->renderingPreviewMode == NoPreviewMode || + (d->renderingPreviewMode == PreviewToggleOnMouseOver && d->onMouseMovePreviewToggled == true )) + { + d->iface->paint(d->pixmap, d->rect.x(), d->rect.y(), + d->rect.width(), d->rect.height(), + d->underExposureIndicator, d->overExposureIndicator); + + if (d->renderingPreviewMode == PreviewTargetImage || + d->renderingPreviewMode == PreviewToggleOnMouseOver) + { + text = i18n("Target"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + 20, d->rect.y() + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + } + } + else if (d->renderingPreviewMode == PreviewBothImagesVert || + d->renderingPreviewMode == PreviewBothImagesVertCont) + { + if (d->renderingPreviewMode == PreviewBothImagesVert) + { + // Drawing the original image. + p.drawPixmap(d->rect, d->iface->convertToPixmap(d->preview)); + + // Drawing the target image under the original. + d->iface->paint(d->pixmap, + d->rect.x()+d->rect.width()/2, + d->rect.y(), + d->rect.width()/2, + d->rect.height(), + d->underExposureIndicator, + d->overExposureIndicator); + } + else + { + // Drawing the target image. + d->iface->paint(d->pixmap, + d->rect.x(), + d->rect.y(), + d->rect.width(), + d->rect.height(), + d->underExposureIndicator, + d->overExposureIndicator); + + // Drawing the original image under the target. + p.drawPixmap(d->rect.x(), d->rect.y(), d->iface->convertToPixmap(d->preview), + 0, 0, d->rect.width()/2, d->rect.height()); + } + + // Drawing the information and others stuff. + p.fillRect(d->rect.right(), 0, width(), height(), colorGroup().background()); + + p.setPen(TQPen(TQt::white, 2, TQt::SolidLine)); + p.drawLine(d->rect.x()+d->rect.width()/2-1, + d->rect.y(), + d->rect.x()+d->rect.width()/2-1, + d->rect.y()+d->rect.height()); + p.setPen(TQPen(TQt::red, 2, TQt::DotLine)); + p.drawLine(d->rect.x()+d->rect.width()/2-1, + d->rect.y(), + d->rect.x()+d->rect.width()/2-1, + d->rect.y()+d->rect.height()); + + p.setPen(TQPen(TQt::red, 1)) ; + + text = i18n("Target"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + d->rect.width()/2 + 20, + d->rect.y() + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + + text = i18n("Original"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + 20, d->rect.y() + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + } + else if (d->renderingPreviewMode == PreviewBothImagesHorz || + d->renderingPreviewMode == PreviewBothImagesHorzCont) + { + if (d->renderingPreviewMode == PreviewBothImagesHorz) + { + // Drawing the original image. + p.drawPixmap(d->rect, d->iface->convertToPixmap(d->preview)); + + // Drawing the target image under the original. + d->iface->paint(d->pixmap, + d->rect.x(), + d->rect.y()+d->rect.height()/2, + d->rect.width(), + d->rect.height()/2, + d->underExposureIndicator, + d->overExposureIndicator); + } + else + { + // Drawing the target image. + d->iface->paint(d->pixmap, + d->rect.x(), + d->rect.y(), + d->rect.width(), + d->rect.height(), + d->underExposureIndicator, + d->overExposureIndicator); + + // Drawing the original image under the target. + p.drawPixmap(d->rect.x(), d->rect.y(), d->iface->convertToPixmap(d->preview), + 0, 0, d->rect.width(), d->rect.height()/2); + } + + p.fillRect(0, d->rect.bottom(), width(), height(), colorGroup().background()); + + p.setPen(TQPen(TQt::white, 2, TQt::SolidLine)); + p.drawLine(d->rect.x(), + d->rect.y()+d->rect.height()/2-1, + d->rect.x()+d->rect.width(), + d->rect.y()+d->rect.height()/2-1); + p.setPen(TQPen(TQt::red, 2, TQt::DotLine)); + p.drawLine(d->rect.x(), + d->rect.y()+d->rect.height()/2-1, + d->rect.x()+d->rect.width(), + d->rect.y()+d->rect.height()/2-1); + + p.setPen(TQPen(TQt::red, 1)) ; + + text = i18n("Target"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + 20, + d->rect.y() + d->rect.height()/2 + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + + text = i18n("Original"); + fontRect = fontMt.boundingRect(0, 0, d->rect.width(), d->rect.height(), 0, text); + textRect.setTopLeft(TQPoint(d->rect.x() + 20, d->rect.y() + 20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + } + + if (d->spotVisible) + { + // Adapt spot from image coordinate to widget coordinate. + int xspot = d->spot.x() + d->rect.x(); + int yspot = d->spot.y() + d->rect.y(); + + switch (d->guideMode) + { + case HVGuideMode: + { + p.setPen(TQPen(TQt::white, d->guideSize, TQt::SolidLine)); + p.drawLine(xspot, d->rect.top() + d->flicker, xspot, d->rect.bottom() - d->flicker); + p.drawLine(d->rect.left() + d->flicker, yspot, d->rect.right() - d->flicker, yspot); + p.setPen(TQPen(d->guideColor, d->guideSize, TQt::DotLine)); + p.drawLine(xspot, d->rect.top() + d->flicker, xspot, d->rect.bottom() - d->flicker); + p.drawLine(d->rect.left() + d->flicker, yspot, d->rect.right() - d->flicker, yspot); + break; + } + + case PickColorMode: + { + p.setPen(TQPen(d->guideColor, 1, TQt::SolidLine)); + p.drawLine(xspot-10, yspot-10, xspot+10, yspot+10); + p.drawLine(xspot+10, yspot-10, xspot-10, yspot+10); + p.setPen(TQPen(d->guideColor, 3, TQt::SolidLine)); + p.drawEllipse( xspot-5, yspot-5, 11, 11 ); + + if (d->flicker%2 != 0) + { + p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + p.drawEllipse( xspot-5, yspot-5, 11, 11 ); + } + + break; + } + } + } + + p.end(); +} + +void ImageGuideWidget::paintEvent(TQPaintEvent*) +{ + bitBlt(this, 0, 0, d->pixmap); +} + +void ImageGuideWidget::updatePreview() +{ + updatePixmap(); + repaint(false); +} + +void ImageGuideWidget::timerEvent(TQTimerEvent* e) +{ + if (e->timerId() == d->timerID) + { + if (d->flicker == 5) d->flicker=0; + else d->flicker++; + updatePreview(); + } + else + TQWidget::timerEvent(e); +} + +void ImageGuideWidget::resizeEvent(TQResizeEvent* e) +{ + blockSignals(true); + delete d->pixmap; + int w = e->size().width(); + int h = e->size().height(); + int old_w = d->width; + int old_h = d->height; + + uchar *data = d->iface->setPreviewImageSize(w, h); + d->width = d->iface->previewWidth(); + d->height = d->iface->previewHeight(); + bool sixteenBit = d->iface->previewSixteenBit(); + bool hasAlpha = d->iface->previewHasAlpha(); + d->preview = DImg(d->width, d->height, sixteenBit, hasAlpha, data); + d->preview.setICCProfil( d->iface->getOriginalImg()->getICCProfil() ); + + delete [] data; + + d->pixmap = new TQPixmap(w, h); + d->rect = TQRect(w/2-d->width/2, h/2-d->height/2, d->width, d->height); + + d->spot.setX((int)((float)d->spot.x() * ( (float)d->width / (float)old_w))); + d->spot.setY((int)((float)d->spot.y() * ( (float)d->height / (float)old_h))); + updatePixmap(); + blockSignals(false); + emit signalResized(); +} + +void ImageGuideWidget::mousePressEvent(TQMouseEvent* e) +{ + if ( !d->focus && e->button() == TQt::LeftButton && + d->rect.contains( e->x(), e->y() ) && d->spotVisible ) + { + d->focus = true; + d->spot.setX(e->x()-d->rect.x()); + d->spot.setY(e->y()-d->rect.y()); + updatePreview(); + } +} + +void ImageGuideWidget::mouseReleaseEvent(TQMouseEvent* e) +{ + if ( d->rect.contains( e->x(), e->y() ) && d->focus && d->spotVisible) + { + d->focus = false; + updatePreview(); + d->spot.setX(e->x()-d->rect.x()); + d->spot.setY(e->y()-d->rect.y()); + + DColor color; + TQPoint point = getSpotPosition(); + + if (d->renderingPreviewMode == PreviewOriginalImage) + { + color = getSpotColor(OriginalImage); + emit spotPositionChangedFromOriginal( color, d->spot ); + } + else if (d->renderingPreviewMode == PreviewTargetImage || d->renderingPreviewMode == NoPreviewMode) + { + color = getSpotColor(TargetPreviewImage); + emit spotPositionChangedFromTarget( color, d->spot ); + } + else if (d->renderingPreviewMode == PreviewBothImagesVert) + { + if (d->spot.x() > d->rect.width()/2) + { + color = getSpotColor(TargetPreviewImage); + emit spotPositionChangedFromTarget(color, TQPoint(d->spot.x() - d->rect.width()/2, + d->spot.y())); + } + else + { + color = getSpotColor(OriginalImage); + emit spotPositionChangedFromOriginal( color, d->spot ); + } + } + else if (d->renderingPreviewMode == PreviewBothImagesVertCont) + { + if (d->spot.x() > d->rect.width()/2) + { + color = getSpotColor(TargetPreviewImage); + emit spotPositionChangedFromTarget( color, d->spot); + } + else + { + color = getSpotColor(OriginalImage); + emit spotPositionChangedFromOriginal( color, d->spot ); + } + } + else if (d->renderingPreviewMode == PreviewBothImagesHorz) + { + if (d->spot.y() > d->rect.height()/2) + { + color = getSpotColor(TargetPreviewImage); + emit spotPositionChangedFromTarget(color, TQPoint(d->spot.x(), + d->spot.y() - d->rect.height()/2 )); + } + else + { + color = getSpotColor(OriginalImage); + emit spotPositionChangedFromOriginal( color, d->spot ); + } + } + else if (d->renderingPreviewMode == PreviewBothImagesHorzCont) + { + if (d->spot.y() > d->rect.height()/2) + { + color = getSpotColor(TargetPreviewImage); + emit spotPositionChangedFromTarget( color, d->spot); + } + else + { + color = getSpotColor(OriginalImage); + emit spotPositionChangedFromOriginal( color, d->spot ); + } + } + } +} + +void ImageGuideWidget::mouseMoveEvent(TQMouseEvent* e) +{ + if ( d->rect.contains( e->x(), e->y() ) && !d->focus && d->spotVisible ) + { + setCursor( KCursor::crossCursor() ); + } + else if ( d->rect.contains( e->x(), e->y() ) && d->focus && d->spotVisible ) + { + d->spot.setX(e->x()-d->rect.x()); + d->spot.setY(e->y()-d->rect.y()); + } + else + { + unsetCursor(); + } +} + +void ImageGuideWidget::enterEvent(TQEvent*) +{ + if ( !d->focus && d->renderingPreviewMode == PreviewToggleOnMouseOver ) + { + d->onMouseMovePreviewToggled = false; + updatePixmap(); + repaint(false); + } +} + +void ImageGuideWidget::leaveEvent(TQEvent*) +{ + if ( !d->focus && d->renderingPreviewMode == PreviewToggleOnMouseOver ) + { + d->onMouseMovePreviewToggled = true; + updatePixmap(); + repaint(false); + } +} + +} // NameSpace Digikam diff --git a/src/libs/widgets/imageplugins/imageguidewidget.h b/src/libs/widgets/imageplugins/imageguidewidget.h new file mode 100644 index 00000000..48d6d246 --- /dev/null +++ b/src/libs/widgets/imageplugins/imageguidewidget.h @@ -0,0 +1,132 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-08-20 + * Description : a widget to display an image with guides + * + * Copyright (C) 2004-2008 Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEGUIDEWIDGET_H +#define IMAGEGUIDEWIDGET_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqpoint.h> +#include <tqcolor.h> + +// Local includes. + +#include "dcolor.h" +#include "digikam_export.h" + +class TQPixmap; + +namespace Digikam +{ + +class DColor; +class ImageIface; +class ImageGuideWidgetPriv; + +class DIGIKAM_EXPORT ImageGuideWidget : public TQWidget +{ +TQ_OBJECT + + +public: + + enum GuideToolMode + { + HVGuideMode=0, + PickColorMode + }; + + enum RenderingPreviewMode + { + PreviewOriginalImage=0, // Original image only. + PreviewBothImagesHorz, // Horizontal with original and target duplicated. + PreviewBothImagesVert, // Vertical with original and target duplicated. + PreviewBothImagesHorzCont, // Horizontal with original and target in contiguous. + PreviewBothImagesVertCont, // Vertical with original and target in contiguous. + PreviewTargetImage, // Target image only. + PreviewToggleOnMouseOver, // Original image if mouse is over image area, else target image. + NoPreviewMode // Target image only without information displayed. + }; + + enum ColorPointSrc + { + OriginalImage=0, + PreviewImage, + TargetPreviewImage + }; + +public: + + ImageGuideWidget(int w, int h, TQWidget *parent=0, + bool spotVisible=true, int guideMode=HVGuideMode, + const TQColor& guideColor=TQt::red, int guideSize=1, + bool blink=false, bool useImageSelection=false); + ~ImageGuideWidget(); + + ImageIface* imageIface(); + + TQPoint getSpotPosition(); + DColor getSpotColor(int getColorFrom); + void setSpotVisible(bool spotVisible, bool blink=false); + int getRenderingPreviewMode(); + void resetSpotPosition(); + void updatePreview(); + +public slots: + + void slotChangeGuideColor(const TQColor &color); + void slotChangeGuideSize(int size); + void slotChangeRenderingPreviewMode(int mode); + void slotToggleUnderExposure(bool); + void slotToggleOverExposure(bool); + +signals: + + void spotPositionChangedFromOriginal(const Digikam::DColor &color, const TQPoint &position); + void spotPositionChangedFromTarget(const Digikam::DColor &color, const TQPoint &position); + void signalResized(); + +protected: + + void paintEvent(TQPaintEvent*); + void resizeEvent(TQResizeEvent*); + void timerEvent(TQTimerEvent*); + void mousePressEvent(TQMouseEvent*); + void mouseReleaseEvent(TQMouseEvent*); + void mouseMoveEvent(TQMouseEvent*); + void enterEvent(TQEvent*); + void leaveEvent(TQEvent*); + +private: + + void updatePixmap(); + +private: + + ImageGuideWidgetPriv *d; +}; + +} // NameSpace Digikam + +#endif /* IMAGEGUIDEWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/imagepanelwidget.cpp b/src/libs/widgets/imageplugins/imagepanelwidget.cpp new file mode 100644 index 00000000..4551e09e --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepanelwidget.cpp @@ -0,0 +1,335 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-07-01 + * Description : a widget to draw a control panel image tool. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqframe.h> +#include <tqvgroupbox.h> +#include <tqlabel.h> +#include <tqpixmap.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> +#include <tqtimer.h> +#include <tqhbuttongroup.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqpixmap.h> + +// KDE includes. + +#include <kdialog.h> +#include <tdelocale.h> +#include <kcursor.h> +#include <tdeapplication.h> +#include <kiconloader.h> +#include <tdeconfig.h> +#include <kstandarddirs.h> + +// Local includes. + +#include "ddebug.h" +#include "thumbnailsize.h" +#include "imageregionwidget.h" +#include "imagepaniconwidget.h" +#include "imagepanelwidget.h" +#include "imagepanelwidget.moc" + +namespace Digikam +{ + +class ImagePanelWidgetPriv +{ +public: + + ImagePanelWidgetPriv() + { + imagePanIconWidget = 0; + imageRegionWidget = 0; + separateView = 0; + } + + TQString settingsSection; + + TQHButtonGroup *separateView; + + ImagePanIconWidget *imagePanIconWidget; + + ImageRegionWidget *imageRegionWidget; +}; + +ImagePanelWidget::ImagePanelWidget(uint w, uint h, const TQString& settingsSection, + ImagePanIconWidget *pan, TQWidget *parent, int separateViewMode) + : TQWidget(parent, 0, TQt::WDestructiveClose) +{ + d = new ImagePanelWidgetPriv; + d->settingsSection = settingsSection; + d->imagePanIconWidget = pan; + TQGridLayout *grid = new TQGridLayout(this, 2, 3); + + // ------------------------------------------------------------- + + TQFrame *preview = new TQFrame(this); + TQVBoxLayout* l1 = new TQVBoxLayout(preview, 5, 0); + d->imageRegionWidget = new ImageRegionWidget(w, h, preview, false); + d->imageRegionWidget->setFrameStyle(TQFrame::NoFrame); + preview->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQWhatsThis::add( d->imageRegionWidget, i18n("<p>Here you can see the original clip image " + "which will be used for the preview computation." + "<p>Click and drag the mouse cursor in the " + "image to change the clip focus.")); + l1->addWidget(d->imageRegionWidget, 0); + + // ------------------------------------------------------------- + + TQString directory; + d->separateView = new TQHButtonGroup(this); + d->separateView->setExclusive(true); + d->separateView->setInsideMargin( 0 ); + d->separateView->setFrameShape(TQFrame::NoFrame); + + if (separateViewMode == SeparateViewDuplicate || + separateViewMode == SeparateViewAll) + { + TQPushButton *duplicateHorButton = new TQPushButton( d->separateView ); + d->separateView->insert(duplicateHorButton, ImageRegionWidget::SeparateViewDuplicateHorz); + TDEGlobal::dirs()->addResourceType("duplicatebothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothhorz", "duplicatebothhorz.png"); + duplicateHorButton->setPixmap( TQPixmap( directory + "duplicatebothhorz.png" ) ); + duplicateHorButton->setToggleButton(true); + TQWhatsThis::add( duplicateHorButton, i18n("<p>If you enable this option, you will separate the preview area " + "horizontally, displaying the original and target image " + "at the same time. The target is duplicated from the original " + "below the red dashed line." ) ); + + TQPushButton *duplicateVerButton = new TQPushButton( d->separateView ); + d->separateView->insert(duplicateVerButton, ImageRegionWidget::SeparateViewDuplicateVert); + TDEGlobal::dirs()->addResourceType("duplicatebothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothvert", "duplicatebothvert.png"); + duplicateVerButton->setPixmap( TQPixmap( directory + "duplicatebothvert.png" ) ); + duplicateVerButton->setToggleButton(true); + TQWhatsThis::add( duplicateVerButton, i18n("<p>If you enable this option, you will separate the preview area " + "vertically, displaying the original and target image " + "at the same time. The target is duplicated from the original to " + "the right of the red dashed line." ) ); + } + + if (separateViewMode == SeparateViewNormal || + separateViewMode == SeparateViewAll) + { + TQPushButton *separateHorButton = new TQPushButton( d->separateView ); + d->separateView->insert(separateHorButton, ImageRegionWidget::SeparateViewHorizontal); + TDEGlobal::dirs()->addResourceType("bothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothhorz", "bothhorz.png"); + separateHorButton->setPixmap( TQPixmap( directory + "bothhorz.png" ) ); + separateHorButton->setToggleButton(true); + TQWhatsThis::add( separateHorButton, i18n( "<p>If you enable this option, you will separate the preview area " + "horizontally, displaying the original and target image " + "at the same time. The original is above the " + "red dashed line, the target below it." ) ); + + TQPushButton *separateVerButton = new TQPushButton( d->separateView ); + d->separateView->insert(separateVerButton, ImageRegionWidget::SeparateViewVertical); + TDEGlobal::dirs()->addResourceType("bothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothvert", "bothvert.png"); + separateVerButton->setPixmap( TQPixmap( directory + "bothvert.png" ) ); + separateVerButton->setToggleButton(true); + TQWhatsThis::add( separateVerButton, i18n( "<p>If you enable this option, you will separate the preview area " + "vertically, displaying the original and target image " + "at the same time. The original is to the left of the " + "red dashed line, the target to the right of it." ) ); + } + + TQPushButton *noSeparateButton = new TQPushButton( d->separateView ); + d->separateView->insert(noSeparateButton, ImageRegionWidget::SeparateViewNone); + TDEGlobal::dirs()->addResourceType("target", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("target", "target.png"); + noSeparateButton->setPixmap( TQPixmap( directory + "target.png" ) ); + noSeparateButton->setToggleButton(true); + TQWhatsThis::add( noSeparateButton, i18n( "<p>If you enable this option, the preview area will not " + "be separated." ) ); + + // ------------------------------------------------------------- + + grid->addMultiCellWidget(preview, 0, 1, 0, 3); + grid->addMultiCellWidget(d->separateView, 2, 2, 3, 3); + grid->setRowStretch(1, 10); + grid->setColStretch(1, 10); + grid->setMargin(0); + grid->setSpacing(KDialog::spacingHint()); + + // ------------------------------------------------------------- + + TQTimer::singleShot(0, this, TQ_SLOT(slotInitGui())); + + // ------------------------------------------------------------- + + connect(d->imageRegionWidget, TQ_SIGNAL(signalContentsMovedEvent(bool)), + this, TQ_SLOT(slotOriginalImageRegionChanged(bool))); + + connect(d->imagePanIconWidget, TQ_SIGNAL(signalSelectionMoved(const TQRect&, bool)), + this, TQ_SLOT(slotSetImageRegionPosition(const TQRect&, bool))); + + connect(d->imagePanIconWidget, TQ_SIGNAL(signalSelectionTakeFocus()), + this, TQ_SLOT(slotPanIconTakeFocus())); + + connect(d->separateView, TQ_SIGNAL(released(int)), + d->imagePanIconWidget, TQ_SLOT(slotSeparateViewToggled(int))); + + connect(d->separateView, TQ_SIGNAL(released(int)), + d->imageRegionWidget, TQ_SLOT(slotSeparateViewToggled(int))); +} + +ImagePanelWidget::~ImagePanelWidget() +{ + writeSettings(); + delete d; +} + +ImageRegionWidget *ImagePanelWidget::previewWidget() const +{ + return d->imageRegionWidget; +} + +void ImagePanelWidget::readSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + int mode = config->readNumEntry("Separate View", ImageRegionWidget::SeparateViewDuplicateVert); + mode = TQMAX(ImageRegionWidget::SeparateViewHorizontal, mode); + mode = TQMIN(ImageRegionWidget::SeparateViewDuplicateHorz, mode); + + d->imageRegionWidget->blockSignals(true); + d->imagePanIconWidget->blockSignals(true); + d->separateView->blockSignals(true); + d->imageRegionWidget->slotSeparateViewToggled( mode ); + d->imagePanIconWidget->slotSeparateViewToggled( mode ); + d->separateView->setButton( mode ); + d->imageRegionWidget->blockSignals(false); + d->imagePanIconWidget->blockSignals(false); + d->separateView->blockSignals(false); +} + +void ImagePanelWidget::writeSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + config->writeEntry( "Separate View", d->separateView->selectedId() ); + config->sync(); +} + +void ImagePanelWidget::slotOriginalImageRegionChanged(bool target) +{ + d->imagePanIconWidget->slotZoomFactorChanged(d->imageRegionWidget->zoomFactor()); + TQRect rect = getOriginalImageRegion(); + d->imagePanIconWidget->setRegionSelection(rect); + updateSelectionInfo(rect); + + if (target) + { + d->imageRegionWidget->backupPixmapRegion(); + emit signalOriginalClipFocusChanged(); + } +} + +void ImagePanelWidget::slotZoomSliderChanged(int size) +{ + double h = (double)ThumbnailSize::Huge; + double s = (double)ThumbnailSize::Small; + double zmin = d->imageRegionWidget->zoomMin(); + double zmax = d->imageRegionWidget->zoomMax(); + double b = (zmin-(zmax*s/h))/(1-s/h); + double a = (zmax-b)/h; + double z = a*size+b; + + d->imageRegionWidget->setZoomFactorSnapped(z); +} + +void ImagePanelWidget::resizeEvent(TQResizeEvent *) +{ + emit signalResized(); +} + +void ImagePanelWidget::slotInitGui() +{ + readSettings(); + setCenterImageRegionPosition(); + slotOriginalImageRegionChanged(true); +} + +void ImagePanelWidget::setPanIconHighLightPoints(const TQPointArray& pt) +{ + d->imageRegionWidget->setHighLightPoints(pt); + d->imagePanIconWidget->setHighLightPoints(pt); +} + +void ImagePanelWidget::slotPanIconTakeFocus() +{ + d->imageRegionWidget->restorePixmapRegion(); +} + +void ImagePanelWidget::setEnable(bool b) +{ + d->imageRegionWidget->setEnabled(b); + d->separateView->setEnabled(b); +} + +TQRect ImagePanelWidget::getOriginalImageRegion() +{ + return ( d->imageRegionWidget->getImageRegion() ); +} + +TQRect ImagePanelWidget::getOriginalImageRegionToRender() +{ + return ( d->imageRegionWidget->getImageRegionToRender() ); +} + +DImg ImagePanelWidget::getOriginalRegionImage() +{ + return ( d->imageRegionWidget->getImageRegionImage() ); +} + +void ImagePanelWidget::setPreviewImage(DImg img) +{ + d->imageRegionWidget->updatePreviewImage(&img); + d->imageRegionWidget->repaintContents(false); +} + +void ImagePanelWidget::setCenterImageRegionPosition() +{ + d->imageRegionWidget->setCenterContentsPosition(); +} + +void ImagePanelWidget::slotSetImageRegionPosition(const TQRect& rect, bool targetDone) +{ + d->imageRegionWidget->setContentsPosition(rect.x(), rect.y(), targetDone); +} + +void ImagePanelWidget::updateSelectionInfo(const TQRect& rect) +{ + TQToolTip::add( d->imagePanIconWidget, + i18n("<nobr>(%1,%2)(%3x%4)</nobr>") + .arg(rect.left()).arg(rect.top()) + .arg(rect.width()).arg(rect.height())); +} + +} // NameSpace Digikam diff --git a/src/libs/widgets/imageplugins/imagepanelwidget.h b/src/libs/widgets/imageplugins/imagepanelwidget.h new file mode 100644 index 00000000..32179da9 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepanelwidget.h @@ -0,0 +1,117 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-07-01 + * Description : a widget to draw a control panel image tool. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEPANELWIDGET_H +#define IMAGEPANELWIDGET_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqimage.h> +#include <tqrect.h> +#include <tqstring.h> + +// Local includes. + +#include "dimg.h" +#include "digikam_export.h" + +class KProgress; + +namespace Digikam +{ + +class ImagePanelWidgetPriv; +class ImageRegionWidget; +class ImagePanIconWidget; + +class DIGIKAM_EXPORT ImagePanelWidget : public TQWidget +{ +TQ_OBJECT + + +public: + + enum SeparateViewOptions + { + SeparateViewNormal=0, + SeparateViewDuplicate, + SeparateViewAll + }; + +public: + + ImagePanelWidget(uint w, uint h, const TQString& settingsSection, ImagePanIconWidget *pan, + TQWidget *parent=0, int separateViewMode=SeparateViewAll); + ~ImagePanelWidget(); + + TQRect getOriginalImageRegion(); + TQRect getOriginalImageRegionToRender(); + DImg getOriginalRegionImage(); + void setPreviewImage(DImg img); + void setCenterImageRegionPosition(); + + void setEnable(bool b); + + void setPanIconHighLightPoints(const TQPointArray& pt); + + void writeSettings(); + + ImageRegionWidget *previewWidget() const; + +signals: + + void signalOriginalClipFocusChanged(); + void signalResized(); + +public slots: + + // Set the top/Left conner clip position. + void slotSetImageRegionPosition(const TQRect& rect, bool targetDone); + + // Slot used when the original image clip focus is changed by the user. + void slotOriginalImageRegionChanged(bool target); + +protected: + + void resizeEvent(TQResizeEvent *e); + +private slots: + + void slotPanIconTakeFocus(); + void slotInitGui(); + void slotZoomSliderChanged(int); + +private: + + void updateSelectionInfo(const TQRect& rect); + void readSettings(); + +private: + + ImagePanelWidgetPriv* d; +}; + +} // NameSpace Digikam + +#endif /* IMAGEPANNELWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/imagepaniconwidget.cpp b/src/libs/widgets/imageplugins/imagepaniconwidget.cpp new file mode 100644 index 00000000..38564228 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepaniconwidget.cpp @@ -0,0 +1,198 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-08-22 + * Description : a widget to display a panel to choose + * a rectangular image area. + * + * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cmath> + +// TQt includes. + +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqpen.h> +#include <tqtimer.h> + +// Local includes. + +#include "ddebug.h" +#include "imageiface.h" +#include "imageregionwidget.h" +#include "imagepaniconwidget.h" +#include "imagepaniconwidget.moc" + +namespace Digikam +{ + +class ImagePanIconWidgetPriv +{ +public: + + ImagePanIconWidgetPriv() + { + iface = 0; + data = 0; + separateView = ImageRegionWidget::SeparateViewNone; + } + + uchar *data; + + int separateView; + + TQPointArray hightlightPoints; + + ImageIface *iface; +}; + +ImagePanIconWidget::ImagePanIconWidget(int w, int h, TQWidget *parent, WFlags flags) + : PanIconWidget(parent, flags) +{ + d = new ImagePanIconWidgetPriv; + + d->iface = new ImageIface(w, h); + d->data = d->iface->getPreviewImage(); + m_width = d->iface->previewWidth(); + m_height = d->iface->previewHeight(); + m_orgWidth = d->iface->originalWidth(); + m_orgHeight = d->iface->originalHeight(); + m_zoomedOrgWidth = d->iface->originalWidth(); + m_zoomedOrgHeight = d->iface->originalHeight(); + m_pixmap = new TQPixmap(w, h); + + setFixedSize(m_width, m_height); + + m_rect = TQRect(width()/2-m_width/2, height()/2-m_height/2, m_width, m_height); + updatePixmap(); + m_timerID = startTimer(800); +} + +ImagePanIconWidget::~ImagePanIconWidget() +{ + delete d->iface; + delete [] d->data; + delete d; +} + +void ImagePanIconWidget::setHighLightPoints(const TQPointArray& pointsList) +{ + d->hightlightPoints = pointsList; + updatePixmap(); + repaint(false); +} + +void ImagePanIconWidget::updatePixmap() +{ + // Drawing background and image. + m_pixmap->fill(colorGroup().background()); + d->iface->paint(m_pixmap, m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height()); + + TQPainter p(m_pixmap); + + // Drawing HighLighted points. + + if (!d->hightlightPoints.isEmpty()) + { + TQPoint pt; + + for (int i = 0 ; i < d->hightlightPoints.count() ; i++) + { + pt = d->hightlightPoints.point(i); + pt.setX((int)(pt.x() * (float)(m_width) / (float)d->iface->originalWidth())); + pt.setY((int)(pt.y() * (float)(m_height) / (float)d->iface->originalHeight())); + p.setPen(TQPen(TQt::black, 1, TQt::SolidLine)); + p.drawLine(pt.x(), pt.y()-1, pt.x(), pt.y()+1); + p.drawLine(pt.x()-1, pt.y(), pt.x()+1, pt.y()); + p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + p.drawPoint(pt.x()-1, pt.y()-1); + p.drawPoint(pt.x()+1, pt.y()+1); + p.drawPoint(pt.x()-1, pt.y()+1); + p.drawPoint(pt.x()+1, pt.y()-1); + } + } + + // Drawing selection border + + if (m_flicker) p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + else p.setPen(TQPen(TQt::red, 1, TQt::SolidLine)); + + p.drawRect(m_localRegionSelection.x(), + m_localRegionSelection.y(), + m_localRegionSelection.width(), + m_localRegionSelection.height()); + + if (m_flicker) p.setPen(TQPen(TQt::red, 1, TQt::DotLine)); + else p.setPen(TQPen(TQt::white, 1, TQt::DotLine)); + + p.drawRect(m_localRegionSelection.x(), + m_localRegionSelection.y(), + m_localRegionSelection.width(), + m_localRegionSelection.height()); + + if (d->separateView == ImageRegionWidget::SeparateViewVertical) + { + if (m_flicker) p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + else p.setPen(TQPen(TQt::red, 1, TQt::SolidLine)); + + p.drawLine(m_localRegionSelection.topLeft().x() + m_localRegionSelection.width()/2, + m_localRegionSelection.topLeft().y(), + m_localRegionSelection.bottomLeft().x() + m_localRegionSelection.width()/2, + m_localRegionSelection.bottomLeft().y()); + + if (m_flicker) p.setPen(TQPen(TQt::red, 1, TQt::DotLine)); + else p.setPen(TQPen(TQt::white, 1, TQt::DotLine)); + + p.drawLine(m_localRegionSelection.topLeft().x() + m_localRegionSelection.width()/2, + m_localRegionSelection.topLeft().y() + 1, + m_localRegionSelection.bottomLeft().x() + m_localRegionSelection.width()/2, + m_localRegionSelection.bottomLeft().y() - 1); + } + else if (d->separateView == ImageRegionWidget::SeparateViewHorizontal) + { + if (m_flicker) p.setPen(TQPen(TQt::white, 1, TQt::SolidLine)); + else p.setPen(TQPen(TQt::red, 1, TQt::SolidLine)); + + p.drawLine(m_localRegionSelection.topLeft().x(), + m_localRegionSelection.topLeft().y() + m_localRegionSelection.height()/2, + m_localRegionSelection.topRight().x(), + m_localRegionSelection.topRight().y() + m_localRegionSelection.height()/2); + + if (m_flicker) p.setPen(TQPen(TQt::red, 1, TQt::DotLine)); + else p.setPen(TQPen(TQt::white, 1, TQt::DotLine)); + + p.drawLine(m_localRegionSelection.topLeft().x() + 1, + m_localRegionSelection.topLeft().y() + m_localRegionSelection.height()/2, + m_localRegionSelection.topRight().x() - 1, + m_localRegionSelection.topRight().y() + m_localRegionSelection.height()/2); + } + + p.end(); +} + +void ImagePanIconWidget::slotSeparateViewToggled(int t) +{ + d->separateView = t; + updatePixmap(); + repaint(false); +} + +} // NameSpace Digikam diff --git a/src/libs/widgets/imageplugins/imagepaniconwidget.h b/src/libs/widgets/imageplugins/imagepaniconwidget.h new file mode 100644 index 00000000..e7d6ffb7 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepaniconwidget.h @@ -0,0 +1,68 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-08-22 + * Description : a widget to display a panel to choose + * a rectangular image area. + * + * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEPANICONWIDGET_H +#define IMAGEPANICONWIDGET_H + +// TQt includes. + +#include <tqpointarray.h> + +// Local includes. + +#include "paniconwidget.h" + +namespace Digikam +{ + +class ImagePanIconWidgetPriv; + +class ImagePanIconWidget : public PanIconWidget +{ +TQ_OBJECT + + +public: + + ImagePanIconWidget(int width, int height, TQWidget *parent=0, WFlags flags=TQt::WDestructiveClose); + ~ImagePanIconWidget(); + + void setHighLightPoints(const TQPointArray& pointsList); + +public slots: + + void slotSeparateViewToggled(int t); + +private: + + void updatePixmap(); + +private: + + ImagePanIconWidgetPriv *d; +}; + +} // NameSpace Digikam + +#endif /* IMAGEPANICONWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/imagepannelwidget.cpp b/src/libs/widgets/imageplugins/imagepannelwidget.cpp new file mode 100644 index 00000000..cebf0f3c --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepannelwidget.cpp @@ -0,0 +1,477 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-07-01 + * Description : a widget to draw a control pannel image tool. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqframe.h> +#include <tqvgroupbox.h> +#include <tqlabel.h> +#include <tqpixmap.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> +#include <tqtimer.h> +#include <tqhbuttongroup.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqpixmap.h> + +// KDE includes. + +#include <kdialog.h> +#include <tdelocale.h> +#include <kcursor.h> +#include <kprogress.h> +#include <tdeapplication.h> +#include <kiconloader.h> +#include <tdeconfig.h> +#include <kstandarddirs.h> +#include <kseparator.h> + +// Local includes. + +#include "ddebug.h" +#include "sidebar.h" +#include "statuszoombar.h" +#include "thumbnailsize.h" +#include "imageregionwidget.h" +#include "imagepaniconwidget.h" +#include "imagepannelwidget.h" +#include "imagepannelwidget.moc" + +namespace Digikam +{ + +class ImagePannelWidgetPriv +{ +public: + + ImagePannelWidgetPriv() + { + imageRegionWidget = 0; + imagePanIconWidget = 0; + mainLayout = 0; + separateView = 0; + progressBar = 0; + settingsSideBar = 0; + splitter = 0; + settingsLayout = 0; + settings = 0; + previewWidget = 0; + zoomBar = 0; + } + + TQGridLayout *mainLayout; + + TQHButtonGroup *separateView; + + TQString settingsSection; + + TQWidget *settings; + TQWidget *previewWidget; + + TQVBoxLayout *settingsLayout; + + TQSplitter *splitter; + + KProgress *progressBar; + + ImageRegionWidget *imageRegionWidget; + ImagePanIconWidget *imagePanIconWidget; + + Sidebar *settingsSideBar; + + StatusZoomBar *zoomBar; +}; + +ImagePannelWidget::ImagePannelWidget(uint w, uint h, const TQString& settingsSection, + TQWidget *parent, int separateViewMode) + : TQHBox(parent, 0, TQt::WDestructiveClose) +{ + d = new ImagePannelWidgetPriv; + d->settingsSection = settingsSection; + d->splitter = new TQSplitter(this); + d->previewWidget = new TQWidget(d->splitter); + d->mainLayout = new TQGridLayout( d->previewWidget, 2, 3, 0, KDialog::spacingHint()); + + d->splitter->setFrameStyle( TQFrame::NoFrame ); + d->splitter->setFrameShadow( TQFrame::Plain ); + d->splitter->setFrameShape( TQFrame::NoFrame ); + d->splitter->setOpaqueResize(false); + + // ------------------------------------------------------------- + + TQFrame *preview = new TQFrame(d->previewWidget); + TQVBoxLayout* l1 = new TQVBoxLayout(preview, 5, 0); + d->imageRegionWidget = new ImageRegionWidget(w, h, preview, false); + d->imageRegionWidget->setFrameStyle(TQFrame::NoFrame); + preview->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQWhatsThis::add( d->imageRegionWidget, i18n("<p>Here you can see the original clip image " + "which will be used for the preview computation." + "<p>Click and drag the mouse cursor in the " + "image to change the clip focus.")); + l1->addWidget(d->imageRegionWidget, 0); + + TQSizePolicy rightSzPolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding, 2, 1); + d->previewWidget->setSizePolicy(rightSzPolicy); + + // ------------------------------------------------------------- + + d->zoomBar = new StatusZoomBar(d->previewWidget); + TQWhatsThis::add( d->zoomBar, i18n("<p>Here set the zoom factor of the preview area.") ); + + // ------------------------------------------------------------- + + TQString directory; + d->separateView = new TQHButtonGroup(d->previewWidget); + d->separateView->setExclusive(true); + d->separateView->setInsideMargin( 0 ); + d->separateView->setFrameShape(TQFrame::NoFrame); + + if (separateViewMode == SeparateViewDuplicate || + separateViewMode == SeparateViewAll) + { + TQPushButton *duplicateHorButton = new TQPushButton( d->separateView ); + d->separateView->insert(duplicateHorButton, ImageRegionWidget::SeparateViewDuplicateHorz); + TDEGlobal::dirs()->addResourceType("duplicatebothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothhorz", "duplicatebothhorz.png"); + duplicateHorButton->setPixmap( TQPixmap( directory + "duplicatebothhorz.png" ) ); + duplicateHorButton->setToggleButton(true); + TQWhatsThis::add( duplicateHorButton, i18n("<p>If you enable this option, you will separate the preview area " + "horizontally, displaying the original and target image " + "at the same time. The target is duplicated from the original " + "below the red dashed line." ) ); + + TQPushButton *duplicateVerButton = new TQPushButton( d->separateView ); + d->separateView->insert(duplicateVerButton, ImageRegionWidget::SeparateViewDuplicateVert); + TDEGlobal::dirs()->addResourceType("duplicatebothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothvert", "duplicatebothvert.png"); + duplicateVerButton->setPixmap( TQPixmap( directory + "duplicatebothvert.png" ) ); + duplicateVerButton->setToggleButton(true); + TQWhatsThis::add( duplicateVerButton, i18n("<p>If you enable this option, you will separate the preview area " + "vertically, displaying the original and target image " + "at the same time. The target is duplicated from the original to " + "the right of the red dashed line." ) ); + } + + if (separateViewMode == SeparateViewNormal || + separateViewMode == SeparateViewAll) + { + TQPushButton *separateHorButton = new TQPushButton( d->separateView ); + d->separateView->insert(separateHorButton, ImageRegionWidget::SeparateViewHorizontal); + TDEGlobal::dirs()->addResourceType("bothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothhorz", "bothhorz.png"); + separateHorButton->setPixmap( TQPixmap( directory + "bothhorz.png" ) ); + separateHorButton->setToggleButton(true); + TQWhatsThis::add( separateHorButton, i18n( "<p>If you enable this option, you will separate the preview area " + "horizontally, displaying the original and target image " + "at the same time. The original is above the " + "red dashed line, the target below it." ) ); + + TQPushButton *separateVerButton = new TQPushButton( d->separateView ); + d->separateView->insert(separateVerButton, ImageRegionWidget::SeparateViewVertical); + TDEGlobal::dirs()->addResourceType("bothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothvert", "bothvert.png"); + separateVerButton->setPixmap( TQPixmap( directory + "bothvert.png" ) ); + separateVerButton->setToggleButton(true); + TQWhatsThis::add( separateVerButton, i18n( "<p>If you enable this option, you will separate the preview area " + "vertically, displaying the original and target image " + "at the same time. The original is to the left of the " + "red dashed line, the target to the right of it." ) ); + } + + TQPushButton *noSeparateButton = new TQPushButton( d->separateView ); + d->separateView->insert(noSeparateButton, ImageRegionWidget::SeparateViewNone); + TDEGlobal::dirs()->addResourceType("target", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("target", "target.png"); + noSeparateButton->setPixmap( TQPixmap( directory + "target.png" ) ); + noSeparateButton->setToggleButton(true); + TQWhatsThis::add( noSeparateButton, i18n( "<p>If you enable this option, the preview area will not " + "be separated." ) ); + + // ------------------------------------------------------------- + + d->progressBar = new KProgress(100, d->previewWidget); + TQWhatsThis::add(d->progressBar ,i18n("<p>This is the percentage of the task which has been completed up to this point.")); + d->progressBar->setProgress(0); + d->progressBar->setMaximumHeight( fontMetrics().height() ); + + // ------------------------------------------------------------- + + d->mainLayout->addMultiCellWidget(preview, 0, 1, 0, 3); + d->mainLayout->addMultiCellWidget(d->zoomBar, 2, 2, 0, 0); + d->mainLayout->addMultiCellWidget(d->progressBar, 2, 2, 2, 2); + d->mainLayout->addMultiCellWidget(d->separateView, 2, 2, 3, 3); + + d->mainLayout->setRowStretch(1, 10); + d->mainLayout->setColStretch(1, 10); + + // ------------------------------------------------------------- + + TQString sbName(d->settingsSection + TQString(" Image Plugin Sidebar")); + d->settingsSideBar = new Sidebar(this, sbName.ascii(), Sidebar::Right); + d->settingsSideBar->setSplitter(d->splitter); + + d->settings = new TQWidget(d->settingsSideBar); + d->settingsLayout = new TQVBoxLayout(d->settings); + + TQFrame *frame3 = new TQFrame(d->settings); + frame3->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQVBoxLayout* l3 = new TQVBoxLayout(frame3, 5, 0); + d->imagePanIconWidget = new ImagePanIconWidget(360, 240, frame3); + TQWhatsThis::add( d->imagePanIconWidget, i18n("<p>Here you can see the original image panel " + "which can help you to select the clip preview." + "<p>Click and drag the mouse cursor in the " + "red rectangle to change the clip focus.")); + l3->addWidget(d->imagePanIconWidget, 0, TQt::AlignCenter); + + d->settingsLayout->addWidget(frame3, 0, TQt::AlignHCenter); + d->settingsLayout->addSpacing(KDialog::spacingHint()); + + d->settingsSideBar->appendTab(d->settings, SmallIcon("configure"), i18n("Settings")); + d->settingsSideBar->loadViewState(); + + // ------------------------------------------------------------- + + setProgressVisible(false); + TQTimer::singleShot(0, this, TQ_SLOT(slotInitGui())); + + // ------------------------------------------------------------- + + connect(d->imageRegionWidget, TQ_SIGNAL(signalContentsMovedEvent(bool)), + this, TQ_SLOT(slotOriginalImageRegionChanged(bool))); + + connect(d->imagePanIconWidget, TQ_SIGNAL(signalSelectionMoved(const TQRect&, bool)), + this, TQ_SLOT(slotSetImageRegionPosition(const TQRect&, bool))); + + connect(d->imagePanIconWidget, TQ_SIGNAL(signalSelectionTakeFocus()), + this, TQ_SLOT(slotPanIconTakeFocus())); + + connect(d->separateView, TQ_SIGNAL(released(int)), + d->imageRegionWidget, TQ_SLOT(slotSeparateViewToggled(int))); + + connect(d->separateView, TQ_SIGNAL(released(int)), + d->imagePanIconWidget, TQ_SLOT(slotSeparateViewToggled(int))); + + connect(d->zoomBar, TQ_SIGNAL(signalZoomMinusClicked()), + d->imageRegionWidget, TQ_SLOT(slotDecreaseZoom())); + + connect(d->zoomBar, TQ_SIGNAL(signalZoomPlusClicked()), + d->imageRegionWidget, TQ_SLOT(slotIncreaseZoom())); + + connect(d->zoomBar, TQ_SIGNAL(signalZoomSliderReleased(int)), + this, TQ_SLOT(slotZoomSliderChanged(int))); +} + +ImagePannelWidget::~ImagePannelWidget() +{ + writeSettings(); + delete d->settingsSideBar; + delete d; +} + +void ImagePannelWidget::readSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + int mode = config->readNumEntry("Separate View", ImageRegionWidget::SeparateViewDuplicateVert); + mode = TQMAX(ImageRegionWidget::SeparateViewHorizontal, mode); + mode = TQMIN(ImageRegionWidget::SeparateViewDuplicateHorz, mode); + + d->imageRegionWidget->blockSignals(true); + d->imagePanIconWidget->blockSignals(true); + d->separateView->blockSignals(true); + d->imageRegionWidget->slotSeparateViewToggled( mode ); + d->imagePanIconWidget->slotSeparateViewToggled( mode ); + d->separateView->setButton( mode ); + d->imageRegionWidget->blockSignals(false); + d->imagePanIconWidget->blockSignals(false); + d->separateView->blockSignals(false); +} + +void ImagePannelWidget::writeSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + config->writeEntry( "Separate View", d->separateView->selectedId() ); + config->sync(); +} + +void ImagePannelWidget::slotOriginalImageRegionChanged(bool target) +{ + slotZoomFactorChanged(d->imageRegionWidget->zoomFactor()); + TQRect rect = getOriginalImageRegion(); + d->imagePanIconWidget->setRegionSelection(rect); + updateSelectionInfo(rect); + + if (target) + { + d->imageRegionWidget->backupPixmapRegion(); + emit signalOriginalClipFocusChanged(); + } +} + +void ImagePannelWidget::slotZoomFactorChanged(double zoom) +{ + double h = (double)ThumbnailSize::Huge; + double s = (double)ThumbnailSize::Small; + double zmin = d->imageRegionWidget->zoomMin(); + double zmax = d->imageRegionWidget->zoomMax(); + double b = (zmin-(zmax*s/h))/(1-s/h); + double a = (zmax-b)/h; + int size = (int)((zoom - b) /a); + + d->zoomBar->setZoomSliderValue(size); + d->zoomBar->setZoomTrackerText(i18n("zoom: %1%").arg((int)(zoom*100.0))); + + d->zoomBar->setEnableZoomPlus(true); + d->zoomBar->setEnableZoomMinus(true); + + if (d->imageRegionWidget->maxZoom()) + d->zoomBar->setEnableZoomPlus(false); + + if (d->imageRegionWidget->minZoom()) + d->zoomBar->setEnableZoomMinus(false); + + d->imagePanIconWidget->slotZoomFactorChanged(zoom); +} + +void ImagePannelWidget::slotZoomSliderChanged(int size) +{ + double h = (double)ThumbnailSize::Huge; + double s = (double)ThumbnailSize::Small; + double zmin = d->imageRegionWidget->zoomMin(); + double zmax = d->imageRegionWidget->zoomMax(); + double b = (zmin-(zmax*s/h))/(1-s/h); + double a = (zmax-b)/h; + double z = a*size+b; + + d->imageRegionWidget->setZoomFactorSnapped(z); +} + +KProgress *ImagePannelWidget::progressBar() +{ + return d->progressBar; +} + +void ImagePannelWidget::resizeEvent(TQResizeEvent *) +{ + emit signalResized(); +} + +void ImagePannelWidget::slotInitGui() +{ + readSettings(); + setCenterImageRegionPosition(); + slotOriginalImageRegionChanged(true); +} + +void ImagePannelWidget::setPanIconHighLightPoints(const TQPointArray& pt) +{ + d->imageRegionWidget->setHighLightPoints(pt); + d->imagePanIconWidget->setHighLightPoints(pt); +} + +void ImagePannelWidget::slotPanIconTakeFocus() +{ + d->imageRegionWidget->restorePixmapRegion(); +} + +void ImagePannelWidget::setUserAreaWidget(TQWidget *w) +{ + w->reparent( d->settings, TQPoint(0, 0) ); + d->settingsLayout->addSpacing(KDialog::spacingHint()); + d->settingsLayout->addWidget(w); + d->settingsLayout->addStretch(); +} + +void ImagePannelWidget::setEnable(bool b) +{ + d->imageRegionWidget->setEnabled(b); + d->imagePanIconWidget->setEnabled(b); + d->separateView->setEnabled(b); + d->zoomBar->setEnabled(b); +} + +void ImagePannelWidget::setProgress(int val) +{ + d->progressBar->setValue(val); +} + +void ImagePannelWidget::setProgressVisible(bool b) +{ + if (b) d->progressBar->show(); + else d->progressBar->hide(); +} + +void ImagePannelWidget::setProgressWhatsThis(const TQString& desc) +{ + TQWhatsThis::add( d->progressBar, desc); +} + +void ImagePannelWidget::setPreviewImageWaitCursor(bool enable) +{ + if ( enable ) + d->imageRegionWidget->setCursor( KCursor::waitCursor() ); + else + d->imageRegionWidget->unsetCursor(); +} + +TQRect ImagePannelWidget::getOriginalImageRegion() +{ + return ( d->imageRegionWidget->getImageRegion() ); +} + +TQRect ImagePannelWidget::getOriginalImageRegionToRender() +{ + return ( d->imageRegionWidget->getImageRegionToRender() ); +} + +DImg ImagePannelWidget::getOriginalRegionImage() +{ + return ( d->imageRegionWidget->getImageRegionImage() ); +} + +void ImagePannelWidget::setPreviewImage(DImg img) +{ + d->imageRegionWidget->updatePreviewImage(&img); +} + +void ImagePannelWidget::setCenterImageRegionPosition() +{ + d->imageRegionWidget->setCenterContentsPosition(); +} + +void ImagePannelWidget::slotSetImageRegionPosition(const TQRect& rect, bool targetDone) +{ + d->imageRegionWidget->setContentsPosition(rect.x(), rect.y(), targetDone); +} + +void ImagePannelWidget::updateSelectionInfo(const TQRect& rect) +{ + TQToolTip::add( d->imagePanIconWidget, + i18n("<nobr>(%1,%2)(%3x%4)</nobr>") + .arg(rect.left()).arg(rect.top()) + .arg(rect.width()).arg(rect.height())); +} + +} // NameSpace Digikam diff --git a/src/libs/widgets/imageplugins/imagepannelwidget.h b/src/libs/widgets/imageplugins/imagepannelwidget.h new file mode 100644 index 00000000..a3429887 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagepannelwidget.h @@ -0,0 +1,123 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-07-01 + * Description : a widget to draw a control pannel image tool. + * + * Copyright (C) 2005-2008 Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEPANNELWIDGET_H +#define IMAGEPANNELWIDGET_H + +// TQt includes. + +#include <tqhbox.h> +#include <tqimage.h> +#include <tqrect.h> +#include <tqstring.h> + +// Local includes + +#include "dimg.h" +#include "digikam_export.h" + +class KProgress; + +namespace Digikam +{ + +class ImagePannelWidgetPriv; +class ImageRegionWidget; + +class DIGIKAM_EXPORT ImagePannelWidget : public TQHBox +{ +TQ_OBJECT + + +public: + + enum SeparateViewOptions + { + SeparateViewNormal=0, + SeparateViewDuplicate, + SeparateViewAll + }; + +public: + + ImagePannelWidget(uint w, uint h, const TQString& settingsSection, TQWidget *parent=0, + int separateViewMode=SeparateViewAll); + ~ImagePannelWidget(); + + TQRect getOriginalImageRegion(); + TQRect getOriginalImageRegionToRender(); + DImg getOriginalRegionImage(); + void setPreviewImage(DImg img); + void setPreviewImageWaitCursor(bool enable); + void setCenterImageRegionPosition(); + + void setEnable(bool b); + + void setProgress(int val); + void setProgressVisible(bool b); + void setProgressWhatsThis(const TQString& desc); + + void setUserAreaWidget(TQWidget *w); + + void setPanIconHighLightPoints(const TQPointArray& pt); + + KProgress *progressBar(); + +signals: + + void signalOriginalClipFocusChanged(); + void signalResized(); + +public slots: + + // Set the top/Left conner clip position. + void slotSetImageRegionPosition(const TQRect& rect, bool targetDone); + + // Slot used when the original image clip focus is changed by the user. + void slotOriginalImageRegionChanged(bool target); + +protected: + + void resizeEvent(TQResizeEvent *e); + +private slots: + + void slotPanIconTakeFocus(); + void slotInitGui(); + void slotZoomSliderChanged(int); + void slotZoomFactorChanged(double); + +private: + + void updateSelectionInfo(const TQRect& rect); + void readSettings(); + void writeSettings(); + +private: + + ImagePannelWidgetPriv* d; +}; + +} // NameSpace Digikam + +#endif /* IMAGEPANNELWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/imageregionwidget.cpp b/src/libs/widgets/imageplugins/imageregionwidget.cpp new file mode 100644 index 00000000..c1392cc2 --- /dev/null +++ b/src/libs/widgets/imageplugins/imageregionwidget.cpp @@ -0,0 +1,473 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-08-17 + * Description : a widget to draw an image clip region. + * + * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cmath> + +// TQt includes. + +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqtimer.h> +#include <tqpainter.h> +#include <tqpen.h> +#include <tqimage.h> +#include <tqbrush.h> +#include <tqfont.h> +#include <tqfontmetrics.h> +#include <tqpointarray.h> + +// KDE includes. + +#include <kstandarddirs.h> +#include <kcursor.h> +#include <tdeglobal.h> +#include <tdeapplication.h> + +// Local includes. + +#include "ddebug.h" +#include "imageiface.h" +#include "imageregionwidget.h" +#include "imageregionwidget.moc" + +namespace Digikam +{ + +class ImageRegionWidgetPriv +{ + +public: + + ImageRegionWidgetPriv() + { + iface = 0; + separateView = ImageRegionWidget::SeparateViewVertical; + } + + int separateView; + int xpos; + int ypos; + + TQPixmap pixmapRegion; // Pixmap of current region to render. + + TQPointArray hightlightPoints; + + DImg image; // Entire content image to render pixmap. + + ImageIface *iface; +}; + +ImageRegionWidget::ImageRegionWidget(int wp, int hp, TQWidget *parent, bool scrollBar) + : PreviewWidget(parent) +{ + d = new ImageRegionWidgetPriv; + d->iface = new ImageIface(0, 0); + d->image = d->iface->getOriginalImg()->copy(); + + setMinimumSize(wp, hp); + setBackgroundColor(colorGroup().background()); + + if( !scrollBar ) + { + setVScrollBarMode( TQScrollView::AlwaysOff ); + setHScrollBarMode( TQScrollView::AlwaysOff ); + } + + connect(this, TQ_SIGNAL(signalZoomFactorChanged(double)), + this, TQ_SLOT(slotZoomFactorChanged())); +} + +ImageRegionWidget::~ImageRegionWidget() +{ + if (d->iface) delete d->iface; + delete d; +} + +void ImageRegionWidget::resizeEvent(TQResizeEvent* e) +{ + if (!e) return; + + TQScrollView::resizeEvent(e); + + // NOTE: We will always adapt the min. zoom factor to the visible size of canvas + + double srcWidth = previewWidth(); + double srcHeight = previewHeight(); + double dstWidth = contentsRect().width(); + double dstHeight = contentsRect().height(); + double zoom = TQMAX(dstWidth/srcWidth, dstHeight/srcHeight); + + setZoomMin(zoom); + setZoomMax(zoom*12.0); + setZoomFactor(zoom); +} + +int ImageRegionWidget::previewWidth() +{ + return d->image.width(); +} + +int ImageRegionWidget::previewHeight() +{ + return d->image.height(); +} + +bool ImageRegionWidget::previewIsNull() +{ + return d->image.isNull(); +} + +void ImageRegionWidget::resetPreview() +{ + d->image.reset(); +} + +void ImageRegionWidget::paintPreview(TQPixmap *pix, int sx, int sy, int sw, int sh) +{ + DImg img = d->image.smoothScaleSection(sx, sy, sw, sh, tileSize(), tileSize()); + TQPixmap pix2 = d->iface->convertToPixmap(img); + bitBlt(pix, 0, 0, &pix2, 0, 0); +} + +void ImageRegionWidget::setHighLightPoints(const TQPointArray& pointsList) +{ + d->hightlightPoints = pointsList; + repaintContents(false); +} + +void ImageRegionWidget::slotZoomFactorChanged() +{ + emit signalContentsMovedEvent(true); +} + +void ImageRegionWidget::slotSeparateViewToggled(int mode) +{ + d->separateView = mode; + updateContentsSize(); + slotZoomFactorChanged(); +} + +TQRect ImageRegionWidget::getImageRegion() +{ + TQRect region; + + switch (d->separateView) + { + case SeparateViewVertical: + case SeparateViewHorizontal: + case SeparateViewNone: + region = TQRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()); + break; + case SeparateViewDuplicateVert: + region = TQRect(contentsX(), contentsY(), visibleWidth()/2, visibleHeight()); + break; + case SeparateViewDuplicateHorz: + region = TQRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()/2); + break; + } + + return region; +} + +void ImageRegionWidget::viewportPaintExtraData() +{ + if (!m_movingInProgress && !d->pixmapRegion.isNull()) + { + TQPainter p(viewport()); + TQRect region = getLocalTargetImageRegion(); + TQRect rt(contentsToViewport(region.topLeft()), contentsToViewport(region.bottomRight())); + + region = getLocalImageRegionToRender(); + TQRect ro(contentsToViewport(region.topLeft()), contentsToViewport(region.bottomRight())); + + bitBlt(viewport(), rt.x(), rt.y(), &d->pixmapRegion, 0, 0, rt.width(), rt.height()); + + // Drawing separate view. + + switch (d->separateView) + { + case SeparateViewVertical: + case SeparateViewDuplicateVert: + { + p.setPen(TQPen(TQt::white, 2, TQt::SolidLine)); + p.drawLine(rt.topLeft().x(), rt.topLeft().y(), + rt.bottomLeft().x(), rt.bottomLeft().y()); + p.setPen(TQPen(TQt::red, 2, TQt::DotLine)); + p.drawLine(rt.topLeft().x(), rt.topLeft().y()+1, + rt.bottomLeft().x(), rt.bottomLeft().y()-1); + + p.setPen(TQPen(TQt::red, 1)) ; + TQFontMetrics fontMt = p.fontMetrics(); + + TQString text(i18n("Target")); + TQRect textRect; + TQRect fontRect = fontMt.boundingRect(0, 0, contentsWidth(), contentsHeight(), 0, text); + textRect.setTopLeft(TQPoint(rt.topLeft().x()+20, rt.topLeft().y()+20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + + text = i18n("Original"); + fontRect = fontMt.boundingRect(0, 0, contentsWidth(), contentsHeight(), 0, text); + + if (d->separateView == SeparateViewVertical) + ro.moveBy(-ro.width(), 0); + + textRect.setTopLeft(TQPoint(ro.topLeft().x()+20, ro.topLeft().y()+20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + break; + } + case SeparateViewHorizontal: + case SeparateViewDuplicateHorz: + { + p.setPen(TQPen(TQt::white, 2, TQt::SolidLine)); + p.drawLine(rt.topLeft().x()+1, rt.topLeft().y(), + rt.topRight().x()-1, rt.topRight().y()); + p.setPen(TQPen(TQt::red, 2, TQt::DotLine)); + p.drawLine(rt.topLeft().x(), rt.topLeft().y(), + rt.topRight().x(), rt.topRight().y()); + + p.setPen(TQPen(TQt::red, 1)) ; + TQFontMetrics fontMt = p.fontMetrics(); + + TQString text(i18n("Target")); + TQRect textRect; + TQRect fontRect = fontMt.boundingRect(0, 0, contentsWidth(), contentsHeight(), 0, text); + textRect.setTopLeft(TQPoint(rt.topLeft().x()+20, rt.topLeft().y()+20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + + text = i18n("Original"); + fontRect = fontMt.boundingRect(0, 0, contentsWidth(), contentsHeight(), 0, text); + + if (d->separateView == SeparateViewHorizontal) + ro.moveBy(0, -ro.height()); + + textRect.setTopLeft(TQPoint(ro.topLeft().x()+20, ro.topLeft().y()+20)); + textRect.setSize( TQSize(fontRect.width()+2, fontRect.height()+2 ) ); + p.fillRect(textRect, TQBrush(TQColor(250, 250, 255)) ); + p.drawRect(textRect); + p.drawText(textRect, TQt::AlignCenter, text); + break; + } + } + + // Drawing HighLighted points. + + if (!d->hightlightPoints.isEmpty()) + { + TQPoint pt; + TQRect hpArea; + + for (int i = 0 ; i < d->hightlightPoints.count() ; i++) + { + pt = d->hightlightPoints.point(i); + + if ( getImageRegionToRender().contains(pt) ) + { + int x = (int)(((double)pt.x() * tileSize()) / floor(tileSize() / zoomFactor())); + int y = (int)(((double)pt.y() * tileSize()) / floor(tileSize() / zoomFactor())); + + TQPoint hp(contentsToViewport(TQPoint(x, y))); + hpArea.setSize(TQSize((int)(16*zoomFactor()), (int)(16*zoomFactor()))); + hpArea.moveCenter(hp); + + p.setPen(TQPen(TQt::white, 2, TQt::SolidLine)); + p.drawLine(hp.x(), hpArea.y(), + hp.x(), hp.y()-(int)(3*zoomFactor())); + p.drawLine(hp.x(), hp.y()+(int)(3*zoomFactor()), + hp.x(), hpArea.bottom()); + p.drawLine(hpArea.x(), hp.y(), + hp.x()-(int)(3*zoomFactor()), hp.y()); + p.drawLine(hp.x()+(int)(3*zoomFactor()), hp.y(), + hpArea.right(), hp.y()); + + p.setPen(TQPen(TQt::red, 2, TQt::DotLine)); + p.drawLine(hp.x(), hpArea.y(), + hp.x(), hp.y()-(int)(3*zoomFactor())); + p.drawLine(hp.x(), hp.y()+(int)(3*zoomFactor()), + hp.x(), hpArea.bottom()); + p.drawLine(hpArea.x(), hp.y(), + hp.x()-(int)(3*zoomFactor()), hp.y()); + p.drawLine(hp.x()+(int)(3*zoomFactor()), hp.y(), + hpArea.right(), hp.y()); + } + } + } + p.end(); + } +} + +void ImageRegionWidget::setCenterContentsPosition() +{ + center(contentsWidth()/2, contentsHeight()/2); + slotZoomFactorChanged(); +} + +void ImageRegionWidget::setContentsPosition(int x, int y, bool targetDone) +{ + if( targetDone ) + m_movingInProgress = false; + + setContentsPos(x, y); + + if( targetDone ) + slotZoomFactorChanged(); +} + +void ImageRegionWidget::backupPixmapRegion() +{ + d->pixmapRegion = TQPixmap(); +} + +void ImageRegionWidget::restorePixmapRegion() +{ + m_movingInProgress = true; + viewport()->repaint(false); +} + +void ImageRegionWidget::updatePreviewImage(DImg *img) +{ + DImg image = img->copy(); + TQRect r = getLocalImageRegionToRender(); + image.resize(r.width(), r.height()); + + // Because image plugins are tool witch only work on image data, the DImg container + // do not contain metadata from original image. About Color Managed View, we need to + // restore the embedded ICC color profile. + image.setICCProfil(d->image.getICCProfil()); + d->pixmapRegion = d->iface->convertToPixmap(image); +} + +DImg ImageRegionWidget::getImageRegionImage() +{ + return (d->image.copy(getImageRegionToRender())); +} + +TQRect ImageRegionWidget::getImageRegionToRender() +{ + TQRect r = getLocalImageRegionToRender(); + + int x = (int)(((double)r.x() / tileSize()) * floor(tileSize() / zoomFactor())); + int y = (int)(((double)r.y() / tileSize()) * floor(tileSize() / zoomFactor())); + int w = (int)(((double)r.width() / tileSize()) * floor(tileSize() / zoomFactor())); + int h = (int)(((double)r.height() / tileSize()) * floor(tileSize() / zoomFactor())); + + TQRect rect(x, y, w, h); + return (rect); +} + +TQRect ImageRegionWidget::getLocalImageRegionToRender() +{ + TQRect region; + + if (d->separateView == SeparateViewVertical) + { + region = TQRect((int)ceilf(contentsX()+visibleWidth()/2.0), contentsY(), + (int)ceilf(visibleWidth()/2.0), visibleHeight()); + } + else if (d->separateView == SeparateViewHorizontal) + { + region = TQRect(contentsX(), (int)ceilf(contentsY()+visibleHeight()/2.0), + visibleWidth(), (int)ceilf(visibleHeight()/2.0)); + } + else if (d->separateView == SeparateViewDuplicateVert) + { + region = TQRect(contentsX(), contentsY(), + (int)ceilf(visibleWidth()/2.0), visibleHeight()); + } + else if (d->separateView == SeparateViewDuplicateHorz) + { + region = TQRect(contentsX(), contentsY(), + visibleWidth(), (int)ceilf(visibleHeight()/2.0)); + } + else + { + region = TQRect(contentsX(), contentsY(), + visibleWidth(), visibleHeight()); + } + + return (region); +} + +TQRect ImageRegionWidget::getLocalTargetImageRegion() +{ + TQRect region = getLocalImageRegionToRender(); + + if (d->separateView == SeparateViewDuplicateVert) + region.moveBy(region.width(), 0); + else if (d->separateView == SeparateViewDuplicateHorz) + region.moveBy(0, region.height()); + + return region; +} + +void ImageRegionWidget::setContentsSize() +{ + switch (d->separateView) + { + case SeparateViewVertical: + case SeparateViewHorizontal: + case SeparateViewNone: + { + PreviewWidget::setContentsSize(); + break; + } + case SeparateViewDuplicateVert: + { + resizeContents(zoomWidth()+visibleWidth()/2, zoomHeight()); + break; + } + case SeparateViewDuplicateHorz: + { + resizeContents(zoomWidth(), zoomHeight()+visibleHeight()/2); + break; + } + default: + DWarning() << "Unknown separation view specified" << endl; + } +} + +void ImageRegionWidget::contentsWheelEvent(TQWheelEvent *e) +{ + e->accept(); + + if (e->state() & TQt::ControlButton) + { + if (e->delta() < 0 && !maxZoom()) + slotIncreaseZoom(); + else if (e->delta() > 0 && !minZoom()) + slotDecreaseZoom(); + return; + } +} + +} // NameSpace Digikam diff --git a/src/libs/widgets/imageplugins/imageregionwidget.h b/src/libs/widgets/imageplugins/imageregionwidget.h new file mode 100644 index 00000000..8555703d --- /dev/null +++ b/src/libs/widgets/imageplugins/imageregionwidget.h @@ -0,0 +1,115 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2004-08-17 + * Description : a widget to draw an image clip region. + * + * Copyright (C) 2004-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEREGIONWIDGET_H +#define IMAGEREGIONWIDGET_H + +// TQt includes. + +#include <tqrect.h> + +// Local includes. + +#include "previewwidget.h" +#include "dimg.h" +#include "digikam_export.h" + +namespace Digikam +{ + +class ImageRegionWidgetPriv; + +class DIGIKAM_EXPORT ImageRegionWidget : public PreviewWidget +{ +TQ_OBJECT + + +public: + + enum SeparateViewMode + { + SeparateViewHorizontal=0, + SeparateViewVertical, + SeparateViewNone, + SeparateViewDuplicateVert, + SeparateViewDuplicateHorz + }; + +public: + + ImageRegionWidget(int wp, int hp, TQWidget *parent=0, bool scrollBar=true); + ~ImageRegionWidget(); + + void setContentsPosition(int x, int y, bool targetDone); + void setCenterContentsPosition(); + + /** To get image region including original or/and target area depending of separate view mode. + The region is given using not scaled image unit.*/ + TQRect getImageRegion(); + + /** To get target image region area to render */ + TQRect getImageRegionToRender(); + + /** To get target image region image to use for render operations */ + DImg getImageRegionImage(); + + void updatePreviewImage(DImg *img); + + void backupPixmapRegion(); + void restorePixmapRegion(); + + void setHighLightPoints(const TQPointArray& pointsList); + void drawSeparateView(); + +public slots: + + void slotSeparateViewToggled(int mode); + +private slots: + + void slotZoomFactorChanged(); + +private: + + void updatePixmap(DImg& img); + TQRect getLocalTargetImageRegion(); + TQRect getLocalImageRegionToRender(); + void viewportPaintExtraData(); + int previewWidth(); + int previewHeight(); + bool previewIsNull(); + void resetPreview(); + void setContentsSize(); + void resizeEvent(TQResizeEvent *); + void contentsWheelEvent(TQWheelEvent *); + + inline void paintPreview(TQPixmap *pix, int sx, int sy, int sw, int sh); + +private: + + ImageRegionWidgetPriv* d; +}; + +} // NameSpace Digikam + +#endif /* IMAGEREGIONWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/imagewidget.cpp b/src/libs/widgets/imageplugins/imagewidget.cpp new file mode 100644 index 00000000..ab73bbf7 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagewidget.cpp @@ -0,0 +1,347 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-02-01 + * Description : a widget to display an image preview with some + * modes to compare effect results. + * + * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqwhatsthis.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqhbuttongroup.h> +#include <tqpushbutton.h> + +// KDE includes. + +#include <ksqueezedtextlabel.h> +#include <kdialog.h> +#include <tdeapplication.h> +#include <tdelocale.h> +#include <kiconloader.h> +#include <tdeconfig.h> +#include <kstandarddirs.h> + +// Local includes. + +#include "ddebug.h" +#include "imagewidget.h" +#include "imagewidget.moc" + +namespace Digikam +{ + +class ImageWidgetPriv +{ +public: + + ImageWidgetPriv() + { + spotInfoLabel = 0; + previewButtons = 0; + underExposureButton = 0; + overExposureButton = 0; + previewWidget = 0; + } + + TQString settingsSection; + + TQHButtonGroup *previewButtons; + + TQPushButton *underExposureButton; + TQPushButton *overExposureButton; + + KSqueezedTextLabel *spotInfoLabel; + + ImageGuideWidget *previewWidget; +}; + +ImageWidget::ImageWidget(const TQString& settingsSection, TQWidget *parent, + const TQString& previewWhatsThis, bool prevModeOptions, + int guideMode, bool guideVisible, bool useImageSelection) + : TQWidget(parent) +{ + d = new ImageWidgetPriv; + d->settingsSection = settingsSection; + + // ------------------------------------------------------------- + + TQGridLayout* grid = new TQGridLayout(this, 2, 3); + + d->spotInfoLabel = new KSqueezedTextLabel(this); + d->spotInfoLabel->setAlignment(TQt::AlignRight); + + // ------------------------------------------------------------- + + d->previewButtons = new TQHButtonGroup(this); + d->previewButtons->setExclusive(true); + d->previewButtons->setInsideMargin(0); + d->previewButtons->setFrameShape(TQFrame::NoFrame); + + TQPushButton *previewOriginalButton = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewOriginalButton, ImageGuideWidget::PreviewOriginalImage); + TDEGlobal::dirs()->addResourceType("original", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("original", "original.png"); + previewOriginalButton->setPixmap( TQPixmap( directory + "original.png" ) ); + previewOriginalButton->setToggleButton(true); + TQWhatsThis::add( previewOriginalButton, i18n( "<p>If you enable this option, you will see " + "the original image." ) ); + + TQPushButton *previewBothButtonVert = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewBothButtonVert, ImageGuideWidget::PreviewBothImagesVertCont); + TDEGlobal::dirs()->addResourceType("bothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothvert", "bothvert.png"); + previewBothButtonVert->setPixmap( TQPixmap( directory + "bothvert.png" ) ); + previewBothButtonVert->setToggleButton(true); + TQWhatsThis::add( previewBothButtonVert, i18n( "<p>If you enable this option, the preview area will " + "split vertically. " + "A contiguous area of the image will be shown, " + "with one half from the original image, " + "the other half from the target image.") ); + + TQPushButton *previewBothButtonHorz = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewBothButtonHorz, ImageGuideWidget::PreviewBothImagesHorzCont); + TDEGlobal::dirs()->addResourceType("bothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("bothhorz", "bothhorz.png"); + previewBothButtonHorz->setPixmap( TQPixmap( directory + "bothhorz.png" ) ); + previewBothButtonHorz->setToggleButton(true); + TQWhatsThis::add( previewBothButtonHorz, i18n( "<p>If you enable this option, the preview area will " + "split horizontally. " + "A contiguous area of the image will be shown, " + "with one half from the original image, " + "the other half from the target image.") ); + + TQPushButton *previewDuplicateBothButtonVert = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewDuplicateBothButtonVert, ImageGuideWidget::PreviewBothImagesVert); + TDEGlobal::dirs()->addResourceType("duplicatebothvert", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothvert", "duplicatebothvert.png"); + previewDuplicateBothButtonVert->setPixmap( TQPixmap( directory + "duplicatebothvert.png" ) ); + previewDuplicateBothButtonVert->setToggleButton(true); + TQWhatsThis::add( previewDuplicateBothButtonVert, i18n( "<p>If you enable this option, the preview area will " + "split vertically. " + "The same part of the original and the target image " + "will be shown side by side.") ); + + TQPushButton *previewDupplicateBothButtonHorz = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewDupplicateBothButtonHorz, ImageGuideWidget::PreviewBothImagesHorz); + TDEGlobal::dirs()->addResourceType("duplicatebothhorz", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("duplicatebothhorz", "duplicatebothhorz.png"); + previewDupplicateBothButtonHorz->setPixmap( TQPixmap( directory + "duplicatebothhorz.png" ) ); + previewDupplicateBothButtonHorz->setToggleButton(true); + TQWhatsThis::add( previewDupplicateBothButtonHorz, i18n( "<p>If you enable this option, the preview area will " + "split horizontally. " + "The same part of the original and the target image " + "will be shown side by side.") ); + + TQPushButton *previewtargetButton = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewtargetButton, ImageGuideWidget::PreviewTargetImage); + TDEGlobal::dirs()->addResourceType("target", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("target", "target.png"); + previewtargetButton->setPixmap( TQPixmap( directory + "target.png" ) ); + previewtargetButton->setToggleButton(true); + TQWhatsThis::add( previewtargetButton, i18n( "<p>If you enable this option, you will see " + "the target image." ) ); + + TQPushButton *previewToggleMouseOverButton = new TQPushButton( d->previewButtons ); + d->previewButtons->insert(previewToggleMouseOverButton, ImageGuideWidget::PreviewToggleOnMouseOver); + TDEGlobal::dirs()->addResourceType("togglemouseover", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("togglemouseover", "togglemouseover.png"); + previewToggleMouseOverButton->setPixmap( TQPixmap( directory + "togglemouseover.png" ) ); + previewToggleMouseOverButton->setToggleButton(true); + TQWhatsThis::add( previewToggleMouseOverButton, i18n( "<p>If you enable this option, you will see " + "the original image when the mouse is over image area, " + "else the target image." ) ); + + // ------------------------------------------------------------- + + TQHButtonGroup *exposureButtons = new TQHButtonGroup(this); + exposureButtons->setInsideMargin(0); + exposureButtons->setFrameShape(TQFrame::NoFrame); + + d->underExposureButton = new TQPushButton(exposureButtons); + exposureButtons->insert(d->underExposureButton, UnderExposure); + d->underExposureButton->setPixmap(SmallIcon("underexposure")); + d->underExposureButton->setToggleButton(true); + TQWhatsThis::add(d->underExposureButton, i18n("<p>Set this option to display black " + "overlaid on the preview. This will help you to avoid " + "under-exposing the image." ) ); + + d->overExposureButton = new TQPushButton(exposureButtons); + exposureButtons->insert(d->overExposureButton, OverExposure); + d->overExposureButton->setPixmap(SmallIcon("overexposure")); + d->overExposureButton->setToggleButton(true); + TQWhatsThis::add(d->overExposureButton, i18n("<p>Set this option on display white " + "overlaid on the preview. This will help you to avoid " + "over-exposing the image." ) ); + + // ------------------------------------------------------------- + + TQFrame *frame = new TQFrame(this); + frame->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); + TQVBoxLayout* l = new TQVBoxLayout(frame, 5, 0); + d->previewWidget = new ImageGuideWidget(480, 320, frame, guideVisible, + guideMode, TQt::red, 1, false, + useImageSelection); + TQWhatsThis::add( d->previewWidget, previewWhatsThis); + l->addWidget(d->previewWidget, 0); + + // ------------------------------------------------------------- + + grid->addMultiCellWidget(d->previewButtons, 1, 1, 0, 0); + grid->addMultiCellWidget(d->spotInfoLabel, 1, 1, 1, 1); + grid->addMultiCellWidget(exposureButtons, 1, 1, 2, 2); + grid->addMultiCellWidget(frame, 3, 3, 0, 2); + grid->setColSpacing(1, KDialog::spacingHint()); + grid->setRowSpacing(0, KDialog::spacingHint()); + grid->setRowSpacing(2, KDialog::spacingHint()); + grid->setRowStretch(3, 10); + grid->setColStretch(1, 10); + + // ------------------------------------------------------------- + + connect(d->previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SIGNAL(signalResized())); + + connect(d->previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const TQPoint & )), + this, TQ_SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const TQPoint & ))); + + connect(d->previewWidget, TQ_SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotUpdateSpotInfo( const Digikam::DColor &, const TQPoint & ))); + + connect(d->previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & ))); + + connect(d->previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotUpdateSpotInfo( const Digikam::DColor &, const TQPoint & ))); + + connect(d->previewButtons, TQ_SIGNAL(released(int)), + d->previewWidget, TQ_SLOT(slotChangeRenderingPreviewMode(int))); + + connect(d->underExposureButton, TQ_SIGNAL(toggled(bool)), + d->previewWidget, TQ_SLOT(slotToggleUnderExposure(bool))); + + connect(d->overExposureButton, TQ_SIGNAL(toggled(bool)), + d->previewWidget, TQ_SLOT(slotToggleOverExposure(bool))); + + // ------------------------------------------------------------- + + if (prevModeOptions) + readSettings(); + else + { + setRenderingPreviewMode(ImageGuideWidget::NoPreviewMode); + d->spotInfoLabel->hide(); + d->previewButtons->hide(); + exposureButtons->hide(); + } +} + +ImageWidget::~ImageWidget() +{ + writeSettings(); + delete d; +} + +ImageIface* ImageWidget::imageIface() +{ + return d->previewWidget->imageIface(); +} + +void ImageWidget::updatePreview() +{ + d->previewWidget->updatePreview(); +} + +void ImageWidget::slotChangeGuideColor(const TQColor &color) +{ + d->previewWidget->slotChangeGuideColor(color); +} + +void ImageWidget::slotChangeGuideSize(int size) +{ + d->previewWidget->slotChangeGuideSize(size); +} + +void ImageWidget::resetSpotPosition() +{ + d->previewWidget->resetSpotPosition(); +} + +TQPoint ImageWidget::getSpotPosition() +{ + return ( d->previewWidget->getSpotPosition() ); +} + +DColor ImageWidget::getSpotColor(int getColorFrom) +{ + return ( d->previewWidget->getSpotColor(getColorFrom) ); +} + +void ImageWidget::setSpotVisible(bool spotVisible, bool blink) +{ + d->previewWidget->setSpotVisible(spotVisible, blink); +} + +int ImageWidget::getRenderingPreviewMode() +{ + return ( d->previewWidget->getRenderingPreviewMode() ); +} + +void ImageWidget::setRenderingPreviewMode(int mode) +{ + d->previewButtons->setButton(mode); + d->previewWidget->slotChangeRenderingPreviewMode(mode); +} + +void ImageWidget::slotUpdateSpotInfo(const Digikam::DColor &col, const TQPoint &point) +{ + DColor color = col; + d->spotInfoLabel->setText(i18n("(%1,%2) RGBA:%3,%4,%5,%6") + .arg(point.x()).arg(point.y()) + .arg(color.red()).arg(color.green()) + .arg(color.blue()).arg(color.alpha()) ); +} + +void ImageWidget::readSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + + d->underExposureButton->setOn(config->readBoolEntry("Under Exposure Indicator", false)); + d->overExposureButton->setOn(config->readBoolEntry("Over Exposure Indicator", false)); + + int mode = config->readNumEntry("Separate View", ImageGuideWidget::PreviewBothImagesVertCont); + mode = TQMAX(ImageGuideWidget::PreviewOriginalImage, mode); + mode = TQMIN(ImageGuideWidget::NoPreviewMode, mode); + setRenderingPreviewMode(mode); +} + +void ImageWidget::writeSettings() +{ + TDEConfig *config = kapp->config(); + config->setGroup(d->settingsSection); + config->writeEntry("Separate View", getRenderingPreviewMode()); + config->writeEntry("Under Exposure Indicator", d->underExposureButton->isOn()); + config->writeEntry("Over Exposure Indicator", d->overExposureButton->isOn()); + config->sync(); +} + +} // namespace Digikam diff --git a/src/libs/widgets/imageplugins/imagewidget.h b/src/libs/widgets/imageplugins/imagewidget.h new file mode 100644 index 00000000..ebdf92e9 --- /dev/null +++ b/src/libs/widgets/imageplugins/imagewidget.h @@ -0,0 +1,106 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-02-01 + * Description : a widget to display an image preview with some + * modes to compare effect results. + * + * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEWIDGET_H +#define IMAGEWIDGET_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqpoint.h> +#include <tqcolor.h> +#include <tqstring.h> + +// Local includes. + +#include "dcolor.h" +#include "imageguidewidget.h" +#include "digikam_export.h" + +namespace Digikam +{ + +class ImageIface; +class ImageWidgetPriv; + +class DIGIKAM_EXPORT ImageWidget : public TQWidget +{ +TQ_OBJECT + + +public: + + enum ExposureIndicator + { + UnderExposure=0, + OverExposure + }; + +public: + + ImageWidget(const TQString& settingsSection, TQWidget *parent=0, + const TQString& previewWhatsThis=TQString(), bool prevModeOptions=true, + int guideMode=ImageGuideWidget::PickColorMode, + bool guideVisible=true, bool useImageSelection=false); + ~ImageWidget(); + + ImageIface* imageIface(); + + TQPoint getSpotPosition(); + DColor getSpotColor(int getColorFrom); + void setSpotVisible(bool spotVisible, bool blink=false); + int getRenderingPreviewMode(); + void resetSpotPosition(); + void updatePreview(); + void writeSettings(); + + void setRenderingPreviewMode(int mode); + +public slots: + + void slotChangeGuideColor(const TQColor &color); + void slotChangeGuideSize(int size); + +signals: + + void spotPositionChangedFromOriginal( const Digikam::DColor &color, const TQPoint &position ); + void spotPositionChangedFromTarget( const Digikam::DColor &color, const TQPoint &position ); + void signalResized(); + +private slots: + + void slotUpdateSpotInfo(const Digikam::DColor &col, const TQPoint &point); + +private: + + void readSettings(); + +private: + + ImageWidgetPriv* d; +}; + +} // namespace Digikam + +#endif /* IMAGEWIDGET_H */ diff --git a/src/libs/widgets/imageplugins/listboxpreviewitem.cpp b/src/libs/widgets/imageplugins/listboxpreviewitem.cpp new file mode 100644 index 00000000..8ba63a61 --- /dev/null +++ b/src/libs/widgets/imageplugins/listboxpreviewitem.cpp @@ -0,0 +1,62 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-10-05 + * Description : a TQListBoxItem which can display an image preview + * as a thumbnail and a customized qwhatsthis class + * for listbox items + * + * Copyright (C) 2006-2007 by Guillaume Laurent <glaurent@telegraph-road.org> + * + * 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, 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. + * + * ============================================================ */ + +// Local includes. + +#include "listboxpreviewitem.h" + +namespace Digikam +{ + +int ListBoxPreviewItem::height(const TQListBox *lb) const +{ + int height = TQListBoxPixmap::height(lb); + return TQMAX(height, pixmap()->height() + 5); +} + +int ListBoxPreviewItem::width(const TQListBox *lb) const +{ + int width = TQListBoxPixmap::width(lb); + return TQMAX(width, pixmap()->width() + 5); +} + +// ------------------------------------------------------------------- + +TQString ListBoxWhatsThis::text(const TQPoint &p) +{ + TQListBoxItem* item = m_listBox->itemAt(p); + + if (item != 0) + return m_itemWhatsThisMap[item]; + + return TQString(); +} + +void ListBoxWhatsThis::add(TQListBoxItem* item, const TQString& text) +{ + m_itemWhatsThisMap[item] = text; +} + +} // namespace Digikam diff --git a/src/libs/widgets/imageplugins/listboxpreviewitem.h b/src/libs/widgets/imageplugins/listboxpreviewitem.h new file mode 100644 index 00000000..50b769c6 --- /dev/null +++ b/src/libs/widgets/imageplugins/listboxpreviewitem.h @@ -0,0 +1,80 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-10-05 + * Description : a TQListBoxItem which can display an image preview + * as a thumbnail and a customized qwhatsthis class + * for listbox items + * + * Copyright (C) 2006-2007 by Guillaume Laurent <glaurent@telegraph-road.org> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef LISTBOXPREVIEWITEM_H +#define LISTBOXPREVIEWITEM_H + +// TQt includes. + +#include <tqmap.h> +#include <tqlistbox.h> +#include <tqwhatsthis.h> +#include <tqpixmap.h> + +// Local includes. + +#include "digikam_export.h" + +namespace Digikam +{ + +class DIGIKAM_EXPORT ListBoxPreviewItem : public TQListBoxPixmap +{ + +public: + + ListBoxPreviewItem(TQListBox *listbox, const TQPixmap &pix, const TQString &text) + : TQListBoxPixmap(listbox, pix, text) {}; + + ListBoxPreviewItem(const TQPixmap &pix, const TQString &text) + : TQListBoxPixmap(pix, text) {}; + + virtual int height ( const TQListBox * lb ) const; + virtual int width ( const TQListBox * lb ) const; +}; + +/** + * A qwhatthis class which can be pointed to a specific item + * in a TQListBox rather than the TQListBox itself + * + */ +class DIGIKAM_EXPORT ListBoxWhatsThis : public TQWhatsThis +{ + +public: + + ListBoxWhatsThis(TQListBox* w) : TQWhatsThis(w), m_listBox(w) {} + virtual TQString text (const TQPoint &); + void add(TQListBoxItem*, const TQString& text); + +protected: + + TQMap<TQListBoxItem*, TQString> m_itemWhatsThisMap; + TQListBox *m_listBox; +}; + +} // namespace Digikam + +#endif // LISTBOXPREVIEWITEM_H |