A CircleViewer is a layer to plot colored ellipses. More...
#include <CircleViewer.h>
Classes | |
| class | Item |
| class | Limits |
Public Slots | |
| void | add (double x, double y, double a, double b, double phi, QColor col) |
| bool | add (const QString &line) |
| void | insert (int index, double x, double y, double a, double b, double phi, QColor col) |
| void | remove (int index) |
| void | set (int index, double x, double y, double a, double b, double phi, QColor col) |
Public Member Functions | |
| virtual Rect | boundingRect () const |
| CircleViewer (AxisWindow *parent=0) | |
| void | clear () |
| int | count () const |
| double | lineWeight () const |
| virtual void | paintData (const LayerPainterRequest &lp, QPainter &p, double dotpercm) const |
| void | resize (int n) |
| void | setLineWeight (double lw) |
| virtual const QString & | xml_tagName () const |
Static Public Attributes | |
| static const QString | xmlCircleViewerTag = "CircleViewer" |
Protected Member Functions | |
| XMLMember | xml_member (XML_MEMBER_ARGS) |
| bool | xml_setProperty (XML_SETPROPERTY_ARGS) |
| void | xml_writeProperties (XML_WRITEPROPERTIES_ARGS) const |
Protected Attributes | |
| QVector< Item > | _items |
| double | _lineWeight |
Properties | |
| double | lineWeight |
A CircleViewer is a layer to plot colored ellipses.
| SciFigs::CircleViewer::CircleViewer | ( | AxisWindow * | parent = 0 | ) |
References _lineWeight, and TRACE.
:
GraphContentLayer(parent)
{
TRACE;
_lineWeight=0.05;
}
| void SciFigs::CircleViewer::add | ( | double | x, |
| double | y, | ||
| double | a, | ||
| double | b, | ||
| double | phi, | ||
| QColor | col | ||
| ) | [slot] |
References SciFigs::CircleViewer::Item::_color, SciFigs::CircleViewer::Item::_ellipse, _items, QGpCoreTools::Ellipse::setCenter(), QGpCoreTools::Ellipse::setMajorRadius(), QGpCoreTools::Ellipse::setMinorRadius(), QGpCoreTools::Ellipse::setOrientation(), and TRACE.
Referenced by add(), SciFigs::CircleMask::CircleMask(), createCircles(), Simulator::on_addSource_clicked(), and xml_setProperty().
{
TRACE;
Item item;
Ellipse& ell=item._ellipse;
ell.setCenter(Point2D(x, y));
ell.setMajorRadius(a);
ell.setMinorRadius(b);
ell.setOrientation(phi);
item._color=col;
LayerLocker ll(this);
_items.push_back(item);
}
| bool SciFigs::CircleViewer::add | ( | const QString & | line | ) | [slot] |
Add a circle from the text contained in Line
3 x y rx black circle 4 x y rx ry black ellipse 5 x y rx ry rot black rotated ellipse 6 x y rx r g b colored circle 7 x y rx ry r g b colored ellipse 8 x y rx ry rot r g b colored rotated ellipse
References add(), count(), QGpCoreTools::LineParser::count(), QGpCoreTools::endl(), QGpCoreTools::LineParser::toDouble(), QGpCoreTools::LineParser::toInt(), QGpCoreTools::tr(), and TRACE.
{
TRACE;
LineParser parser(line);
bool ok=true;
switch(parser.count()) {
case 0: // Ignore blank lines positively
return true;
case 3: {
double r=parser.toDouble(2, ok);
add(parser.toDouble(0, ok), parser.toDouble(1, ok), r, r, 0.0, Qt::black);
}
return ok;
case 4:
add(parser.toDouble(0, ok), parser.toDouble(1, ok),
parser.toDouble(2, ok), parser.toDouble(3, ok), 0.0, Qt::black);
return ok;
case 5:
add(parser.toDouble(0, ok), parser.toDouble(1, ok),
parser.toDouble(2, ok), parser.toDouble(3, ok), parser.toDouble(4, ok)/180.0*M_PI,Qt::black);
return ok;
case 6: {
double r=parser.toDouble(2, ok);
QColor c;
c.setRgb(parser.toInt(3, ok),
parser.toInt(4, ok),
parser.toInt(5, ok));
add(parser.toDouble(0, ok), parser.toDouble(1, ok), r, r, 0.0, c);
}
return ok;
case 7: {
QColor c;
c.setRgb(parser.toInt(4, ok),
parser.toInt(5, ok),
parser.toInt(6, ok));
add(parser.toDouble(0, ok), parser.toDouble(1, ok),
parser.toDouble(2, ok), parser.toDouble(3, ok), 0.0, c);
}
return ok;
case 8: {
QColor c;
c.setRgb(parser.toInt(5, ok),
parser.toInt(6, ok),
parser.toInt(7, ok));
add(parser.toDouble(0, ok), parser.toDouble(1, ok),
parser.toDouble(2, ok), parser.toDouble(3, ok), parser.toDouble(4, ok)/180.0*M_PI, c);
}
return ok;
default:
App::stream() << tr("Error parsing circle (%1 already added): %2 columns encountered instead of 3, 4, 6 or 7.\n"
"\"%3\"").arg(count()).arg(parser.count()).arg(line) << endl;
return false;
}
}
| Rect SciFigs::CircleViewer::boundingRect | ( | ) | const [virtual] |
Implements SciFigs::GraphContentLayer.
Reimplemented in SciFigs::CircleMask.
References _items, QGpCoreTools::Rect::add(), QGpCoreTools::Ellipse::center(), QGpCoreTools::Rect::setLimits(), TRACE, QGpCoreTools::Point2D::x(), QGpCoreTools::Ellipse::xRadius(), QGpCoreTools::Point2D::y(), and QGpCoreTools::Ellipse::yRadius().
{
TRACE;
Rect r;
if(_items.count()>0) {
const Ellipse& ell=_items[0]._ellipse;
const Point2D& c=ell.center();
double xRadius=ell.xRadius();
double yRadius=ell.yRadius();
r.setLimits(c.x()-xRadius, c.y()-yRadius, c.x()+xRadius, c.y()+yRadius);
for(int i=1; i<_items.count(); i++) {
const Ellipse& ell=_items[i]._ellipse;
const Point2D& c=ell.center();
r.add(c.x()-xRadius, c.y()-yRadius);
r.add(c.x()+xRadius, c.y()+yRadius);
}
}
return r;
}
| void SciFigs::CircleViewer::clear | ( | ) |
| int SciFigs::CircleViewer::count | ( | ) | const [inline] |
Referenced by add(), createCircles(), and xml_setProperty().
{return _items.count();}
| void SciFigs::CircleViewer::insert | ( | int | index, |
| double | x, | ||
| double | y, | ||
| double | a, | ||
| double | b, | ||
| double | phi, | ||
| QColor | col | ||
| ) | [slot] |
References SciFigs::CircleViewer::Item::_color, SciFigs::CircleViewer::Item::_ellipse, _items, QGpCoreTools::Ellipse::setCenter(), QGpCoreTools::Ellipse::setMajorRadius(), QGpCoreTools::Ellipse::setMinorRadius(), QGpCoreTools::Ellipse::setOrientation(), and TRACE.
{
TRACE;
Item item;
Ellipse& ell=item._ellipse;
ell.setCenter(Point2D(x, y));
ell.setMajorRadius(a);
ell.setMinorRadius(b);
ell.setOrientation(phi);
item._color=col;
LayerLocker ll(this);
_items.insert(index, item);
}
| double SciFigs::CircleViewer::lineWeight | ( | ) | const [inline] |
Referenced by paintData().
{return _lineWeight;}
| void SciFigs::CircleViewer::paintData | ( | const LayerPainterRequest & | lp, |
| QPainter & | p, | ||
| double | dotpercm | ||
| ) | const [virtual] |
Implements SciFigs::GraphContentLayer.
Reimplemented in SciFigs::CircleMask.
References SciFigs::CircleViewer::Item::_color, SciFigs::CircleViewer::Item::_ellipse, _items, _lineWeight, QGpCoreTools::abs(), SciFigs::GraphContentOptions::ax(), SciFigs::GraphContentOptions::ay(), QGpCoreTools::Ellipse::center(), QGpCoreTools::Angle::degrees(), QGpCoreTools::Angle::isNull(), lineWeight(), QGpCoreTools::Ellipse::majorRadius(), QGpCoreTools::Ellipse::minorRadius(), SciFigs::LayerPainterRequest::options(), QGpCoreTools::Ellipse::orientation(), SciFigs::CircleViewer::Limits::polarLimits(), SciFigs::LayerPainterRequest::terminated(), TRACE, QGpCoreTools::Point2D::x(), SciFigs::GraphContentOptions::xr2s(), QGpCoreTools::Point2D::y(), and SciFigs::GraphContentOptions::yr2s().
{
TRACE;
const GraphContentOptions& gc=lp.options();
Limits limits(gc);
double startPhi, stopPhi;
int lineWeight=(int)floor(_lineWeight*dotpercm+0.5);
if(lineWeight<1) {
lineWeight=1;
}
for(int i=0; i<_items.count(); i++) {
if(lp.terminated()) return;
const Item& item=_items[i];
const Ellipse& ell=item._ellipse;
if(limits.polarLimits(ell, startPhi, stopPhi)) {
p.setPen(QPen(item._color, lineWeight));
int rx=abs((int)(ell.majorRadius()* gc.ax()));
int ry=abs((int)(ell.minorRadius()*gc.ay()));
int orx=gc.xr2s(ell.center().x())-rx;
int ory=gc.yr2s(ell.center().y())-ry;
int minphi=(int)floor(Angle::radiansToDegrees(startPhi)*16.0);
int dphi=(int)ceil(Angle::radiansToDegrees(stopPhi)*16.0)-minphi;
//printf("Circle %i is plotted phi %lg %lg\n",i,startPhi,stopPhi);
if(ell.orientation().isNull()) {
p.drawArc(orx, ory, rx + rx, ry + ry, minphi, dphi);
} else {
p.save();
p.translate(orx+rx, ory+ry);
p.rotate(-ell.orientation().degrees());
p.drawArc(-rx, -ry, rx + rx, ry + ry, minphi, dphi);
p.restore();
}
}
//else printf("Circle %i is not plotted\n",i);
}
}
| void SciFigs::CircleViewer::remove | ( | int | index | ) | [slot] |
Referenced by Simulator::on_removeSource_clicked().
| void SciFigs::CircleViewer::resize | ( | int | n | ) |
| void SciFigs::CircleViewer::set | ( | int | index, |
| double | x, | ||
| double | y, | ||
| double | a, | ||
| double | b, | ||
| double | phi, | ||
| QColor | col | ||
| ) | [slot] |
References SciFigs::CircleViewer::Item::_color, SciFigs::CircleViewer::Item::_ellipse, _items, QGpCoreTools::Ellipse::setCenter(), QGpCoreTools::Ellipse::setMajorRadius(), QGpCoreTools::Ellipse::setMinorRadius(), QGpCoreTools::Ellipse::setOrientation(), and TRACE.
Referenced by Simulator::displaySource(), FKTimeWindows::on_kEdit_valueChanged(), FKTimeWindows::on_vEdit_valueChanged(), ArrayGui::ArrayResponse::setKmax(), ArrayGui::ArrayResponse::setKmin(), and GeopsyGui::RingEditor::updateGraph().
{
TRACE;
Item& item=_items[index];
Ellipse& ell=item._ellipse;
LayerLocker ll(this);
ell.setCenter(Point2D(x, y));
ell.setMajorRadius(a);
ell.setMinorRadius(b);
ell.setOrientation(phi);
item._color=col;
}
| void SciFigs::CircleViewer::setLineWeight | ( | double | lw | ) |
References _lineWeight.
{
LayerLocker ll(this);
_lineWeight=lw;
}
| XMLMember SciFigs::CircleViewer::xml_member | ( | XML_MEMBER_ARGS | ) | [protected, virtual] |
Re-implement this function to offer XML restore (children and properties) support to your class.
From tag and map (with contains the attibute value) return a unique identifier under the format of a XMLMember. XMLMember is initialized with 3 types of contructors:
Map of attributes can be inspected in this way (can be achived also in xml_setProperty()):
static const QString tmp("childrenName"); XMLRestoreAttributeIterator it=map.find(tmp); if(it!=map.end()) { // found attribute "childrenName" }
If the map of attributes is not used:
Q_UNUSED(attributes);
if(tag=="x1") return XMLMember(0);
else if(tag=="y1") return XMLMember(1);
else if(tag=="x2") return XMLMember(2);
else if(tag=="y2") return XMLMember(3);
else return XMLMember(XMLMember::Unknown);
Arithmetic operations + and - apply to XMLMember to avoid confusion of property id numbers between inherited objects. Offset 3 corresponds to the number of properties defined in this object.
if(tag=="anInteger") return XMLMember(0); else if(tag=="aString") return XMLMember(1); else if(tag=="aDouble") return XMLMember(2); return AbstractLine::xml_member(tag, attributes, context)+3;
For the arguments of this function use Macro XML_MEMBER_ARGS.
Reimplemented from SciFigs::GraphContentLayer.
References SciFigs::XMLSciFigs::data(), and TRACE.
{
TRACE;
XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
if(scifigsContext->data()) {
if(tag=="data") return XMLMember(0);
else if(tag=="nCircles") return XMLMember(1); // For compatibility
}
return GraphContentLayer::xml_member(tag, attributes, context)+2;
}
| bool SciFigs::CircleViewer::xml_setProperty | ( | XML_SETPROPERTY_ARGS | ) | [protected, virtual] |
Re-implement this function to offer XML restore properties support to your class.
From memberID set the corresponding property with value content. The map of attributes is given as a supplementary information (not useful in all cases).
For a general case:
Q_UNUSED(attributes); double val=content.toDouble(); switch (memberID) { case 0: _x1=val; return true; case 1: _y1=val; return true; case 2: _x2=val; return true; case 3: _y2=val; return true; default: return false; }
For classes inheriting other classes (see also xml_member())
switch (memberID) { case 0: _anInteger=content.toString(); return true; case 1: _aString=content.toInt(); return true; case 2: _aDouble=content.toDouble(); return true; default: return AbstractLine::xml_setProperty(memberID-3, map, content);
For the arguments of this function use Macro XML_SETPROPERTY_ARGS.
Reimplemented from SciFigs::GraphContentLayer.
References add(), count(), QGpCoreTools::endl(), QGpCoreTools::StringSection::isValid(), QGpCoreTools::StringSection::readLine(), QGpCoreTools::StringSection::toString(), QGpCoreTools::tr(), and TRACE.
{
TRACE;
Q_UNUSED(tag);
switch (memberID) {
case 0: {
const QChar * ptr=0;
//int n=_items.count();
//if(n==0) return true;
StringSection l=content.readLine(ptr);
while(l.isValid()) {
if(!add(l.toString())) {
App::stream() << tr("Error parsing circle (%1 already added), incomplete line").arg(count()) << endl;
return false;
}
l=content.readLine(ptr);
}
}
return true;
case 1: { // For compatibility
return true;
}
default:
break;
}
return GraphContentLayer::xml_setProperty(memberID-2, tag, attributes, content, context);
}
| virtual const QString& SciFigs::CircleViewer::xml_tagName | ( | ) | const [inline, virtual] |
Reimplemented from SciFigs::GraphContentLayer.
Reimplemented in SciFigs::CircleMask.
{return xmlCircleViewerTag;}
| void SciFigs::CircleViewer::xml_writeProperties | ( | XML_WRITEPROPERTIES_ARGS | ) | const [protected, virtual] |
Reimplemented from SciFigs::GraphContentLayer.
References SciFigs::CircleViewer::Item::_color, SciFigs::CircleViewer::Item::_ellipse, _items, QGpCoreTools::Ellipse::center(), SciFigs::XMLSciFigs::data(), QGpCoreTools::Angle::degrees(), QGpCoreTools::Ellipse::majorRadius(), QGpCoreTools::Ellipse::minorRadius(), QGpCoreTools::Ellipse::orientation(), TRACE, QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().
{
// TODO: have a more xml format for recording
TRACE;
GraphContentLayer::xml_writeProperties(s, context);
XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
if(scifigsContext->data()) {
QString tmp;
tmp+=s.indent();
tmp+="<data>\n";
int n=_items.count();
for(int i=0;i<n;i++) {
const Item& item=_items[i];
const Ellipse& ell=item._ellipse;
const QColor& col=item._color;
tmp+=s.indent();
tmp+=" ";
tmp+=QString::number(ell.center().x(),'g',10);
tmp+=" ";
tmp+=QString::number(ell.center().y(),'g',10);
tmp+=" ";
tmp+=QString::number(ell.majorRadius(),'g',10);
tmp+=" ";
tmp+=QString::number(ell.minorRadius(),'g',10);
tmp+=" ";
tmp+=QString::number(ell.orientation().degrees(),'g',10);
tmp+=" ";
tmp+=QString::number(col.red());
tmp+=" ";
tmp+=QString::number(col.green());
tmp+=" ";
tmp+=QString::number(col.blue());
tmp+="\n";
}
tmp+=s.indent();
tmp+="</data>\n";
s << tmp;
}
}
QVector<Item> SciFigs::CircleViewer::_items [protected] |
Referenced by add(), SciFigs::CircleMask::boundingRect(), boundingRect(), clear(), insert(), SciFigs::CircleMask::paintData(), paintData(), remove(), resize(), set(), and xml_writeProperties().
double SciFigs::CircleViewer::_lineWeight [protected] |
Referenced by CircleViewer(), paintData(), and setLineWeight().
const QString SciFigs::CircleViewer::xmlCircleViewerTag = "CircleViewer" [static] |
double SciFigs::CircleViewer::lineWeight [read, write] |