/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-08-22 * Description : a generic widget to display a panel to choose * a rectangular image area. * * Copyright (C) 2004-2008 by Gilles Caulier * * 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 // TQt includes. #include #include #include #include // KDE includes. #include // Local includes. #include "ddebug.h" #include "paniconwidget.h" #include "paniconwidget.moc" namespace Digikam { class PanIconWidgetPriv { public: PanIconWidgetPriv() { moveSelection = false; } bool moveSelection; int xpos; int ypos; TQRect regionSelection; // Original size image selection. TQImage image; }; PanIconWidget::PanIconWidget(TQWidget *parent, WFlags flags) : TQWidget(parent, 0, flags) { d = new PanIconWidgetPriv; m_flicker = false; m_timerID = 0; m_pixmap = 0; m_zoomFactor = 1.0; setBackgroundMode(TQt::NoBackground); setMouseTracking(true); } PanIconWidget::~PanIconWidget() { if (m_timerID) killTimer(m_timerID); if (m_pixmap) delete m_pixmap; delete d; } void PanIconWidget::setImage(int previewWidth, int previewHeight, const TQImage& image) { TQSize sz(image.width(), image.height()); sz.tqscale(previewWidth, previewHeight, TQSize::ScaleMin); m_pixmap = new TQPixmap(previewWidth, previewHeight); m_width = sz.width(); m_height = sz.height(); d->image = image.smoothScale(sz.width(), sz.height()); m_orgWidth = image.width(); m_orgHeight = image.height(); m_zoomedOrgWidth = image.width(); m_zoomedOrgHeight = image.height(); 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); } void PanIconWidget::setImage(int previewWidth, int previewHeight, const DImg& image) { DImg img(image); setImage(previewWidth, previewHeight, img.copyTQImage()); } void PanIconWidget::slotZoomFactorChanged(double factor) { if (m_zoomFactor == factor) return; m_zoomFactor = factor; m_zoomedOrgWidth = (int)(m_orgWidth * factor); m_zoomedOrgHeight = (int)(m_orgHeight * factor); updatePixmap(); tqrepaint(false); } void PanIconWidget::setRegionSelection(const TQRect& regionSelection) { d->regionSelection = regionSelection; m_localRegionSelection.setX( m_rect.x() + (int)((float)d->regionSelection.x() * ((float)m_width / (float)m_zoomedOrgWidth)) ); m_localRegionSelection.setY( m_rect.y() + (int)((float)d->regionSelection.y() * ((float)m_height / (float)m_zoomedOrgHeight)) ); m_localRegionSelection.setWidth( (int)((float)d->regionSelection.width() * ((float)m_width / (float)m_zoomedOrgWidth)) ); m_localRegionSelection.setHeight( (int)((float)d->regionSelection.height() * ((float)m_height / (float)m_zoomedOrgHeight)) ); updatePixmap(); tqrepaint(false); } TQRect PanIconWidget::getRegionSelection() { return (d->regionSelection); } void PanIconWidget::setCursorToLocalRegionSelectionCenter() { TQCursor::setPos(mapToGlobal(m_localRegionSelection.center())); } void PanIconWidget::setCenterSelection() { setRegionSelection(TQRect( (int)(((float)m_zoomedOrgWidth / 2.0) - ((float)d->regionSelection.width() / 2.0)), (int)(((float)m_zoomedOrgHeight / 2.0) - ((float)d->regionSelection.height() / 2.0)), d->regionSelection.width(), d->regionSelection.height())); } void PanIconWidget::regionSelectionMoved(bool targetDone) { if (targetDone) { updatePixmap(); tqrepaint(false); } int x = (int)lround( ((float)m_localRegionSelection.x() - (float)m_rect.x() ) * ((float)m_zoomedOrgWidth / (float)m_width) ); int y = (int)lround( ((float)m_localRegionSelection.y() - (float)m_rect.y() ) * ((float)m_zoomedOrgHeight / (float)m_height) ); int w = (int)lround( (float)m_localRegionSelection.width() * ((float)m_zoomedOrgWidth / (float)m_width) ); int h = (int)lround( (float)m_localRegionSelection.height() * ((float)m_zoomedOrgHeight / (float)m_height) ); d->regionSelection.setX(x); d->regionSelection.setY(y); d->regionSelection.setWidth(w); d->regionSelection.setHeight(h); emit signalSelectionMoved( d->regionSelection, targetDone ); } void PanIconWidget::updatePixmap() { // Drawing background and image. m_pixmap->fill(colorGroup().background()); bitBlt(m_pixmap, m_rect.x(), m_rect.y(), &d->image, 0, 0); TQPainter p(m_pixmap); // 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()); p.end(); } void PanIconWidget::paintEvent(TQPaintEvent*) { bitBlt(this, 0, 0, m_pixmap); } void PanIconWidget::setMouseFocus() { raise(); d->xpos = m_localRegionSelection.center().x(); d->ypos = m_localRegionSelection.center().y(); d->moveSelection = true; setCursor( KCursor::sizeAllCursor() ); emit signalSelectionTakeFocus(); } void PanIconWidget::hideEvent(TQHideEvent *e) { TQWidget::hideEvent(e); if ( d->moveSelection ) { d->moveSelection = false; setCursor( KCursor::arrowCursor() ); emit signalHiden(); } } void PanIconWidget::mousePressEvent ( TQMouseEvent * e ) { if ( (e->button() == Qt::LeftButton || e->button() == Qt::MidButton) && m_localRegionSelection.contains( e->x(), e->y() ) ) { d->xpos = e->x(); d->ypos = e->y(); d->moveSelection = true; setCursor( KCursor::sizeAllCursor() ); emit signalSelectionTakeFocus(); } } void PanIconWidget::mouseMoveEvent ( TQMouseEvent * e ) { if ( d->moveSelection && (e->state() == Qt::LeftButton || e->state() == Qt::MidButton) ) { int newxpos = e->x(); int newypos = e->y(); m_localRegionSelection.moveBy (newxpos - d->xpos, newypos - d->ypos); d->xpos = newxpos; d->ypos = newypos; // Perform normalization of selection area. if (m_localRegionSelection.left() < m_rect.left()) m_localRegionSelection.moveLeft(m_rect.left()); if (m_localRegionSelection.top() < m_rect.top()) m_localRegionSelection.moveTop(m_rect.top()); if (m_localRegionSelection.right() > m_rect.right()) m_localRegionSelection.moveRight(m_rect.right()); if (m_localRegionSelection.bottom() > m_rect.bottom()) m_localRegionSelection.moveBottom(m_rect.bottom()); updatePixmap(); tqrepaint(false); regionSelectionMoved(false); return; } else { if ( m_localRegionSelection.contains( e->x(), e->y() ) ) setCursor( KCursor::handCursor() ); else setCursor( KCursor::arrowCursor() ); } } void PanIconWidget::mouseReleaseEvent ( TQMouseEvent * ) { if ( d->moveSelection ) { d->moveSelection = false; setCursor( KCursor::arrowCursor() ); regionSelectionMoved(true); } } void PanIconWidget::timerEvent(TQTimerEvent * e) { if (e->timerId() == m_timerID) { m_flicker = !m_flicker; updatePixmap(); tqrepaint(false); } else TQWidget::timerEvent(e); } } // NameSpace Digikam