All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Classes | Public Slots | Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Properties
SciFigs::CircleViewer Class Reference

A CircleViewer is a layer to plot colored ellipses. More...

#include <CircleViewer.h>

Inheritance diagram for SciFigs::CircleViewer:
SciFigs::GraphContentLayer QGpGuiTools::PropertyItem QGpCoreTools::XMLClass SciFigs::CircleMask

List of all members.

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

Detailed Description

A CircleViewer is a layer to plot colored ellipses.


Constructor & Destructor Documentation

References _lineWeight, and TRACE.

                                                :
      GraphContentLayer(parent)
  {
    TRACE;
    _lineWeight=0.05;
  }

Member Function Documentation

void SciFigs::CircleViewer::add ( double  x,
double  y,
double  a,
double  b,
double  phi,
QColor  col 
) [slot]
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;
    }
  }

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;
  }

References _items, and TRACE.

  {
    TRACE;
    LayerLocker ll(this);
    _items.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]
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]

References _items, and TRACE.

Referenced by Simulator::on_removeSource_clicked().

  {
    TRACE;
    LayerLocker ll(this);
    _items.remove(index);
  }
void SciFigs::CircleViewer::set ( int  index,
double  x,
double  y,
double  a,
double  b,
double  phi,
QColor  col 
) [slot]

References _lineWeight.

  {
    LayerLocker ll(this);
    _lineWeight=lw;
  }

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:

  • An integer: id number of a property
  • A XMLClass * : a child of this object identified by tag
  • Default constructor: error, unknow child or property

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;
  }

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.

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;
    }
  }

Member Data Documentation

const QString SciFigs::CircleViewer::xmlCircleViewerTag = "CircleViewer" [static]

Property Documentation

double SciFigs::CircleViewer::lineWeight [read, write]

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines