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] |