Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
graphicline.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  graphicline.cpp
3  -----------------
4  begin : Mon Nov 24 2003
5  copyright : (C) 2003 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 "graphicline.h"
19 #include "filldialog.h"
20 #include "schematic.h"
21 #include <QPushButton>
22 #include <QLineEdit>
23 #include <QComboBox>
24 
25 #include <math.h>
26 
27 
28 GraphicLine::GraphicLine(int cx_, int cy_, int x2_, int y2_, QPen Pen_)
29 {
30  Name = "Line ";
31  isSelected = false;
32  Pen = Pen_;
33  cx = cx_;
34  cy = cy_;
35  x1 = y1 = 0;
36  x2 = x2_;
37  y2 = y2_;
38 }
39 
41 {
42 }
43 
44 // --------------------------------------------------------------------------
46 {
47  if(isSelected) {
48  p->Painter->setPen(QPen(Qt::darkGray,Pen.width()+5));
49  p->drawLine(cx, cy, cx+x2, cy+y2);
50  p->Painter->setPen(QPen(Qt::white, Pen.width(), Pen.style()));
51  p->drawLine(cx, cy, cx+x2, cy+y2);
52 
53  p->Painter->setPen(QPen(Qt::darkRed,2));
54  p->drawResizeRect(cx, cy); // markers for changing the size
55  p->drawResizeRect(cx+x2, cy+y2);
56  return;
57  }
58  p->Painter->setPen(Pen);
59  p->drawLine(cx, cy, cx+x2, cy+y2);
60 }
61 
62 // --------------------------------------------------------------------------
64 {
65  p->PostPaintEvent(_Line, cx, cy, cx+x2, cy+y2);
66 }
67 
68 // --------------------------------------------------------------------------
69 void GraphicLine::getCenter(int& x, int &y)
70 {
71  x = cx+(x2>>1);
72  y = cy+(y2>>1);
73 }
74 
75 // --------------------------------------------------------------------------
76 // Sets the center of the painting to x/y.
77 void GraphicLine::setCenter(int x, int y, bool relative)
78 {
79  if(relative) { cx += x; cy += y; }
80  else { cx = x-(x2>>1); cy = y-(y2>>1); }
81 }
82 
83 // --------------------------------------------------------------------------
85 {
86  return new GraphicLine();
87 }
88 
89 // --------------------------------------------------------------------------
90 Element* GraphicLine::info(QString& Name, char* &BitmapFile, bool getNewOne)
91 {
92  Name = QObject::tr("Line");
93  BitmapFile = (char *) "line";
94 
95  if(getNewOne) return new GraphicLine();
96  return 0;
97 }
98 
99 // --------------------------------------------------------------------------
100 bool GraphicLine::load(const QString& s)
101 {
102  bool ok;
103 
104  QString n;
105  n = s.section(' ',1,1); // cx
106  cx = n.toInt(&ok);
107  if(!ok) return false;
108 
109  n = s.section(' ',2,2); // cy
110  cy = n.toInt(&ok);
111  if(!ok) return false;
112 
113  n = s.section(' ',3,3); // x2
114  x2 = n.toInt(&ok);
115  if(!ok) return false;
116 
117  n = s.section(' ',4,4); // y2
118  y2 = n.toInt(&ok);
119  if(!ok) return false;
120 
121  n = s.section(' ',5,5); // color
122  QColor co;
123  co.setNamedColor(n);
124  Pen.setColor(co);
125  if(!Pen.color().isValid()) return false;
126 
127  n = s.section(' ',6,6); // thickness
128  Pen.setWidth(n.toInt(&ok));
129  if(!ok) return false;
130 
131  n = s.section(' ',7,7); // line style
132  Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
133  if(!ok) return false;
134 
135  return true;
136 }
137 
138 // --------------------------------------------------------------------------
140 {
141  QString s = Name+QString::number(cx)+" "+QString::number(cy)+" ";
142  s += QString::number(x2)+" "+QString::number(y2)+" ";
143  s += Pen.color().name()+" "+QString::number(Pen.width())+" ";
144  s += QString::number(Pen.style());
145  return s;
146 }
147 
148 // --------------------------------------------------------------------------
150 {
151  QString s =
152  QString ("new Line (%1, %2, %3, %4, QPen (QColor (\"%5\"), %6, %7))").
153  arg(cx+x1).arg(cy+y1).arg(cx+x2).arg(cy+y2).
154  arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
155  s = "Lines.append (" + s + ");";
156  return s;
157 }
158 
160 {
161  QString s =
162  QString ("{\"type\" : \"line\", "
163  "\"x1\" : %1, \"y1\" : %2, \"x2\" : %3, \"y2\" : %4, "
164  "\"color\" : \"%5\", \"thick\" : %6, \"style\" : \"%7\"},").
165  arg(cx+x1).arg(cy+y1).arg(cx+x2).arg(cy+y2).
166  arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
167  return s;
168 }
169 
170 // --------------------------------------------------------------------------
171 // Checks if the resize area was clicked.
172 bool GraphicLine::resizeTouched(float fX, float fY, float len)
173 {
174  float fCX = float(cx), fCY = float(cy);
175 
176  if(fX <= fCX+len) if(fX >= fCX-len) if(fY <= fCY+len) if(fY >= fCY-len) {
177  State = 1;
178  return true;
179  }
180 
181  fCX += float(x2);
182  fCY += float(y2);
183  if(fX <= fCX+len) if(fX >= fCX-len) if(fY <= fCY+len) if(fY >= fCY-len) {
184  State = 2;
185  return true;
186  }
187 
188  State = 0;
189  return false;
190 }
191 
192 // --------------------------------------------------------------------------
193 // Mouse move action during resize.
195 {
196  paintScheme(p); // erase old painting
197  if(State == 1) { x2 += cx-x; y2 += cy-y; cx = x; cy = y; } // move beginning
198  else { x2 = x-cx; y2 = y-cy; } // move ending
199 
200  paintScheme(p); // paint new painting
201 }
202 
203 // --------------------------------------------------------------------------
204 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
205 // x/y are coordinates without scaling.
207  Schematic *paintScale, int, int, int gx, int gy,
208  Schematic *p, int x, int y, bool drawn)
209 {
210  if(State > 0) {
211  if(State > 1)
212  paintScale->PostPaintEvent(_Line, cx, cy, cx+x2, cy+y2); // erase old painting
213  State++;
214  x2 = gx-cx;
215  y2 = gy-cy;
216  paintScale->PostPaintEvent(_Line, cx, cy, cx+x2, cy+y2); // paint new painting
217  }
218  else { cx = gx; cy = gy; }
219 
220 
221  // FIXME #warning p->setPen(Qt::SolidLine);
222  if(drawn) {
223  p->PostPaintEvent(_Line, x1+27, y1, x1+15, y1+12,0,0,true); // erase old cursor symbol
224  p->PostPaintEvent(_Line, x1+25, y1-2, x1+29, y1+2,0,0,true);
225  p->PostPaintEvent(_Line, x1+13, y1+10, x1+17, y1+14,0,0,true);
226  }
227  x1 = x;
228  y1 = y;
229  p->PostPaintEvent(_Line, x1+27, y1, x1+15, y1+12,0,0,true); // paint new cursor symbol
230  p->PostPaintEvent(_Line, x1+25, y1-2, x1+29, y1+2,0,0,true);
231  p->PostPaintEvent(_Line, x1+13, y1+10, x1+17, y1+14,0,0,true);
232 }
233 
234 // --------------------------------------------------------------------------
236 {
237  State++;
238  if(State > 2) {
239  x1 = y1 = 0;
240  State = 0;
241  return true; // painting is ready
242  }
243  return false;
244 }
245 
246 // --------------------------------------------------------------------------
247 // Checks if the coordinates x/y point to the painting.
248 // 5 is the precision the user must point onto the painting.
249 bool GraphicLine::getSelected(float fX, float fY, float w)
250 {
251  fX -= float(cx);
252  fY -= float(cy);
253 
254  if(fX < -w) {
255  if(fX < float(x2)-w) // is point between x coordinates ?
256  return false;
257  }
258  else {
259  if(fX > w)
260  if(fX > float(x2)+w)
261  return false;
262  }
263 
264  if(fY < -w) {
265  if(fY < float(y2)-w) // is point between y coordinates ?
266  return false;
267  }
268  else {
269  if(fY > w)
270  if(fY > float(y2)+w)
271  return false;
272  }
273 
274  float A = float(x2)*fY - fX*float(y2); // calculate the rectangle area spanned
275  A *= A; // avoid the need for square root
276 
277  if(A <= w*w*float(x2*x2 + y2*y2))
278  return true; // x/y lies on the graph line
279 
280  return false;
281 }
282 
283 // --------------------------------------------------------------------------
284 void GraphicLine::Bounding(int& _x1, int& _y1, int& _x2, int& _y2)
285 {
286  if(x2 < 0) { _x1 = cx+x2; _x2 = cx; }
287  else { _x1 = cx; _x2 = cx+x2; }
288 
289  if(y2 < 0) { _y1 = cy+y2; _y2 = cy; }
290  else { _y1 = cy; _y2 = cy+y2; }
291 }
292 
293 // --------------------------------------------------------------------------
294 // Rotates around the center.
296 {
297  cx += (x2>>1) - (y2>>1);
298  cy += (x2>>1) + (y2>>1);
299 
300  int tmp = x2;
301  x2 = y2;
302  y2 = -tmp;
303 }
304 
305 // --------------------------------------------------------------------------
306 // Mirrors about center line.
308 {
309  cy += y2;
310  y2 = -y2;
311 }
312 
313 // --------------------------------------------------------------------------
314 // Mirrors about center line.
316 {
317  cx += x2;
318  x2 = -x2;
319 }
320 
321 // --------------------------------------------------------------------------
322 // Calls the property dialog for the painting and changes them accordingly.
323 // If there were changes, it returns 'true'.
325 {
326  bool changed = false;
327 
328  FillDialog *d = new FillDialog(QObject::tr("Edit Line Properties"), false);
329  d->ColorButt->setPaletteBackgroundColor(Pen.color());
330  d->LineWidth->setText(QString::number(Pen.width()));
331  d->StyleBox->setCurrentItem(Pen.style()-1);
332 
333  if(d->exec() == QDialog::Rejected) {
334  delete d;
335  return false;
336  }
337 
338  if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
339  Pen.setColor(d->ColorButt->paletteBackgroundColor());
340  changed = true;
341  }
342  if(Pen.width() != d->LineWidth->text().toUInt()) {
343  Pen.setWidth(d->LineWidth->text().toUInt());
344  changed = true;
345  }
346  if(Pen.style() != (d->StyleBox->currentItem()+1)) {
347  Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
348  changed = true;
349  }
350 
351  delete d;
352  return changed;
353 }
void setCenter(int, int, bool relative=false)
Definition: graphicline.cpp:77
void drawResizeRect(int, int)
QPainter * Painter
Definition: viewpainter.h:58
void MouseMoving(Schematic *, int, int, int, int, Schematic *, int, int, bool)
QString saveCpp()
QString toPenString(int)
Definition: painting.cpp:54
int State
Definition: painting.h:56
bool getSelected(float, float, float)
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
void paintScheme(Schematic *)
Definition: graphicline.cpp:63
void paint(ViewPainter *)
Definition: graphicline.cpp:45
int y2
Definition: element.h:153
QLineEdit * LineWidth
Definition: filldialog.h:53
int x1
Definition: element.h:153
void drawLine(int, int, int, int)
Definition: viewpainter.cpp:85
void Bounding(int &, int &, int &, int &)
QString saveJSON()
GraphicLine(int cx_=0, int cy_=0, int x2_=0, int y2_=0, QPen Pen_=QPen(QColor()))
Definition: graphicline.cpp:28
QString save()
Painting * newOne()
Definition: graphicline.cpp:84
int cx
Definition: element.h:153
void mirrorX()
void getCenter(int &, int &)
Definition: graphicline.cpp:69
static Element * info(QString &, char *&, bool getNewOne=false)
Definition: graphicline.cpp:90
bool load(const QString &)
bool isSelected
Definition: element.h:151
void mirrorY()
void MouseResizeMoving(int, int, Schematic *)
QString Name
Definition: painting.h:55
bool MousePressing()
Superclass of all schematic drawing elements.
Definition: element.h:142
bool resizeTouched(float, float, float)
int cy
Definition: element.h:153
QPushButton * ColorButt
Definition: filldialog.h:54
QComboBox * StyleBox
Definition: filldialog.h:55
int x2
Definition: element.h:153