Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ellipsearc.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ellipsearc.cpp
3  ----------------
4  begin : Thu Sep 9 2004
5  copyright : (C) 2004 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <QtGui>
18 #include "ellipsearc.h"
19 #include "filldialog.h"
20 #include "main.h"
21 #include "schematic.h"
22 #include <QPushButton>
23 #include <QLineEdit>
24 #include <QComboBox>
25 
26 #include <math.h>
27 
28 
30 {
31  Name = "EArc ";
32  isSelected = false;
33  Pen = QPen(QColor());
34  cx = cy = x1 = x2 = y1 = y2 = Angle = ArcLen = 0;
35 }
36 
38 {
39 }
40 
41 // --------------------------------------------------------------------------
43 {
44  if(isSelected) {
45  p->Painter->setPen(QPen(Qt::darkGray,Pen.width()+5));
46  p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
47  p->Painter->setPen(QPen(Qt::white, Pen.width(), Pen.style()));
48  p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
49 
50  p->Painter->setPen(QPen(Qt::darkRed,2));
51  p->drawResizeRect(cx, cy+y2); // markers for changing the size
52  p->drawResizeRect(cx, cy);
53  p->drawResizeRect(cx+x2, cy+y2);
54  p->drawResizeRect(cx+x2, cy);
55  return;
56  }
57  p->Painter->setPen(Pen);
58  p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
59 }
60 
61 // --------------------------------------------------------------------------
63 {
65 }
66 
67 // --------------------------------------------------------------------------
68 void EllipseArc::getCenter(int& x, int &y)
69 {
70  x = cx+(x2>>1);
71  y = cy+(y2>>1);
72 }
73 
74 // --------------------------------------------------------------------------
75 // Sets the center of the painting to x/y.
76 void EllipseArc::setCenter(int x, int y, bool relative)
77 {
78  if(relative) { cx += x; cy += y; }
79  else { cx = x-(x2>>1); cy = y-(y2>>1); }
80 }
81 
82 // --------------------------------------------------------------------------
84 {
85  return new EllipseArc();
86 }
87 
88 // --------------------------------------------------------------------------
89 Element* EllipseArc::info(QString& Name, char* &BitmapFile, bool getNewOne)
90 {
91  Name = QObject::tr("Elliptic Arc");
92  BitmapFile = (char *) "ellipsearc";
93 
94  if(getNewOne) return new EllipseArc();
95  return 0;
96 }
97 
98 // --------------------------------------------------------------------------
99 bool EllipseArc::load(const QString& s)
100 {
101  bool ok;
102  QString n;
103 
104  n = s.section(' ',1,1); // cx
105  cx = n.toInt(&ok);
106  if(!ok) return false;
107 
108  n = s.section(' ',2,2); // cy
109  cy = n.toInt(&ok);
110  if(!ok) return false;
111 
112  n = s.section(' ',3,3); // x2
113  x2 = n.toInt(&ok);
114  if(!ok) return false;
115 
116  n = s.section(' ',4,4); // y2
117  y2 = n.toInt(&ok);
118  if(!ok) return false;
119 
120  n = s.section(' ',5,5); // start angle
121  Angle = n.toInt(&ok);
122  if(!ok) return false;
123 
124  n = s.section(' ',6,6); // arc length
125  ArcLen = n.toInt(&ok);
126  if(!ok) return false;
127 
128  n = s.section(' ',7,7); // color
129  QColor co;
130  co.setNamedColor(n);
131  Pen.setColor(co);
132  if(!Pen.color().isValid()) return false;
133 
134  n = s.section(' ',8,8); // thickness
135  Pen.setWidth(n.toInt(&ok));
136  if(!ok) return false;
137 
138  n = s.section(' ',9,9); // line style
139  Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
140  if(!ok) return false;
141 
142  return true;
143 }
144 
145 // --------------------------------------------------------------------------
147 {
148  QString s = Name +
149  QString::number(cx) + " " + QString::number(cy) + " " +
150  QString::number(x2) + " " + QString::number(y2) + " " +
151  QString::number(Angle) + " " + QString::number(ArcLen) + " " +
152  Pen.color().name() + " " + QString::number(Pen.width()) + " " +
153  QString::number(Pen.style());
154  return s;
155 }
156 
157 // --------------------------------------------------------------------------
159 {
160  QString s =
161  QString ("new Arc (%1, %2, %3, %4, %5, %6, "
162  "QPen (QColor (\"%7\"), %8, %9))").
163  arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
164  arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
165  s = "Arcs.append (" + s + ");";
166  return s;
167 }
168 
170 {
171  QString s =
172  QString ("{\"type\" : \"ellipsearc\", "
173  "\"x\" : %1, \"y\" : %2, \"w\" : %3, \"h\" : %4, "
174  "\"angle\" : %5, \"arclen\" : %6, "
175  "\"color\" : \"%7\", \"thick\" : %8, \"style\" : \"%9\"},").
176  arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
177  arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
178  return s;
179 }
180 
181 // --------------------------------------------------------------------------
182 // Checks if the resize area was clicked.
183 bool EllipseArc::resizeTouched(float fX, float fY, float len)
184 {
185  float fCX = float(cx), fCY = float(cy);
186  float fX2 = float(cx+x2), fY2 = float(cy+y2);
187 
188  State = -1;
189  if(fX < fCX-len) return false;
190  if(fY < fCY-len) return false;
191  if(fX > fX2+len) return false;
192  if(fY > fY2+len) return false;
193 
194  State = 0;
195  if(fX < fCX+len) State = 1;
196  else if(fX <= fX2-len) { State = -1; return false; }
197  if(fY < fCY+len) State |= 2;
198  else if(fY <= fY2-len) { State = -1; return false; }
199 
200  return true;
201 }
202 
203 // --------------------------------------------------------------------------
204 // Mouse move action during resize.
206 {
207  paintScheme(p); // erase old painting
208  switch(State) {
209  case 0: x2 = x-cx; y2 = y-cy; // lower right corner
210  break;
211  case 1: x2 -= x-cx; cx = x; y2 = y-cy; // lower left corner
212  break;
213  case 2: x2 = x-cx; y2 -= y-cy; cy = y; // upper right corner
214  break;
215  case 3: x2 -= x-cx; cx = x; y2 -= y-cy; cy = y; // upper left corner
216  break;
217  }
218  if(x2 < 0) { State ^= 1; x2 *= -1; cx -= x2; }
219  if(y2 < 0) { State ^= 2; y2 *= -1; cy -= y2; }
220 
221  paintScheme(p); // paint new painting
222 }
223 
224 // --------------------------------------------------------------------------
225 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
226 // x/y are coordinates without scaling.
228  Schematic *paintScale, int fx, int fy, int gx, int gy,
229  Schematic *p, int x, int y, bool drawn)
230 {
231  switch(State) {
232  case 0 :
233  x2 = gx;
234  y2 = gy;
235  break;
236  case 1 :
237  State++;
238  x2 = gx - cx;
239  y2 = gy - cy;
240  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // paint new painting
241  break;
242  case 2 :
243  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // erase old painting
244  x2 = gx - cx;
245  y2 = gy - cy;
246  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // paint new painting
247  break;
248  case 3 :
249  State++;
250  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // erase old painting
251  if(x2 < 0) { cx += x2; x2 *= -1; }
252  if(y2 < 0) { cy += y2; y2 *= -1; }
253 
254  Angle = int(16.0*180.0/M_PI
255  * atan2(double(x2*(cy+(y2>>1) - fy)),
256  double(y2*(fx - cx-(x2>>1)))));
257  if(Angle < 0) Angle += 16*360;
258  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180); // new painting
259  break;
260  case 4 :
261  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
262  Angle = int(16.0*180.0/M_PI
263  * atan2(double(x2*(cy+(y2>>1) - fy)),
264  double(y2*(fx - cx-(x2>>1)))));
265  if(Angle < 0) Angle += 16*360;
266  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// paint new painting
267  break;
268  case 5 :
269  State++;
270  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
271  ArcLen = int(16.0*180.0/M_PI
272  * atan2(double(x2*(cy+(y2>>1) - fy)),
273  double(y2*(fx - cx-(x2>>1)))));
274  ArcLen -= Angle;
275  while(ArcLen < 0) ArcLen += 16*360;
276  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
277  break;
278  case 6 :
279  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// erase old painting
280  ArcLen = int(16.0*180.0/M_PI
281  * atan2(double(x2*(cy+(y2>>1) - fy)),
282  double(y2*(fx - cx-(x2>>1)))));
283  ArcLen -= Angle;
284  while(ArcLen <= 32) ArcLen += 16*360;
285  paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
286  break;
287  }
288 
289 
290  // FIXME #warning p->setPen(Qt::SolidLine);
291  if(drawn)
292  p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true); // erase old cursor symbol
293 
294  x1 = x;
295  y1 = y;
296  p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true); // paint new cursor symbol
297 }
298 
299 // --------------------------------------------------------------------------
301 {
302  State++;
303  switch(State) {
304  case 1 :
305  cx = x2;
306  cy = y2; // first corner is determined
307  x2 = y2 = Angle = ArcLen = 0;
308  break;
309  case 7 :
310  State = 0;
311  return true; // painting is ready
312  }
313  return false;
314 }
315 
316 // --------------------------------------------------------------------------
317 // Checks if the coordinates x/y point to the painting.
318 bool EllipseArc::getSelected(float fX, float fY, float w)
319 {
320  float fX2 = float(x2)/2.0;
321  float fY2 = float(y2)/2.0;
322  fX -= float(cx) + fX2;
323  fY -= float(cy) + fY2;
324 
325  int Phase =
326  int(16.0*180.0/M_PI *
327  atan2(-double(x2)*double(fY), double(y2)*double(fX)));
328  Phase -= Angle;
329  while(Phase < 0) Phase += 16*360;
330 
331  if(Phase > ArcLen)
332  return false;
333 
334  float a1 = fX / (fX2 - w); a1 *= a1;
335  float a2 = fX / (fX2 + w); a2 *= a2;
336  float b1 = fY / (fY2 - w); b1 *= b1;
337  float b2 = fY / (fY2 + w); b2 *= b2;
338 
339  if(a1+b1 < 1.0) return false;
340  if(a2+b2 > 1.0) return false;
341 
342  return true;
343 }
344 
345 // --------------------------------------------------------------------------
346 // Rotates around the center.
348 {
349  cy += (y2-x2) >> 1;
350  cx += (x2-y2) >> 1;
351  int tmp = x2;
352  x2 = y2;
353  y2 = tmp;
354 
355  Angle += 16*90;
356  if(Angle >= 16*360) Angle -= 16*360;
357 }
358 
359 // --------------------------------------------------------------------------
360 // Mirrors about center line.
362 {
363  Angle += ArcLen;
364  if(Angle >= 16*360) Angle -= 16*360;
365 
366  if(Angle != 0) Angle = 16*360 - Angle;
367 }
368 
369 // --------------------------------------------------------------------------
370 // Mirrors about center line.
372 {
373  Angle += ArcLen;
374  if(Angle >= 16*360) Angle -= 16*360;
375 
376  if(Angle <= 16*180) Angle = 16*180 - Angle;
377  else Angle = 16*540 - Angle;
378 }
379 
380 // --------------------------------------------------------------------------
381 // Calls the property dialog for the painting and changes them accordingly.
382 // If there were changes, it returns 'true'.
384 {
385  bool changed = false;
386 
387  FillDialog *d = new FillDialog(QObject::tr("Edit Arc Properties"), false);
388  d->ColorButt->setPaletteBackgroundColor(Pen.color());
389  d->LineWidth->setText(QString::number(Pen.width()));
390  d->StyleBox->setCurrentItem(Pen.style()-1);
391 
392  if(d->exec() == QDialog::Rejected) {
393  delete d;
394  return false;
395  }
396 
397  if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
398  Pen.setColor(d->ColorButt->paletteBackgroundColor());
399  changed = true;
400  }
401  if(Pen.width() != d->LineWidth->text().toUInt()) {
402  Pen.setWidth(d->LineWidth->text().toUInt());
403  changed = true;
404  }
405  if(Pen.style() != (Qt::PenStyle)(d->StyleBox->currentItem()+1)) {
406  Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
407  changed = true;
408  }
409 
410  delete d;
411  return changed;
412 }
void drawResizeRect(int, int)
QPainter * Painter
Definition: viewpainter.h:58
void paint(ViewPainter *)
Definition: ellipsearc.cpp:42
bool getSelected(float, float, float)
Definition: ellipsearc.cpp:318
QString toPenString(int)
Definition: painting.cpp:54
int State
Definition: painting.h:56
int y1
Definition: element.h:153
void PostPaintEvent(PE pe, int x1=0, int y1=0, int x2=0, int y2=0, int a=0, int b=0, bool PaintOnViewport=false)
Definition: schematic.cpp:533
static Element * info(QString &, char *&, bool getNewOne=false)
Definition: ellipsearc.cpp:89
void MouseMoving(Schematic *, int, int, int, int, Schematic *, int, int, bool)
Definition: ellipsearc.cpp:227
int y2
Definition: element.h:153
QLineEdit * LineWidth
Definition: filldialog.h:53
int x1
Definition: element.h:153
Definition: schematic.h:55
bool load(const QString &)
Definition: ellipsearc.cpp:99
void mirrorY()
Definition: ellipsearc.cpp:371
Definitions and declarations for the main application.
QString saveJSON()
Definition: ellipsearc.cpp:169
int cx
Definition: element.h:153
void mirrorX()
Definition: ellipsearc.cpp:361
void getCenter(int &, int &)
Definition: ellipsearc.cpp:68
bool isSelected
Definition: element.h:151
QString Name
Definition: painting.h:55
void drawArc(int, int, int, int, int, int)
void rotate()
Definition: ellipsearc.cpp:347
Superclass of all schematic drawing elements.
Definition: element.h:142
bool MousePressing()
Definition: ellipsearc.cpp:300
QPen Pen
Definition: ellipsearc.h:53
void MouseResizeMoving(int, int, Schematic *)
Definition: ellipsearc.cpp:205
int ArcLen
Definition: ellipsearc.h:54
Painting * newOne()
Definition: ellipsearc.cpp:83
int cy
Definition: element.h:153
void setCenter(int, int, bool relative=false)
Definition: ellipsearc.cpp:76
bool Dialog()
Definition: ellipsearc.cpp:383
QPushButton * ColorButt
Definition: filldialog.h:54
QComboBox * StyleBox
Definition: filldialog.h:55
bool resizeTouched(float, float, float)
Definition: ellipsearc.cpp:183
#define M_PI
Definition: diagramdialog.h:25
int x2
Definition: element.h:153
void paintScheme(Schematic *)
Definition: ellipsearc.cpp:62
QString saveCpp()
Definition: ellipsearc.cpp:158
QString save()
Definition: ellipsearc.cpp:146