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.
228 lines
5.9 KiB
228 lines
5.9 KiB
/***************************************************************************
|
|
* 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 <cmath>
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
#include <tqpainter.h>
|
|
|
|
|
|
//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(
|
|
TQString("dp/line"),
|
|
i18n("Line"),
|
|
i18n("Other"),
|
|
TDEGlobal::iconLoader()->loadIcon( "text", TDEIcon::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(TQt::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", TQt::SolidLine );
|
|
|
|
createProperty( "cap-style", Variant::Type::PenCapStyle );
|
|
property("cap-style")->setCaption( i18n("Cap Style") );
|
|
property("cap-style")->setAdvanced(true);
|
|
setDataPenCapStyle( "cap-style", TQt::FlatCap );
|
|
}
|
|
|
|
DPLine::~DPLine()
|
|
{
|
|
}
|
|
|
|
void DPLine::setSelected( bool yes )
|
|
{
|
|
if ( yes == isSelected() )
|
|
return;
|
|
|
|
DrawPart::setSelected(yes);
|
|
m_pLineOverlay->showResizeHandles(yes);
|
|
}
|
|
|
|
|
|
void DPLine::dataChanged()
|
|
{
|
|
setPen( TQPen( dataColor("line-color"),
|
|
unsigned( dataInt("line-width") ),
|
|
getDataPenStyle("line-style"),
|
|
getDataPenCapStyle("cap-style"),
|
|
TQt::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();
|
|
|
|
TQPointArray p(4);
|
|
int pw = pen().width();
|
|
int dx = TQABS(x1-x2);
|
|
int dy = TQABS(y1-y2);
|
|
pw = pw*4/3+2; // approx pw*sqrt(2)
|
|
int px = x1<x2 ? -pw : pw ;
|
|
int py = y1<y2 ? -pw : pw ;
|
|
if ( dx && dy && (dx > dy ? (dx*2/dy <= 2) : (dy*2/dx <= 2)) ) {
|
|
// steep
|
|
if ( px == py ) {
|
|
p[0] = TQPoint(x1 ,y1+py);
|
|
p[1] = TQPoint(x2-px,y2 );
|
|
p[2] = TQPoint(x2 ,y2-py);
|
|
p[3] = TQPoint(x1+px,y1 );
|
|
} else {
|
|
p[0] = TQPoint(x1+px,y1 );
|
|
p[1] = TQPoint(x2 ,y2-py);
|
|
p[2] = TQPoint(x2-px,y2 );
|
|
p[3] = TQPoint(x1 ,y1+py);
|
|
}
|
|
} else if ( dx > dy ) {
|
|
// horizontal
|
|
p[0] = TQPoint(x1+px,y1+py);
|
|
p[1] = TQPoint(x2-px,y2+py);
|
|
p[2] = TQPoint(x2-px,y2-py);
|
|
p[3] = TQPoint(x1+px,y1-py);
|
|
} else {
|
|
// vertical
|
|
p[0] = TQPoint(x1+px,y1+py);
|
|
p[1] = TQPoint(x2+px,y2-py);
|
|
p[2] = TQPoint(x2-px,y2-py);
|
|
p[3] = TQPoint(x1-px,y1+py);
|
|
}
|
|
setItemPoints( p, false );
|
|
}
|
|
|
|
|
|
void DPLine::drawShape( TQPainter & 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(
|
|
TQString("dp/arrow"),
|
|
i18n("Arrow"),
|
|
i18n("Other"),
|
|
TDEGlobal::iconLoader()->loadIcon( "text", TDEIcon::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
|
|
TQStringList allowed = property("cap-style")->allowed();
|
|
allowed.remove( DrawPart::penCapStyleToName( TQt::SquareCap ) );
|
|
property("cap-style")->setAllowed(allowed);
|
|
}
|
|
|
|
DPArrow::~DPArrow()
|
|
{
|
|
}
|
|
|
|
|
|
void DPArrow::drawShape( TQPainter & 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
|
|
TQPen pen = p.pen();
|
|
pen.setCapStyle( TQt::RoundCap );
|
|
p.setPen(pen);
|
|
p.setBrush(pen.color());
|
|
TQPointArray pa(3);
|
|
pa[0] = TQPoint( x2, y2 );
|
|
pa[1] = TQPoint( x3, y3 );
|
|
pa[2] = TQPoint( x4, y4 );
|
|
p.drawPolygon(pa);
|
|
p.drawPolyline(pa);
|
|
// p.drawLine( x2, y2, x3, y3 );
|
|
// p.drawLine( x2, y2, x4, y4 );
|
|
}
|
|
//END class DPLine
|
|
|