Qucs-GUI
0.0.19
|
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 }