Qucs-GUI  0.0.19
/home/travis/build/Qucs/qucs/qucs/qucs/paintings/ellipsearc.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                                ellipsearc.cpp
00003                               ----------------
00004     begin                : Thu Sep 9 2004
00005     copyright            : (C) 2004 by Michael Margraf
00006     email                : michael.margraf@alumni.tu-berlin.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 #include "ellipsearc.h"
00018 #include "filldialog.h"
00019 #include "main.h"
00020 #include "schematic.h"
00021 
00022 #include <QPainter>
00023 #include <QPushButton>
00024 #include <QLineEdit>
00025 #include <QComboBox>
00026 
00027 #include <cmath>
00028 
00029 EllipseArc::EllipseArc()
00030 {
00031   Name = "EArc ";
00032   isSelected = false;
00033   Pen = QPen(QColor());
00034   cx = cy = x1 = x2 = y1 = y2 = Angle = ArcLen = 0;
00035 }
00036 
00037 EllipseArc::~EllipseArc()
00038 {
00039 }
00040 
00041 // --------------------------------------------------------------------------
00042 void EllipseArc::paint(ViewPainter *p)
00043 {
00044   if(isSelected) {
00045     p->Painter->setPen(QPen(Qt::darkGray,Pen.width()+5));
00046     p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
00047     p->Painter->setPen(QPen(Qt::white, Pen.width(), Pen.style()));
00048     p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
00049 
00050     p->Painter->setPen(QPen(Qt::darkRed,2));
00051     p->drawResizeRect(cx, cy+y2);  // markers for changing the size
00052     p->drawResizeRect(cx, cy);
00053     p->drawResizeRect(cx+x2, cy+y2);
00054     p->drawResizeRect(cx+x2, cy);
00055     return;
00056   }
00057   p->Painter->setPen(Pen);
00058   p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
00059 }
00060 
00061 // --------------------------------------------------------------------------
00062 void EllipseArc::paintScheme(Schematic *p)
00063 {
00064   p->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);
00065 }
00066 
00067 // --------------------------------------------------------------------------
00068 void EllipseArc::getCenter(int& x, int &y)
00069 {
00070   x = cx+(x2>>1);
00071   y = cy+(y2>>1);
00072 }
00073 
00074 // --------------------------------------------------------------------------
00075 // Sets the center of the painting to x/y.
00076 void EllipseArc::setCenter(int x, int y, bool relative)
00077 {
00078   if(relative) { cx += x;  cy += y; }
00079   else { cx = x-(x2>>1);  cy = y-(y2>>1); }
00080 }
00081 
00082 // --------------------------------------------------------------------------
00083 Painting* EllipseArc::newOne()
00084 {
00085   return new EllipseArc();
00086 }
00087 
00088 // --------------------------------------------------------------------------
00089 Element* EllipseArc::info(QString& Name, char* &BitmapFile, bool getNewOne)
00090 {
00091   Name = QObject::tr("Elliptic Arc");
00092   BitmapFile = (char *) "ellipsearc";
00093 
00094   if(getNewOne)  return new EllipseArc();
00095   return 0;
00096 }
00097 
00098 // --------------------------------------------------------------------------
00099 bool EllipseArc::load(const QString& s)
00100 {
00101   bool ok;
00102   QString n;
00103 
00104   n  = s.section(' ',1,1);    // cx
00105   cx = n.toInt(&ok);
00106   if(!ok) return false;
00107 
00108   n  = s.section(' ',2,2);    // cy
00109   cy = n.toInt(&ok);
00110   if(!ok) return false;
00111 
00112   n  = s.section(' ',3,3);    // x2
00113   x2 = n.toInt(&ok);
00114   if(!ok) return false;
00115 
00116   n  = s.section(' ',4,4);    // y2
00117   y2 = n.toInt(&ok);
00118   if(!ok) return false;
00119 
00120   n  = s.section(' ',5,5);    // start angle
00121   Angle = n.toInt(&ok);
00122   if(!ok) return false;
00123 
00124   n  = s.section(' ',6,6);    // arc length
00125   ArcLen = n.toInt(&ok);
00126   if(!ok) return false;
00127 
00128   n  = s.section(' ',7,7);    // color
00129   QColor co;
00130   co.setNamedColor(n);
00131   Pen.setColor(co);
00132   if(!Pen.color().isValid()) return false;
00133 
00134   n  = s.section(' ',8,8);    // thickness
00135   Pen.setWidth(n.toInt(&ok));
00136   if(!ok) return false;
00137 
00138   n  = s.section(' ',9,9);    // line style
00139   Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
00140   if(!ok) return false;
00141 
00142   return true;
00143 }
00144 
00145 // --------------------------------------------------------------------------
00146 QString EllipseArc::save()
00147 {
00148   QString s = Name +
00149   QString::number(cx) + " " + QString::number(cy) + " " +
00150   QString::number(x2) + " " + QString::number(y2) + " " +
00151   QString::number(Angle) + " " + QString::number(ArcLen) + " " +
00152   Pen.color().name()  + " " + QString::number(Pen.width()) + " " +
00153   QString::number(Pen.style());
00154   return s;
00155 }
00156 
00157 // --------------------------------------------------------------------------
00158 QString EllipseArc::saveCpp()
00159 {
00160   QString s =
00161     QString ("new Arc (%1, %2, %3, %4, %5, %6, "
00162        "QPen (QColor (\"%7\"), %8, %9))").
00163     arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
00164     arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
00165   s = "Arcs.append (" + s + ");";
00166   return s;
00167 }
00168 
00169 QString EllipseArc::saveJSON()
00170 {
00171   QString s =
00172     QString ("{\"type\" : \"ellipsearc\", "
00173       "\"x\" : %1, \"y\" : %2, \"w\" : %3, \"h\" : %4, "
00174       "\"angle\" : %5, \"arclen\" : %6, "
00175       "\"color\" : \"%7\", \"thick\" : %8, \"style\" : \"%9\"},").
00176       arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
00177       arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
00178   return s;
00179 }
00180 
00181 // --------------------------------------------------------------------------
00182 // Checks if the resize area was clicked.
00183 bool EllipseArc::resizeTouched(float fX, float fY, float len)
00184 {
00185   float fCX = float(cx), fCY = float(cy);
00186   float fX2 = float(cx+x2), fY2 = float(cy+y2);
00187 
00188   State = -1;
00189   if(fX < fCX-len) return false;
00190   if(fY < fCY-len) return false;
00191   if(fX > fX2+len) return false;
00192   if(fY > fY2+len) return false;
00193 
00194   State = 0;
00195   if(fX < fCX+len) State = 1;
00196   else if(fX <= fX2-len) { State = -1; return false; }
00197   if(fY < fCY+len)  State |= 2;
00198   else if(fY <= fY2-len) { State = -1; return false; }
00199 
00200   return true;
00201 }
00202 
00203 // --------------------------------------------------------------------------
00204 // Mouse move action during resize.
00205 void EllipseArc::MouseResizeMoving(int x, int y, Schematic *p)
00206 {
00207   paintScheme(p);  // erase old painting
00208   switch(State) {
00209     case 0: x2 = x-cx; y2 = y-cy; // lower right corner
00210       break;
00211     case 1: x2 -= x-cx; cx = x; y2 = y-cy; // lower left corner
00212       break;
00213     case 2: x2 = x-cx; y2 -= y-cy; cy = y; // upper right corner
00214       break;
00215     case 3: x2 -= x-cx; cx = x; y2 -= y-cy; cy = y; // upper left corner
00216       break;
00217   }
00218   if(x2 < 0) { State ^= 1; x2 *= -1; cx -= x2; }
00219   if(y2 < 0) { State ^= 2; y2 *= -1; cy -= y2; }
00220 
00221   paintScheme(p);  // paint new painting
00222 }
00223 
00224 // --------------------------------------------------------------------------
00225 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
00226 // x/y are coordinates without scaling.
00227 void EllipseArc::MouseMoving(
00228   Schematic *paintScale, int fx, int fy, int gx, int gy,
00229   Schematic *p, int x, int y, bool drawn)
00230 {
00231   switch(State) {
00232     case 0 :
00233        x2 = gx;
00234        y2 = gy;
00235        break;
00236     case 1 :
00237       State++;
00238       x2 = gx - cx;
00239       y2 = gy - cy;
00240       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360);  // paint new painting
00241       break;
00242     case 2 :
00243       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360);  // erase old painting
00244       x2 = gx - cx;
00245       y2 = gy - cy;
00246       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360);  // paint new painting
00247       break;
00248     case 3 :
00249       State++;
00250       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360);  // erase old painting
00251       if(x2 < 0) { cx += x2;  x2 *= -1; }
00252       if(y2 < 0) { cy += y2;  y2 *= -1; }
00253 
00254       Angle = int(16.0*180.0/pi
00255     * atan2(double(x2*(cy+(y2>>1) - fy)),
00256       double(y2*(fx - cx-(x2>>1)))));
00257       if(Angle < 0) Angle += 16*360;
00258       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180); // new painting
00259       break;
00260     case 4 :
00261       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
00262       Angle = int(16.0*180.0/pi
00263     * atan2(double(x2*(cy+(y2>>1) - fy)),
00264       double(y2*(fx - cx-(x2>>1)))));
00265       if(Angle < 0) Angle += 16*360;
00266       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// paint new painting
00267       break;
00268     case 5 :
00269       State++;
00270       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
00271       ArcLen = int(16.0*180.0/pi
00272     * atan2(double(x2*(cy+(y2>>1) - fy)),
00273       double(y2*(fx - cx-(x2>>1)))));
00274       ArcLen -= Angle;
00275       while(ArcLen < 0) ArcLen += 16*360;
00276       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
00277       break;
00278     case 6 :
00279       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// erase old painting
00280       ArcLen = int(16.0*180.0/pi
00281     * atan2(double(x2*(cy+(y2>>1) - fy)),
00282       double(y2*(fx - cx-(x2>>1)))));
00283       ArcLen -= Angle;
00284       while(ArcLen <= 32) ArcLen += 16*360;
00285       paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
00286       break;
00287   }
00288 
00289 
00290   // FIXME #warning p->setPen(Qt::SolidLine);
00291   if(drawn)
00292     p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true); // erase old cursor symbol
00293 
00294   x1 = x;
00295   y1 = y;
00296   p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true);  // paint new cursor symbol
00297 }
00298 
00299 // --------------------------------------------------------------------------
00300 bool EllipseArc::MousePressing()
00301 {
00302   State++;
00303   switch(State) {
00304     case 1 :
00305   cx = x2;
00306   cy = y2;    // first corner is determined
00307   x2 = y2 = Angle = ArcLen = 0;
00308   break;
00309     case 7 :
00310   State = 0;
00311   return true;    // painting is ready
00312   }
00313   return false;
00314 }
00315 
00316 // --------------------------------------------------------------------------
00317 // Checks if the coordinates x/y point to the painting.
00318 bool EllipseArc::getSelected(float fX, float fY, float w)
00319 {
00320   float fX2 = float(x2)/2.0;
00321   float fY2 = float(y2)/2.0;
00322   fX -= float(cx) + fX2;
00323   fY -= float(cy) + fY2;
00324 
00325   int Phase =
00326       int(16.0*180.0/pi *
00327           atan2(-double(x2)*double(fY), double(y2)*double(fX)));
00328   Phase -= Angle;
00329   while(Phase < 0) Phase += 16*360;
00330 
00331   if(Phase > ArcLen)
00332     return false;
00333 
00334   float a1 = fX / (fX2 - w);  a1 *= a1;
00335   float a2 = fX / (fX2 + w);  a2 *= a2;
00336   float b1 = fY / (fY2 - w);  b1 *= b1;
00337   float b2 = fY / (fY2 + w);  b2 *= b2;
00338 
00339   if(a1+b1 < 1.0)  return false;
00340   if(a2+b2 > 1.0)  return false;
00341 
00342   return true;
00343 }
00344 
00345 // --------------------------------------------------------------------------
00346 // Rotates around the center.
00347 void EllipseArc::rotate()
00348 {
00349   cy += (y2-x2) >> 1;
00350   cx += (x2-y2) >> 1;
00351   int tmp = x2;
00352   x2 = y2;
00353   y2 = tmp;
00354 
00355   Angle += 16*90;
00356   if(Angle >= 16*360)  Angle -= 16*360;
00357 }
00358 
00359 // --------------------------------------------------------------------------
00360 // Mirrors about center line.
00361 void EllipseArc::mirrorX()
00362 {
00363   Angle += ArcLen;
00364   if(Angle >= 16*360) Angle -= 16*360;
00365 
00366   if(Angle != 0)  Angle = 16*360 - Angle;
00367 }
00368 
00369 // --------------------------------------------------------------------------
00370 // Mirrors about center line.
00371 void EllipseArc::mirrorY()
00372 {
00373   Angle += ArcLen;
00374   if(Angle >= 16*360) Angle -= 16*360;
00375 
00376   if(Angle <= 16*180)  Angle = 16*180 - Angle;
00377   else  Angle = 16*540 - Angle;
00378 }
00379 
00380 // --------------------------------------------------------------------------
00381 // Calls the property dialog for the painting and changes them accordingly.
00382 // If there were changes, it returns 'true'.
00383 bool EllipseArc::Dialog()
00384 {
00385   bool changed = false;
00386 
00387   FillDialog *d = new FillDialog(QObject::tr("Edit Arc Properties"), false);
00388   d->ColorButt->setPaletteBackgroundColor(Pen.color());
00389   d->LineWidth->setText(QString::number(Pen.width()));
00390   d->StyleBox->setCurrentItem(Pen.style()-1);
00391 
00392   if(d->exec() == QDialog::Rejected) {
00393     delete d;
00394     return false;
00395   }
00396 
00397   if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
00398     Pen.setColor(d->ColorButt->paletteBackgroundColor());
00399     changed = true;
00400   }
00401   if(Pen.width()  != d->LineWidth->text().toInt()) {
00402     Pen.setWidth(d->LineWidth->text().toInt());
00403     changed = true;
00404   }
00405   if(Pen.style()  != (Qt::PenStyle)(d->StyleBox->currentItem()+1)) {
00406     Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
00407     changed = true;
00408   }
00409 
00410   delete d;
00411   return changed;
00412 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines