Commit b44d70a6 authored by Tobias Koenig's avatar Tobias Koenig
Browse files

Implement eraser tool for presentation view

Extend the drawing tool section in top bar with an eraser tool,
which removes parts of the lines that have been drawn before.

FEATURE: 343774
REVIEW: 124689
parent 2a7fda15
......@@ -82,16 +82,18 @@ QCursor AnnotatorEngine::cursor() const
return Qt::CrossCursor;
}
SmoothPath::SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen, qreal opacity )
: points ( points ), pen ( pen ), opacity( opacity )
SmoothPath::SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen, qreal opacity, QPainter::CompositionMode compositionMode )
: points ( points ), pen ( pen ), opacity( opacity ), compositionMode( compositionMode )
{
}
/** SmoothPathEngine */
SmoothPathEngine::SmoothPathEngine( const QDomElement & engineElement )
: AnnotatorEngine( engineElement )
: AnnotatorEngine( engineElement ), compositionMode( QPainter::CompositionMode_SourceOver )
{
// parse engine specific attributes
if ( engineElement.attribute( QStringLiteral("compositionMode"), QStringLiteral("sourceOver") ) == QLatin1String("clear") )
compositionMode = QPainter::CompositionMode_Clear;
}
QRect SmoothPathEngine::event( EventType type, Button button, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/ )
......@@ -153,7 +155,7 @@ void SmoothPathEngine::paint( QPainter * painter, double xScale, double yScale,
const qreal opacity = m_annotElement.attribute( QStringLiteral("opacity"), QStringLiteral("1.0") ).toDouble();
// use engine's color for painting
const SmoothPath path( points, QPen( m_engineColor, penWidth ), opacity );
const SmoothPath path( points, QPen( m_engineColor, penWidth ), opacity, compositionMode );
// draw the path
path.paint( painter, xScale, yScale );
......@@ -164,6 +166,7 @@ void SmoothPath::paint( QPainter * painter, double xScale, double yScale ) const
// draw SmoothPaths with at least 2 points
if ( points.count() > 1 )
{
painter->setCompositionMode( compositionMode );
painter->setPen( pen );
painter->setOpacity( opacity );
......@@ -231,7 +234,7 @@ SmoothPath SmoothPathEngine::endSmoothPath()
const int width = m_annotElement.attribute( QStringLiteral("width"), QStringLiteral("2") ).toInt();
const qreal opacity = m_annotElement.attribute( QStringLiteral("opacity"), QStringLiteral("1.0") ).toDouble();
return SmoothPath( points, QPen(color, width), opacity );
return SmoothPath( points, QPen(color, width), opacity, compositionMode );
}
/* kate: replace-tabs on; indent-width 4; */
......@@ -12,6 +12,7 @@
#include <qdom.h>
#include <qlinkedlist.h>
#include <qpainter.h>
#include <qpen.h>
#include <qrect.h>
......@@ -19,7 +20,6 @@
class QMouseEvent;
class QTabletEvent;
class QPainter;
class PageViewItem;
namespace Okular {
class Annotation;
......@@ -72,13 +72,14 @@ class AnnotatorEngine
class SmoothPath
{
public:
SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen, qreal opacity = 1.0 );
SmoothPath( const QLinkedList<Okular::NormalizedPoint> &points, const QPen &pen, qreal opacity = 1.0, QPainter::CompositionMode compositionMode = QPainter::CompositionMode_SourceOver );
void paint( QPainter * painter, double xScale, double yScale ) const;
private:
const QLinkedList<Okular::NormalizedPoint> points;
const QPen pen;
const qreal opacity;
const QPainter::CompositionMode compositionMode;
};
/** @short SmoothPathEngine */
......@@ -101,6 +102,7 @@ class SmoothPathEngine
QLinkedList<Okular::NormalizedPoint> points;
Okular::NormalizedRect totalRect;
Okular::NormalizedPoint lastPoint;
QPainter::CompositionMode compositionMode;
};
#endif
......
......@@ -166,14 +166,42 @@ void DrawingToolActions::loadTools()
annElem.setAttribute( QStringLiteral("opacity"), opacity );
const QString text = i18n("Drawing Tool: %1", tooltip);
createToolAction( text, tooltip, colorStr, width, opacity, root );
createToolAction( text, tooltip, colorStr, root );
}
drawingDescription = drawingDescription.nextSibling();
}
// add erasure action
{
QDomDocument doc( QStringLiteral("engine") );
QDomElement root = doc.createElement( QStringLiteral("engine") );
root.setAttribute( QStringLiteral("color"), QStringLiteral("transparent") );
root.setAttribute( QStringLiteral("compositionMode"), QStringLiteral("clear") );
doc.appendChild( root );
QDomElement annElem = doc.createElement( QStringLiteral("annotation") );
root.appendChild( annElem );
annElem.setAttribute( QStringLiteral("type"), QStringLiteral("Ink") );
annElem.setAttribute( QStringLiteral("color"), QStringLiteral("transparent") );
annElem.setAttribute( QStringLiteral("width"), 20 );
KActionCollection *ac = static_cast<KActionCollection*>( parent() );
QAction *action = new QAction( ac );
action->setText( i18n("Eraser") );
action->setToolTip( i18n("Eraser") );
action->setCheckable( true );
action->setIcon( QIcon::fromTheme( "draw-eraser" ) );
action->setProperty( "__document", QVariant::fromValue<QDomElement>( root ) );
m_actions.append( action );
ac->addAction( QString("presentation_drawing_eraser"), action );
connect( action, &QAction::triggered, this, &DrawingToolActions::actionTriggered );
}
}
void DrawingToolActions::createToolAction( const QString &text, const QString &toolName, const QString &colorName, const QString &width, const QString &opacity, const QDomElement &root )
void DrawingToolActions::createToolAction( const QString &text, const QString &toolName, const QString &colorName, const QDomElement &root )
{
KActionCollection *ac = static_cast<KActionCollection*>( parent() );
ColorAction *action = new ColorAction( ac );
......
......@@ -37,7 +37,7 @@ private slots:
private:
void loadTools();
void createToolAction( const QString &text, const QString &toolName, const QString &colorName, const QString &width, const QString &opacity, const QDomElement &root );
void createToolAction( const QString &text, const QString &toolName, const QString &colorName, const QDomElement &root );
QList<QAction*> m_actions;
};
......
......@@ -815,16 +815,23 @@ void PresentationWidget::paintEvent( QPaintEvent * pe )
// paint drawings
if ( m_frameIndex != -1 )
{
const QRect & geom = m_frames[ m_frameIndex ]->geometry;
painter.save();
painter.translate( geom.topLeft() );
painter.setRenderHints( QPainter::Antialiasing );
const QRect & geom = m_frames[ m_frameIndex ]->geometry;
QPixmap pm( geom.size() );
pm.fill( Qt::transparent );
QPainter pmPainter( &pm );
pmPainter.setRenderHints( QPainter::Antialiasing );
foreach ( const SmoothPath &drawing, m_frames[ m_frameIndex ]->drawings )
drawing.paint( &painter, geom.width(), geom.height() );
drawing.paint( &pmPainter, geom.width(), geom.height() );
if ( m_drawingEngine && m_drawingRect.intersects( pe->rect() ) )
m_drawingEngine->paint( &painter, geom.width(), geom.height(), m_drawingRect.intersect( pe->rect() ) );
m_drawingEngine->paint( &pmPainter, geom.width(), geom.height(), m_drawingRect.intersect( pe->rect() ) );
painter.setRenderHints( QPainter::Antialiasing );
painter.drawPixmap( geom.topLeft() , pm );
painter.restore();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment