#include "frameobj.h"
#include <QColor>
#include <QDebug>
#include <QGraphicsScene>
#include "misc.h" //for roof function
/////////////////////////////////////////////////////////////////
// FrameObj
/////////////////////////////////////////////////////////////////
FrameObj::FrameObj(QGraphicsItem *parent) :MapObj(parent)
{
init ();
}
FrameObj::~FrameObj()
{
clear();
}
void FrameObj::init()
{
type=NoFrame;
clear();
borderWidth=1;
penColor=QColor (Qt::black);
brushColor=QColor (Qt::white);
includeChildren=false;
}
void FrameObj::clear()
{
switch (type)
{
case NoFrame:
break;
case Rectangle:
delete rectFrame;
break;
case RoundedRectangle:
delete pathFrame;
break;
case Ellipse:
delete ellipseFrame;
break;
case Cloud:
delete pathFrame;
break;
}
type=NoFrame;
padding=0; // No frame requires also no padding
xsize=0;
}
void FrameObj::move(double x, double y)
{
switch (type)
{
case NoFrame:
break;
case Rectangle:
rectFrame->setPos (x,y);
break;
case RoundedRectangle:
pathFrame->setPos (x,y);
break;
case Ellipse:
ellipseFrame->setPos (x,y);
break;
case Cloud:
pathFrame->setPos (x,y);
break;
}
}
void FrameObj::moveBy(double x, double y)
{
MapObj::moveBy (x,y);
}
void FrameObj::positionBBox()
{
}
void FrameObj::calcBBoxSize()
{
}
void FrameObj::setRect(const QRectF &r)
{
bbox=r;
switch (type)
{
case NoFrame:
break;
case Rectangle:
rectFrame->setRect (QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ));
break;
case RoundedRectangle:
{
QPointF tl = bbox.topLeft();
QPointF tr = bbox.topRight();
QPointF bl = bbox.bottomLeft();
QPointF br = bbox.bottomRight();
QPainterPath path;
qreal n = 10;
path.moveTo (tl.x() +n/2, tl.y());
// Top path
path.lineTo (tr.x()-n, tr.y());
path.arcTo (tr.x()-n, tr.y(), n, n,90,-90);
path.lineTo (br.x() , br.y()-n);
path.arcTo (br.x()-n, br.y()-n, n, n,0,-90);
path.lineTo (bl.x()+n, br.y());
path.arcTo (bl.x() , bl.y()-n, n, n,-90,-90);
path.lineTo (tl.x() , tl.y()+n);
path.arcTo (tl.x() , tl.y(), n, n,180,-90);
pathFrame->setPath(path);
}
break;
case Ellipse:
ellipseFrame->setRect (QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ));
xsize = 20;//max(bbox.width(), bbox.height()) / 4;
break;
case Cloud:
QPointF tl = bbox.topLeft();
QPointF tr = bbox.topRight();
QPointF bl = bbox.bottomLeft();
QPainterPath path;
path.moveTo (tl);
float w = bbox.width(); // width
float h = bbox.height();// height
int n = w / 40; // number of intervalls
float d = w / n; // width of interwall
// Top path
for (float i = 0; i < n; i++)
{
path.cubicTo (
tl.x() + i*d, tl.y()- 100*roof ((i+0.5)/n) ,
tl.x() + (i+1)*d, tl.y()- 100*roof ((i+0.5)/n) ,
tl.x() + (i+1)*d + 20*roof ((i+1)/n), tl.y()- 50*roof((i+1)/n) );
}
// Right path
n = h/20;
d = h/n;
for (float i = 0; i < n; i++)
{
path.cubicTo (
tr.x()+ 100*roof ((i+0.5)/n) , tr.y() + i*d,
tr.x()+ 100*roof ((i+0.5)/n) , tr.y() + (i+1)*d,
tr.x() + 60*roof ((i+1)/n) , tr.y() + (i+1)*d );
}
n = w / 60;
d = w / n;
// Bottom path
for (float i = n; i > 0; i--)
{
path.cubicTo (
bl.x() + i*d, bl.y()+ 100*roof ((i-0.5)/n) ,
bl.x() + (i-1)*d, bl.y()+ 100*roof ((i-0.5)/n) ,
bl.x() + (i-1)*d + 20*roof ((i-1)/n), bl.y()+ 50*roof((i-1)/n) );
}
// Left path
n = h / 20;
d = h / n;
for (float i = n; i > 0; i--)
{
path.cubicTo (
tl.x()- 100*roof ((i-0.5)/n) , tr.y() + i*d,
tl.x()- 100*roof ((i-0.5)/n) , tr.y() + (i-1)*d,
tl.x()- 60*roof ((i-1)/n) , tr.y() + (i-1)*d );
}
pathFrame->setPath(path);
xsize = 50;
break;
}
}
void FrameObj::setPadding (const int &i)
{
padding = i;
}
int FrameObj::getPadding()
{
if (type==NoFrame)
return 0;
else
return padding;
}
qreal FrameObj::getTotalPadding()
{
return xsize + padding + borderWidth;
}
qreal FrameObj::getXPadding()
{
return xsize;
}
void FrameObj::setBorderWidth (const int &i)
{
borderWidth=i;
repaint();
}
int FrameObj::getBorderWidth()
{
return borderWidth;
}
FrameObj::FrameType FrameObj::getFrameType()
{
return type;
}
FrameObj::FrameType FrameObj::getFrameType(const QString &s)
{
if (s=="Rectangle")
return Rectangle;
else if (s=="RoundedRectangle")
return RoundedRectangle;
else if (s=="Ellipse")
return Ellipse;
else if (s=="Cloud")
return Cloud;
return NoFrame;
}
QString FrameObj::getFrameTypeName()
{
switch (type)
{
case Rectangle:
return "Rectangle";
break;
case RoundedRectangle:
return "RoundedRectangle";
break;
case Ellipse:
return "Ellipse";
break;
case Cloud:
return "Cloud";
break;
default:
return "NoFrame";
}
}
void FrameObj::setFrameType(const FrameType &t)
{
if (t!=type)
{
clear();
type=t;
switch (type)
{
case NoFrame:
break;
case Rectangle:
rectFrame = scene()->addRect(QRectF(0,0,0,0), QPen(penColor), brushColor);
rectFrame->setZValue(dZ_FRAME_LOW);
rectFrame->setParentItem (this);
rectFrame->show();
break;
case RoundedRectangle:
{
QPainterPath path;
pathFrame = scene()->addPath(path, QPen(penColor), brushColor);
pathFrame->setZValue(dZ_FRAME_LOW);
pathFrame->setParentItem (this);
pathFrame->show();
}
break;
case Ellipse:
ellipseFrame = scene()->addEllipse(QRectF(0,0,0,0), QPen(penColor), brushColor);
ellipseFrame->setZValue(dZ_FRAME_LOW);
ellipseFrame->setParentItem (this);
ellipseFrame->show();
break;
case Cloud:
{
QPainterPath path;
pathFrame = scene()->addPath(path, QPen(penColor), brushColor);
pathFrame->setZValue(dZ_FRAME_LOW);
pathFrame->setParentItem (this);
pathFrame->show();
break;
}
}
}
setVisibility (visible);
}
void FrameObj::setFrameType(const QString &t)
{
if (t=="Rectangle")
FrameObj::setFrameType (Rectangle);
else if (t=="RoundedRectangle")
FrameObj::setFrameType (RoundedRectangle);
else if (t=="Ellipse")
FrameObj::setFrameType (Ellipse);
else if (t=="Cloud")
FrameObj::setFrameType (Cloud);
else
FrameObj::setFrameType (NoFrame);
}
void FrameObj::setPenColor (QColor col)
{
penColor=col;
repaint();
}
QColor FrameObj::getPenColor ()
{
return penColor;
}
void FrameObj::setBrushColor (QColor col)
{
brushColor=col;
repaint();
}
QColor FrameObj::getBrushColor ()
{
return brushColor;
}
void FrameObj::setFrameIncludeChildren(bool b)
{
includeChildren=b;
}
bool FrameObj::getFrameIncludeChildren()
{
return includeChildren;
}
void FrameObj::repaint()
{
QPen pen;
pen.setColor (penColor);
pen.setWidth (borderWidth);
QBrush brush (brushColor);
switch (type)
{
case Rectangle:
rectFrame->setPen (pen);
rectFrame->setBrush (brush);
break;
case RoundedRectangle:
pathFrame->setPen (pen);
pathFrame->setBrush (brush);
break;
case Ellipse:
ellipseFrame->setPen (pen);
ellipseFrame->setBrush (brush);
break;
case Cloud:
pathFrame->setPen (pen);
pathFrame->setBrush (brush);
break;
default:
break;
}
}
void FrameObj::setZValue (double z)
{
switch (type)
{
case NoFrame:
break;
case Rectangle:
rectFrame->setZValue (z);
break;
case RoundedRectangle:
pathFrame->setZValue (z);
break;
case Ellipse:
ellipseFrame->setZValue (z);
break;
case Cloud:
pathFrame->setZValue (z);
break;
}
}
void FrameObj::setVisibility (bool v)
{
MapObj::setVisibility(v);
switch (type)
{
case NoFrame:
break;
case Rectangle:
if (visible)
rectFrame->show();
else
rectFrame->hide();
break;
case RoundedRectangle:
if (visible)
pathFrame->show();
else
pathFrame->hide();
break;
case Ellipse:
if (visible)
ellipseFrame->show();
else
ellipseFrame->hide();
break;
case Cloud:
if (visible)
pathFrame->show();
else
pathFrame->hide();
break;
}
}
QString FrameObj::saveToDir ()
{
QString frameTypeAttr=attribut ("frameType",getFrameTypeName());
if (type==NoFrame)
return singleElement ("frame", frameTypeAttr);
QString penColAttr=attribut ("penColor",penColor.name() );
QString brushColAttr=attribut ("brushColor",brushColor.name() );
QString paddingAttr=attribut ("padding",QString::number (padding) );
QString borderWidthAttr=attribut ("borderWidth",QString::number (borderWidth) );
QString incChildren;
if (includeChildren)
incChildren=attribut ("includeChildren","true");
return singleElement (
"frame",frameTypeAttr +
penColAttr +
brushColAttr +
paddingAttr +
borderWidthAttr +
incChildren);
}