00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "dpline.h"
00012 #include "libraryitem.h"
00013 #include "resizeoverlay.h"
00014 #include "variant.h"
00015
00016 #include <cmath>
00017 #include <kiconloader.h>
00018 #include <klocale.h>
00019 #include <qpainter.h>
00020
00021
00022
00023 Item* DPLine::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00024 {
00025 return new DPLine( itemDocument, newItem, id );
00026 }
00027
00028 LibraryItem* DPLine::libraryItem()
00029 {
00030 return new LibraryItem(
00031 QString("dp/line"),
00032 i18n("Line"),
00033 i18n("Other"),
00034 KGlobal::iconLoader()->loadIcon( "text", KIcon::Small ),
00035 LibraryItem::lit_drawpart,
00036 DPLine::construct );
00037 }
00038
00039 DPLine::DPLine( ItemDocument *itemDocument, bool newItem, const char *id )
00040 : DrawPart( itemDocument, newItem, id ? id : "line" )
00041 {
00042 m_pLineOverlay = new LineOverlay(this);
00043 m_name = i18n("Line");
00044 m_desc = i18n("Select the line to position the end points");
00045
00046 createProperty( "line-color", Variant::Type::Color );
00047 property("line-color")->setCaption( i18n("Line Color") );
00048 property("line-color")->setValue(Qt::black);
00049
00050 createProperty( "line-width", Variant::Type::Int );
00051 property("line-width")->setCaption( i18n("Line Width") );
00052 property("line-width")->setMinValue(1);
00053 property("line-width")->setMaxValue(1000);
00054 property("line-width")->setValue(1);
00055
00056 createProperty( "line-style", Variant::Type::PenStyle );
00057 property("line-style")->setCaption( i18n("Line Style") );
00058 property("line-style")->setAdvanced(true);
00059 setDataPenStyle( "line-style", Qt::SolidLine );
00060
00061 createProperty( "cap-style", Variant::Type::PenCapStyle );
00062 property("cap-style")->setCaption( i18n("Cap Style") );
00063 property("cap-style")->setAdvanced(true);
00064 setDataPenCapStyle( "cap-style", Qt::FlatCap );
00065 }
00066
00067 DPLine::~DPLine()
00068 {
00069 }
00070
00071 void DPLine::setSelected( bool yes )
00072 {
00073 if ( yes == isSelected() )
00074 return;
00075
00076 DrawPart::setSelected(yes);
00077 m_pLineOverlay->showResizeHandles(yes);
00078 }
00079
00080
00081 void DPLine::dataChanged()
00082 {
00083 setPen( QPen( dataColor("line-color"),
00084 unsigned( dataInt("line-width") ),
00085 getDataPenStyle("line-style"),
00086 getDataPenCapStyle("cap-style"),
00087 Qt::MiterJoin ) );
00088
00089 postResize();
00090 update();
00091 }
00092
00093
00094 void DPLine::postResize()
00095 {
00096 int x1 = offsetX();
00097 int y1 = offsetY();
00098 int x2 = x1+width();
00099 int y2 = y1+height();
00100
00101 QPointArray p(4);
00102 int pw = pen().width();
00103 int dx = QABS(x1-x2);
00104 int dy = QABS(y1-y2);
00105 pw = pw*4/3+2;
00106 int px = x1<x2 ? -pw : pw ;
00107 int py = y1<y2 ? -pw : pw ;
00108 if ( dx && dy && (dx > dy ? (dx*2/dy <= 2) : (dy*2/dx <= 2)) ) {
00109
00110 if ( px == py ) {
00111 p[0] = QPoint(x1 ,y1+py);
00112 p[1] = QPoint(x2-px,y2 );
00113 p[2] = QPoint(x2 ,y2-py);
00114 p[3] = QPoint(x1+px,y1 );
00115 } else {
00116 p[0] = QPoint(x1+px,y1 );
00117 p[1] = QPoint(x2 ,y2-py);
00118 p[2] = QPoint(x2-px,y2 );
00119 p[3] = QPoint(x1 ,y1+py);
00120 }
00121 } else if ( dx > dy ) {
00122
00123 p[0] = QPoint(x1+px,y1+py);
00124 p[1] = QPoint(x2-px,y2+py);
00125 p[2] = QPoint(x2-px,y2-py);
00126 p[3] = QPoint(x1+px,y1-py);
00127 } else {
00128
00129 p[0] = QPoint(x1+px,y1+py);
00130 p[1] = QPoint(x2+px,y2-py);
00131 p[2] = QPoint(x2-px,y2-py);
00132 p[3] = QPoint(x1-px,y1+py);
00133 }
00134 setItemPoints( p, false );
00135 }
00136
00137
00138 void DPLine::drawShape( QPainter & p )
00139 {
00140 int x1 = int(x()+offsetX());
00141 int y1 = int(y()+offsetY());
00142 int x2 = x1+width();
00143 int y2 = y1+height();
00144
00145 p.drawLine( x1, y1, x2, y2 );
00146 }
00147
00148
00149
00150
00151 Item* DPArrow::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00152 {
00153 return new DPArrow( itemDocument, newItem, id );
00154 }
00155
00156 LibraryItem* DPArrow::libraryItem()
00157 {
00158 return new LibraryItem(
00159 QString("dp/arrow"),
00160 i18n("Arrow"),
00161 i18n("Other"),
00162 KGlobal::iconLoader()->loadIcon( "text", KIcon::Small ),
00163 LibraryItem::lit_drawpart,
00164 DPArrow::construct );
00165 }
00166
00167 DPArrow::DPArrow( ItemDocument *itemDocument, bool newItem, const char *id )
00168 : DPLine( itemDocument, newItem, id ? id : "arrow" )
00169 {
00170 m_name = i18n("Arrow");
00171
00172
00173 QStringList allowed = property("cap-style")->allowed();
00174 allowed.remove( DrawPart::penCapStyleToName( Qt::SquareCap ) );
00175 property("cap-style")->setAllowed(allowed);
00176 }
00177
00178 DPArrow::~DPArrow()
00179 {
00180 }
00181
00182
00183 void DPArrow::drawShape( QPainter & p )
00184 {
00185 int x1 = int(x()+offsetX());
00186 int y1 = int(y()+offsetY());
00187 int x2 = x1+width();
00188 int y2 = y1+height();
00189
00190 p.drawLine( x1, y1, x2, y2 );
00191
00192 double dx = x2-x1;
00193 double dy = y2-y1;
00194
00195 if ( dx == 0. && dy == 0. ) return;
00196
00197 double arrow_angle = ( dx == 0 ? (dy>0?(M_PI/2.):(-M_PI/2.)) : std::atan(dy/dx) );
00198 if ( dx < 0 ) arrow_angle += M_PI;
00199
00200 double head_angle = 0.6;
00201 double head_length = 10.;
00202
00203
00204 int x3 = int( x2 + head_length*std::cos( M_PI + arrow_angle - head_angle ) );
00205 int y3 = int( y2 + head_length*std::sin( M_PI + arrow_angle - head_angle ) );
00206 int x4 = int( x2 + head_length*std::cos( M_PI + arrow_angle + head_angle ) );
00207 int y4 = int( y2 + head_length*std::sin( M_PI + arrow_angle + head_angle ) );
00208
00209
00210 QPen pen = p.pen();
00211 pen.setCapStyle( Qt::RoundCap );
00212 p.setPen(pen);
00213 p.setBrush(pen.color());
00214 QPointArray pa(3);
00215 pa[0] = QPoint( x2, y2 );
00216 pa[1] = QPoint( x3, y3 );
00217 pa[2] = QPoint( x4, y4 );
00218 p.drawPolygon(pa);
00219 p.drawPolyline(pa);
00220
00221
00222 }
00223
00224