You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
8.8 KiB
330 lines
8.8 KiB
/* ============================================================
|
|
*
|
|
* 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>
|
|
|
|
// TQt includes.
|
|
|
|
#include <tqpainter.h>
|
|
|
|
// KDE includes.
|
|
|
|
#include <kstandarddirs.h>
|
|
#include <kcursor.h>
|
|
#include <tdeglobal.h>
|
|
|
|
// Local includes.
|
|
|
|
#include "superimpose.h"
|
|
#include "superimposewidget.h"
|
|
#include "superimposewidget.moc"
|
|
|
|
namespace DigikamSuperImposeImagesPlugin
|
|
{
|
|
|
|
SuperImposeWidget::SuperImposeWidget(int w, int h, TQWidget *parent)
|
|
: TQWidget(parent, 0, TQt::WDestructiveClose)
|
|
{
|
|
m_pixmap = new TQPixmap(w, h);
|
|
m_editMode = MOVE;
|
|
|
|
Digikam::ImageIface iface(0, 0);
|
|
m_w = iface.originalWidth();
|
|
m_h = iface.originalHeight();
|
|
|
|
setBackgroundMode(TQt::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 = TQRect(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());
|
|
TQPainter p(m_pixmap);
|
|
TQPixmap 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(TQResizeEvent * e)
|
|
{
|
|
blockSignals(true);
|
|
delete m_pixmap;
|
|
int w = e->size().width();
|
|
int h = e->size().height();
|
|
m_pixmap = new TQPixmap(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 = TQRect(width()/2-neww/2, 0, neww, height());
|
|
}
|
|
else
|
|
{
|
|
int newh = (int) ((float)width() / (float)templateWidth * (float)templateHeight);
|
|
m_rect = TQRect(0, height()/2-newh/2, width(), newh);
|
|
}
|
|
|
|
m_templateScaled = m_template.smoothScale(m_rect.width(), m_rect.height());
|
|
makePixmap();
|
|
}
|
|
else
|
|
{
|
|
m_rect = TQRect();
|
|
m_pixmap->fill(colorGroup().background());
|
|
}
|
|
|
|
blockSignals(false);
|
|
}
|
|
|
|
void SuperImposeWidget::paintEvent( TQPaintEvent * )
|
|
{
|
|
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 = TQRect();
|
|
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 = TQRect(width()/2-neww/2, 0, neww, height());
|
|
}
|
|
else
|
|
{
|
|
int newh = (int) ((float)width() / (float)templateWidth * (float)templateHeight);
|
|
m_rect = TQRect(0, height()/2-newh/2, width(), newh);
|
|
}
|
|
|
|
m_templateScaled = m_template.smoothScale(m_rect.width(), m_rect.height());
|
|
|
|
m_currentSelection = TQRect(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)
|
|
{
|
|
TQRect 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;
|
|
|
|
TQRect 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
|
|
TQRect 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 ( TQMouseEvent * e )
|
|
{
|
|
if ( isEnabled() && e->button() == TQt::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 ( TQMouseEvent * )
|
|
{
|
|
setEditModeCursor();
|
|
}
|
|
|
|
void SuperImposeWidget::mouseMoveEvent ( TQMouseEvent * e )
|
|
{
|
|
if ( isEnabled() )
|
|
{
|
|
if ( e->state() == TQt::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
|