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 | 
