/*************************************************************************** * Copyright (C) 2005 by David Saxton * * david@bluehaze.org * * * * 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. * ***************************************************************************/ #include "dpline.h" #include "libraryitem.h" #include "resizeoverlay.h" #include "variant.h" #include #include #include #include //BEGIN class DPLine Item* DPLine::construct( ItemDocument *itemDocument, bool newItem, const char *id ) { return new DPLine( itemDocument, newItem, id ); } LibraryItem* DPLine::libraryItem() { return new LibraryItem( QString("dp/line"), i18n("Line"), i18n("Other"), KGlobal::iconLoader()->loadIcon( "text", KIcon::Small ), LibraryItem::lit_drawpart, DPLine::construct ); } DPLine::DPLine( ItemDocument *itemDocument, bool newItem, const char *id ) : DrawPart( itemDocument, newItem, id ? id : "line" ) { m_pLineOverlay = new LineOverlay(this); m_name = i18n("Line"); m_desc = i18n("Select the line to position the end points"); createProperty( "line-color", Variant::Type::Color ); property("line-color")->setCaption( i18n("Line Color") ); property("line-color")->setValue(Qt::black); createProperty( "line-width", Variant::Type::Int ); property("line-width")->setCaption( i18n("Line Width") ); property("line-width")->setMinValue(1); property("line-width")->setMaxValue(1000); property("line-width")->setValue(1); createProperty( "line-style", Variant::Type::PenStyle ); property("line-style")->setCaption( i18n("Line Style") ); property("line-style")->setAdvanced(true); setDataPenStyle( "line-style", Qt::SolidLine ); createProperty( "cap-style", Variant::Type::PenCapStyle ); property("cap-style")->setCaption( i18n("Cap Style") ); property("cap-style")->setAdvanced(true); setDataPenCapStyle( "cap-style", Qt::FlatCap ); } DPLine::~DPLine() { } void DPLine::setSelected( bool yes ) { if ( yes == isSelected() ) return; DrawPart::setSelected(yes); m_pLineOverlay->showResizeHandles(yes); } void DPLine::dataChanged() { setPen( QPen( dataColor("line-color"), unsigned( dataInt("line-width") ), getDataPenStyle("line-style"), getDataPenCapStyle("cap-style"), Qt::MiterJoin ) ); postResize(); // in case the pen width has changed update(); } void DPLine::postResize() { int x1 = offsetX(); int y1 = offsetY(); int x2 = x1+width(); int y2 = y1+height(); QPointArray p(4); int pw = pen().width(); int dx = QABS(x1-x2); int dy = QABS(y1-y2); pw = pw*4/3+2; // approx pw*sqrt(2) int px = x1 dy ? (dx*2/dy <= 2) : (dy*2/dx <= 2)) ) { // steep if ( px == py ) { p[0] = QPoint(x1 ,y1+py); p[1] = QPoint(x2-px,y2 ); p[2] = QPoint(x2 ,y2-py); p[3] = QPoint(x1+px,y1 ); } else { p[0] = QPoint(x1+px,y1 ); p[1] = QPoint(x2 ,y2-py); p[2] = QPoint(x2-px,y2 ); p[3] = QPoint(x1 ,y1+py); } } else if ( dx > dy ) { // horizontal p[0] = QPoint(x1+px,y1+py); p[1] = QPoint(x2-px,y2+py); p[2] = QPoint(x2-px,y2-py); p[3] = QPoint(x1+px,y1-py); } else { // vertical p[0] = QPoint(x1+px,y1+py); p[1] = QPoint(x2+px,y2-py); p[2] = QPoint(x2-px,y2-py); p[3] = QPoint(x1-px,y1+py); } setItemPoints( p, false ); } void DPLine::drawShape( QPainter & p ) { int x1 = int(x()+offsetX()); int y1 = int(y()+offsetY()); int x2 = x1+width(); int y2 = y1+height(); p.drawLine( x1, y1, x2, y2 ); } //END class DPLine //BEGIN class DPArrow Item* DPArrow::construct( ItemDocument *itemDocument, bool newItem, const char *id ) { return new DPArrow( itemDocument, newItem, id ); } LibraryItem* DPArrow::libraryItem() { return new LibraryItem( QString("dp/arrow"), i18n("Arrow"), i18n("Other"), KGlobal::iconLoader()->loadIcon( "text", KIcon::Small ), LibraryItem::lit_drawpart, DPArrow::construct ); } DPArrow::DPArrow( ItemDocument *itemDocument, bool newItem, const char *id ) : DPLine( itemDocument, newItem, id ? id : "arrow" ) { m_name = i18n("Arrow"); // We don't want to use the square cap style as it screws up drawing our arrow head QStringList allowed = property("cap-style")->allowed(); allowed.remove( DrawPart::penCapStyleToName( Qt::SquareCap ) ); property("cap-style")->setAllowed(allowed); } DPArrow::~DPArrow() { } void DPArrow::drawShape( QPainter & p ) { int x1 = int(x()+offsetX()); int y1 = int(y()+offsetY()); int x2 = x1+width(); int y2 = y1+height(); p.drawLine( x1, y1, x2, y2 ); double dx = x2-x1; double dy = y2-y1; if ( dx == 0. && dy == 0. ) return; double pi = 3.14159265358979323846264; double arrow_angle = ( dx == 0 ? (dy>0?(pi/2.):(-pi/2.)) : std::atan(dy/dx) ); if ( dx < 0 ) arrow_angle += pi; double head_angle = 0.6; // Angle of arrowhead double head_length = 10.; // Position of arrowhead int x3 = int( x2 + head_length*std::cos( pi + arrow_angle - head_angle ) ); int y3 = int( y2 + head_length*std::sin( pi + arrow_angle - head_angle ) ); int x4 = int( x2 + head_length*std::cos( pi + arrow_angle + head_angle ) ); int y4 = int( y2 + head_length*std::sin( pi + arrow_angle + head_angle ) ); // Draw arrowhead QPen pen = p.pen(); pen.setCapStyle( Qt::RoundCap ); p.setPen(pen); p.setBrush(pen.color()); QPointArray pa(3); pa[0] = QPoint( x2, y2 ); pa[1] = QPoint( x3, y3 ); pa[2] = QPoint( x4, y4 ); p.drawPolygon(pa); p.drawPolyline(pa); // p.drawLine( x2, y2, x3, y3 ); // p.drawLine( x2, y2, x4, y4 ); } //END class DPLine