summaryrefslogtreecommitdiffstats
path: root/digikam/imageplugins/superimpose/superimposewidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'digikam/imageplugins/superimpose/superimposewidget.cpp')
-rw-r--r--digikam/imageplugins/superimpose/superimposewidget.cpp329
1 files changed, 329 insertions, 0 deletions
diff --git a/digikam/imageplugins/superimpose/superimposewidget.cpp b/digikam/imageplugins/superimpose/superimposewidget.cpp
new file mode 100644
index 0000000..e5c8b2f
--- /dev/null
+++ b/digikam/imageplugins/superimpose/superimposewidget.cpp
@@ -0,0 +1,329 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-01-04
+ * Description : a Digikam image editor plugin for superimpose a
+ * template to an image.
+ *
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
+ *
+ * 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 <cstdio>
+
+// Qt includes.
+
+#include <qpainter.h>
+
+// KDE includes.
+
+#include <kstandarddirs.h>
+#include <kcursor.h>
+#include <kglobal.h>
+
+// Local includes.
+
+#include "superimpose.h"
+#include "superimposewidget.h"
+#include "superimposewidget.moc"
+
+namespace DigikamSuperImposeImagesPlugin
+{
+
+SuperImposeWidget::SuperImposeWidget(int w, int h, QWidget *parent)
+ : QWidget(parent, 0, Qt::WDestructiveClose)
+{
+ m_pixmap = new QPixmap(w, h);
+ m_editMode = MOVE;
+
+ Digikam::ImageIface iface(0, 0);
+ m_w = iface.originalWidth();
+ m_h = iface.originalHeight();
+
+ setBackgroundMode(Qt::NoBackground);
+ setMinimumSize(w, h);
+ setMouseTracking(true);
+
+ resetEdit();
+}
+
+SuperImposeWidget::~SuperImposeWidget()
+{
+ if(m_pixmap)
+ delete m_pixmap;
+}
+
+Digikam::DImg SuperImposeWidget::makeSuperImpose(void)
+{
+ Digikam::ImageIface iface(0, 0);
+ SuperImpose superimpose(iface.getOriginalImg(), &m_template, m_currentSelection);
+ return superimpose.getTargetImage();
+}
+
+void SuperImposeWidget::resetEdit(void)
+{
+ m_zoomFactor = 1.0;
+ m_currentSelection = QRect(m_w/2 - m_rect.width()/2, m_h/2 - m_rect.height()/2,
+ m_rect.width(), m_rect.height());
+ makePixmap();
+ repaint(false);
+}
+
+void SuperImposeWidget::makePixmap(void)
+{
+ Digikam::ImageIface iface(0, 0);
+ SuperImpose superimpose(iface.getOriginalImg(), &m_templateScaled, m_currentSelection);
+ Digikam::DImg image = superimpose.getTargetImage();
+
+ m_pixmap->fill(colorGroup().background());
+ QPainter p(m_pixmap);
+ QPixmap imagePix = image.convertToPixmap();
+ p.drawPixmap(m_rect.x(), m_rect.y(), imagePix, 0, 0, m_rect.width(), m_rect.height());
+ p.end();
+}
+
+void SuperImposeWidget::resizeEvent(QResizeEvent * e)
+{
+ blockSignals(true);
+ delete m_pixmap;
+ int w = e->size().width();
+ int h = e->size().height();
+ m_pixmap = new QPixmap(w, h);
+
+ if (!m_template.isNull())
+ {
+ int templateWidth = m_template.width();
+ int templateHeight = m_template.height();
+
+ if (templateWidth < templateHeight)
+ {
+ int neww = (int) ((float)height() / (float)templateHeight * (float)templateWidth);
+ m_rect = QRect(width()/2-neww/2, 0, neww, height());
+ }
+ else
+ {
+ int newh = (int) ((float)width() / (float)templateWidth * (float)templateHeight);
+ m_rect = QRect(0, height()/2-newh/2, width(), newh);
+ }
+
+ m_templateScaled = m_template.smoothScale(m_rect.width(), m_rect.height());
+ makePixmap();
+ }
+ else
+ {
+ m_rect = QRect();
+ m_pixmap->fill(colorGroup().background());
+ }
+
+ blockSignals(false);
+}
+
+void SuperImposeWidget::paintEvent( QPaintEvent * )
+{
+ bitBlt(this, 0, 0, m_pixmap);
+}
+
+void SuperImposeWidget::slotEditModeChanged(int mode)
+{
+ m_editMode = mode;
+}
+
+void SuperImposeWidget::slotSetCurrentTemplate(const KURL& url)
+{
+ m_template.load(url.path());
+
+ if (m_template.isNull())
+ {
+ m_rect = QRect();
+ return;
+ }
+
+ int templateWidth = m_template.width();
+ int templateHeight = m_template.height();
+
+ if (templateWidth < templateHeight)
+ {
+ int neww = (int) ((float)height() / (float)templateHeight * (float)templateWidth);
+ m_rect = QRect(width()/2-neww/2, 0, neww, height());
+ }
+ else
+ {
+ int newh = (int) ((float)width() / (float)templateWidth * (float)templateHeight);
+ m_rect = QRect(0, height()/2-newh/2, width(), newh);
+ }
+
+ m_templateScaled = m_template.smoothScale(m_rect.width(), m_rect.height());
+
+ m_currentSelection = QRect(m_w/2 - m_rect.width()/2, m_h/2 - m_rect.height()/2, m_rect.width(), m_rect.height());
+ zoomSelection(0);
+}
+
+void SuperImposeWidget::moveSelection(int dx, int dy)
+{
+ QRect selection = m_currentSelection;
+ float wf = (float)selection.width() / (float)m_rect.width();
+ float hf = (float)selection.height() / (float)m_rect.height();
+
+ selection.moveBy( -(int)(wf*(float)dx), -(int)(hf*(float)dy) );
+
+ if (selection.left() < 0)
+ selection.moveLeft(0);
+ if (selection.top() < 0)
+ selection.moveTop(0);
+ if (selection.bottom() > m_h)
+ selection.moveBottom(m_h);
+ if (selection.right() > m_w)
+ selection.moveRight(m_w);
+
+ m_currentSelection = selection;
+}
+
+bool SuperImposeWidget::zoomSelection(float deltaZoomFactor)
+{
+ float newZoom = m_zoomFactor + deltaZoomFactor;
+
+ if (newZoom < 0.0)
+ return false;
+
+ QRect selection = m_currentSelection;
+ int wf = (int)((float)m_rect.width() / newZoom);
+ int hf = (int)((float)m_rect.height() / newZoom);
+ int deltaX = (m_currentSelection.width() - wf) / 2;
+ int deltaY = (m_currentSelection.height() - hf) / 2;
+
+ selection.setLeft(m_currentSelection.left() + deltaX);
+ selection.setTop(m_currentSelection.top() + deltaY);
+ selection.setWidth(wf);
+ selection.setHeight(hf);
+
+ // check that selection is still inside original image
+ QRect orgImageRect(0, 0, m_w, m_h);
+ if (!orgImageRect.contains(selection))
+ {
+ // try to adjust
+ if (selection.left() < 0)
+ selection.moveLeft(0);
+ if (selection.top() < 0)
+ selection.moveTop(0);
+ if (selection.bottom() > m_h)
+ selection.moveBottom(m_h);
+ if (selection.right() > m_w)
+ selection.moveRight(m_w);
+
+ // was it successful?
+ if (selection.contains(orgImageRect))
+ return false;
+
+ }
+
+ m_zoomFactor = newZoom;
+ m_currentSelection = selection;
+
+ makePixmap();
+ repaint(false);
+
+ return true;
+}
+
+void SuperImposeWidget::mousePressEvent ( QMouseEvent * e )
+{
+ if ( isEnabled() && e->button() == Qt::LeftButton &&
+ rect().contains( e->x(), e->y() ) )
+ {
+ switch (m_editMode)
+ {
+ case ZOOMIN:
+ if (zoomSelection(+0.05))
+ moveSelection(width()/2 - e->x(), height()/2 - e->y());
+ break;
+
+ case ZOOMOUT:
+ if (zoomSelection(-0.05))
+ moveSelection(width()/2 - e->x(), height()/2 - e->y());
+ break;
+
+ case MOVE:
+ m_xpos = e->x();
+ m_ypos = e->y();
+ }
+ }
+}
+
+void SuperImposeWidget::mouseReleaseEvent ( QMouseEvent * )
+{
+ setEditModeCursor();
+}
+
+void SuperImposeWidget::mouseMoveEvent ( QMouseEvent * e )
+{
+ if ( isEnabled() )
+ {
+ if ( e->state() == Qt::LeftButton )
+ {
+ switch (m_editMode)
+ {
+ case ZOOMIN:
+ case ZOOMOUT:
+ break;
+
+ case MOVE:
+ int newxpos = e->x();
+ int newypos = e->y();
+
+ if (newxpos < m_rect.left())
+ newxpos = m_rect.left();
+ if (newxpos > m_rect.right())
+ newxpos = m_rect.right();
+ if (newxpos < m_rect.top())
+ newxpos = m_rect.top();
+ if (newxpos > m_rect.bottom())
+ newxpos = m_rect.bottom();
+
+ moveSelection(newxpos - m_xpos, newypos - m_ypos);
+ makePixmap();
+ repaint(false);
+
+ m_xpos = newxpos;
+ m_ypos = newypos;
+ setCursor( KCursor::handCursor() );
+ break;
+ }
+ }
+ else if (rect().contains( e->x(), e->y() ))
+ {
+ setEditModeCursor();
+ }
+ }
+}
+
+void SuperImposeWidget::setEditModeCursor()
+{
+ switch (m_editMode)
+ {
+ case ZOOMIN:
+ case ZOOMOUT:
+ setCursor ( KCursor::crossCursor() );
+ break;
+
+ case MOVE:
+ setCursor ( KCursor::sizeAllCursor() );
+ }
+}
+
+} // NameSpace DigikamSuperImposeImagesPlugin