move the AnnotatorEngine base class and the SmoothPath engine out of the private use of the page view annotator

svn path=/trunk/playground/graphics/okular/; revision=600980
This commit is contained in:
Pino Toscano 2006-11-01 15:23:11 +00:00
parent 1285f20c21
commit fdbd0101a4
4 changed files with 241 additions and 179 deletions

View file

@ -78,6 +78,7 @@ set(okularpart_SRCS
ui/embeddedfilesdialog.cpp
ui/annotwindow.cpp
ui/annotationpropertiesdialog.cpp
ui/annotationtools.cpp
ui/annotationwidgets.cpp
ui/minibar.cpp
ui/newstuff.cpp

155
ui/annotationtools.cpp Normal file
View file

@ -0,0 +1,155 @@
/***************************************************************************
* Copyright (C) 2005 by Enrico Ros <eros.kde@email.it> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
// qt / kde includes
#include <qcolor.h>
#include <qpainter.h>
// local includes
#include "core/annotations.h"
#include "annotationtools.h"
AnnotatorEngine::AnnotatorEngine( const QDomElement & engineElement )
: m_engineElement( engineElement ), m_creationCompleted( false )
{
// parse common engine attributes
if ( engineElement.hasAttribute( "color" ) )
m_engineColor = QColor( engineElement.attribute( "color" ) );
// get the annotation element
QDomElement annElement = m_engineElement.firstChild().toElement();
if ( !annElement.isNull() && annElement.tagName() == "annotation" )
m_annotElement = annElement;
}
AnnotatorEngine::~AnnotatorEngine()
{
}
/** SmoothPathEngine */
SmoothPathEngine::SmoothPathEngine( const QDomElement & engineElement )
: AnnotatorEngine( engineElement )
{
// parse engine specific attributes
}
QRect SmoothPathEngine::event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/ )
{
// only proceed if pressing left button
if ( button != Left )
return QRect();
// start operation
if ( type == Press && points.isEmpty() )
{
lastPoint.x = nX;
lastPoint.y = nY;
totalRect.left = totalRect.right = lastPoint.x;
totalRect.top = totalRect.bottom = lastPoint.y;
points.append( lastPoint );
}
// add a point to the path
else if ( type == Move && points.count() > 0 )
{
//double dist = hypot( nX - points.last().x, nY - points.last().y );
//if ( dist > 0.0001 )
//{
// append mouse position (as normalized point) to the list
Okular::NormalizedPoint nextPoint = Okular::NormalizedPoint( nX, nY );
points.append( nextPoint );
// update total rect
double dX = 2.0 / (double)xScale;
double dY = 2.0 / (double)yScale;
totalRect.left = qMin( totalRect.left, nX - dX );
totalRect.top = qMin( totalRect.top, nY - dY );
totalRect.right = qMax( nX + dX, totalRect.right );
totalRect.bottom = qMax( nY + dY, totalRect.bottom );
// paint the difference to previous full rect
Okular::NormalizedRect incrementalRect;
incrementalRect.left = qMin( nextPoint.x, lastPoint.x ) - dX;
incrementalRect.right = qMax( nextPoint.x, lastPoint.x ) + dX;
incrementalRect.top = qMin( nextPoint.y, lastPoint.y ) - dY;
incrementalRect.bottom = qMax( nextPoint.y, lastPoint.y ) + dY;
lastPoint = nextPoint;
return incrementalRect.geometry( (int)xScale, (int)yScale );
//}
}
// terminate process
else if ( type == Release && points.count() > 0 )
{
if ( points.count() < 2 )
points.clear();
else
m_creationCompleted = true;
return totalRect.geometry( (int)xScale, (int)yScale );
}
return QRect();
}
void SmoothPathEngine::paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ )
{
// draw SmoothPaths with at least 2 points
if ( points.count() > 1 )
{
// use engine's color for painting
painter->setPen( QPen( m_engineColor, 1 ) );
QLinkedList<Okular::NormalizedPoint>::iterator pIt = points.begin(), pEnd = points.end();
Okular::NormalizedPoint pA = *pIt;
++pIt;
for ( ; pIt != pEnd; ++pIt )
{
Okular::NormalizedPoint pB = *pIt;
painter->drawLine( (int)(pA.x * (double)xScale), (int)(pA.y * (double)yScale),
(int)(pB.x * (double)xScale), (int)(pB.y * (double)yScale) );
pA = pB;
}
}
}
QList< Okular::Annotation* > SmoothPathEngine::end()
{
m_creationCompleted = false;
// find out annotation's description node
if ( m_annotElement.isNull() )
return QList< Okular::Annotation* >();
// find out annotation's type
Okular::Annotation * ann = 0;
QString typeString = m_annotElement.attribute( "type" );
// create InkAnnotation from path
if ( typeString == "Ink" )
{
Okular::InkAnnotation * ia = new Okular::InkAnnotation();
ann = ia;
if ( m_annotElement.hasAttribute( "width" ) )
ann->style.width = m_annotElement.attribute( "width" ).toDouble();
// fill points
ia->inkPaths.append( points );
// set boundaries
ia->boundary = totalRect;
}
// safety check
if ( !ann )
return QList< Okular::Annotation* >();
// set common attributes
ann->style.color = m_annotElement.hasAttribute( "color" ) ?
m_annotElement.attribute( "color" ) : m_engineColor;
if ( m_annotElement.hasAttribute( "opacity" ) )
ann->style.opacity = m_annotElement.attribute( "opacity", "1.0" ).toDouble();
// return annotation
return QList< Okular::Annotation* >() << ann;
}

84
ui/annotationtools.h Normal file
View file

@ -0,0 +1,84 @@
/***************************************************************************
* Copyright (C) 2005 by Enrico Ros <eros.kde@email.it> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _OKULAR_ANNOTATIONTOOLS_H_
#define _OKULAR_ANNOTATIONTOOLS_H_
#include <qdom.h>
#include <qlinkedlist.h>
#include <qrect.h>
#include "core/area.h"
class QPainter;
class PageViewItem;
namespace Okular {
struct Annotation;
class Page;
}
/**
* @short Engine: filter events to distill Annotation's.
*/
class AnnotatorEngine
{
public:
AnnotatorEngine( const QDomElement & engineElement );
virtual ~AnnotatorEngine();
// enum definitions
enum EventType { Press, Move, Release };
enum Button { None, Left, Right };
// perform operations
virtual QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * page ) = 0;
virtual void paint( QPainter * painter, double xScale, double yScale, const QRect & clipRect ) = 0;
virtual QList< Okular::Annotation* > end() = 0;
// query creation state
//PageViewItem * editingItem() const { return m_lockedItem; }
bool creationCompleted() const { return m_creationCompleted; }
void setItem( PageViewItem * item ) { m_item = item; }
protected:
PageViewItem * item() { return m_item; }
// common engine attributes (the element includes annotation desc)
QDomElement m_engineElement;
QDomElement m_annotElement;
QColor m_engineColor;
// other vars (remove this!)
bool m_creationCompleted;
private:
PageViewItem * m_item;
};
/** @short SmoothPathEngine */
class SmoothPathEngine
: public AnnotatorEngine
{
public:
SmoothPathEngine( const QDomElement & engineElement );
QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/ );
void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ );
QList< Okular::Annotation* > end();
private:
// data
QLinkedList<Okular::NormalizedPoint> points;
Okular::NormalizedRect totalRect;
Okular::NormalizedPoint lastPoint;
};
#endif

View file

@ -32,189 +32,11 @@
#include "core/page.h"
#include "core/annotations.h"
#include "settings.h"
#include "annotationtools.h"
#include "pageview.h"
#include "pageviewutils.h"
#include "pageviewannotator.h"
/**
* @short Engine: filter events to distill an Annotation.
*/
class AnnotatorEngine
{
public:
AnnotatorEngine( const QDomElement & engineElement )
: m_engineElement( engineElement ), m_creationCompleted( false )
{
// parse common engine attributes
if ( engineElement.hasAttribute( "color" ) )
m_engineColor = QColor( engineElement.attribute( "color" ) );
// get the annotation element
QDomElement annElement = m_engineElement.firstChild().toElement();
if ( !annElement.isNull() && annElement.tagName() == "annotation" )
m_annotElement = annElement;
}
virtual ~AnnotatorEngine() {};
// enum definitions
enum EventType { Press, Move, Release };
enum Button { None, Left, Right };
// perform operations
virtual QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * page ) = 0;
virtual void paint( QPainter * painter, double xScale, double yScale, const QRect & clipRect ) = 0;
virtual QList< Okular::Annotation* > end() = 0;
// query creation state
//PageViewItem * editingItem() const { return m_lockedItem; }
bool creationCompleted() const { return m_creationCompleted; }
void setItem( PageViewItem * item ) { m_item = item; }
protected:
PageViewItem * item() { return m_item; }
// common engine attributes (the element includes annotation desc)
QDomElement m_engineElement;
QDomElement m_annotElement;
QColor m_engineColor;
// other vars (remove this!)
bool m_creationCompleted;
private:
PageViewItem * m_item;
};
/** @short SmoothPathEngine */
class SmoothPathEngine : public AnnotatorEngine
{
public:
SmoothPathEngine( const QDomElement & engineElement )
: AnnotatorEngine( engineElement )
{
// parse engine specific attributes
}
QRect event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/ )
{
// only proceed if pressing left button
if ( button != Left )
return QRect();
// start operation
if ( type == Press && points.isEmpty() )
{
lastPoint.x = nX;
lastPoint.y = nY;
totalRect.left = totalRect.right = lastPoint.x;
totalRect.top = totalRect.bottom = lastPoint.y;
points.append( lastPoint );
}
// add a point to the path
else if ( type == Move && points.count() > 0 )
{
//double dist = hypot( nX - points.last().x, nY - points.last().y );
//if ( dist > 0.0001 )
//{
// append mouse position (as normalized point) to the list
Okular::NormalizedPoint nextPoint = Okular::NormalizedPoint( nX, nY );
points.append( nextPoint );
// update total rect
double dX = 2.0 / (double)xScale;
double dY = 2.0 / (double)yScale;
totalRect.left = qMin( totalRect.left, nX - dX );
totalRect.top = qMin( totalRect.top, nY - dY );
totalRect.right = qMax( nX + dX, totalRect.right );
totalRect.bottom = qMax( nY + dY, totalRect.bottom );
// paint the difference to previous full rect
Okular::NormalizedRect incrementalRect;
incrementalRect.left = qMin( nextPoint.x, lastPoint.x ) - dX;
incrementalRect.right = qMax( nextPoint.x, lastPoint.x ) + dX;
incrementalRect.top = qMin( nextPoint.y, lastPoint.y ) - dY;
incrementalRect.bottom = qMax( nextPoint.y, lastPoint.y ) + dY;
lastPoint = nextPoint;
return incrementalRect.geometry( (int)xScale, (int)yScale );
//}
}
// terminate process
else if ( type == Release && points.count() > 0 )
{
if ( points.count() < 2 )
points.clear();
else
m_creationCompleted = true;
return totalRect.geometry( (int)xScale, (int)yScale );
}
return QRect();
}
void paint( QPainter * painter, double xScale, double yScale, const QRect & /*clipRect*/ )
{
// draw SmoothPaths with at least 2 points
if ( points.count() > 1 )
{
// use engine's color for painting
painter->setPen( QPen( m_engineColor, 1 ) );
QLinkedList<Okular::NormalizedPoint>::iterator pIt = points.begin(), pEnd = points.end();
Okular::NormalizedPoint pA = *pIt;
++pIt;
for ( ; pIt != pEnd; ++pIt )
{
Okular::NormalizedPoint pB = *pIt;
painter->drawLine( (int)(pA.x * (double)xScale), (int)(pA.y * (double)yScale),
(int)(pB.x * (double)xScale), (int)(pB.y * (double)yScale) );
pA = pB;
}
}
}
QList< Okular::Annotation* > end()
{
m_creationCompleted = false;
// find out annotation's description node
if ( m_annotElement.isNull() )
return QList< Okular::Annotation* >();
// find out annotation's type
Okular::Annotation * ann = 0;
QString typeString = m_annotElement.attribute( "type" );
// create InkAnnotation from path
if ( typeString == "Ink" )
{
Okular::InkAnnotation * ia = new Okular::InkAnnotation();
ann = ia;
if ( m_annotElement.hasAttribute( "width" ) )
ann->style.width = m_annotElement.attribute( "width" ).toDouble();
// fill points
ia->inkPaths.append( points );
// set boundaries
ia->boundary = totalRect;
}
// safety check
if ( !ann )
return QList< Okular::Annotation* >();
// set common attributes
ann->style.color = m_annotElement.hasAttribute( "color" ) ?
m_annotElement.attribute( "color" ) : m_engineColor;
if ( m_annotElement.hasAttribute( "opacity" ) )
ann->style.opacity = m_annotElement.attribute( "opacity", "1.0" ).toDouble();
// return annotation
return QList< Okular::Annotation* >() << ann;
}
private:
// data
QLinkedList<Okular::NormalizedPoint> points;
Okular::NormalizedRect totalRect;
Okular::NormalizedPoint lastPoint;
};
/** @short PickPointEngine */
class PickPointEngine : public AnnotatorEngine
{