My Project  0.0.16
QUCS Mapping
 All Classes Namespaces 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 
18 #include "graphicline.h"
19 #include "filldialog.h"
20 
21 #include <qpushbutton.h>
22 #include <qlineedit.h>
23 #include <qcombobox.h>
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(QPen::darkGray,Pen.width()+5));
49  p->drawLine(cx, cy, cx+x2, cy+y2);
50  p->Painter->setPen(QPen(QPen::white, Pen.width(), Pen.style()));
51  p->drawLine(cx, cy, cx+x2, cy+y2);
52 
53  p->Painter->setPen(QPen(QPen::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 // --------------------------------------------------------------------------
63 void GraphicLine::paintScheme(QPainter *p)
64 {
65  p->drawLine(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 
159 // --------------------------------------------------------------------------
160 // Checks if the resize area was clicked.
161 bool GraphicLine::resizeTouched(float fX, float fY, float len)
162 {
163  float fCX = float(cx), fCY = float(cy);
164 
165  if(fX <= fCX+len) if(fX >= fCX-len) if(fY <= fCY+len) if(fY >= fCY-len) {
166  State = 1;
167  return true;
168  }
169 
170  fCX += float(x2);
171  fCY += float(y2);
172  if(fX <= fCX+len) if(fX >= fCX-len) if(fY <= fCY+len) if(fY >= fCY-len) {
173  State = 2;
174  return true;
175  }
176 
177  State = 0;
178  return false;
179 }
180 
181 // --------------------------------------------------------------------------
182 // Mouse move action during resize.
183 void GraphicLine::MouseResizeMoving(int x, int y, QPainter *p)
184 {
185  paintScheme(p); // erase old painting
186  if(State == 1) { x2 += cx-x; y2 += cy-y; cx = x; cy = y; } // move beginning
187  else { x2 = x-cx; y2 = y-cy; } // move ending
188 
189  paintScheme(p); // paint new painting
190 }
191 
192 // --------------------------------------------------------------------------
193 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
194 // x/y are coordinates without scaling.
196  QPainter *paintScale, int, int, int gx, int gy,
197  QPainter *p, int x, int y, bool drawn)
198 {
199  if(State > 0) {
200  if(State > 1)
201  paintScale->drawLine(cx, cy, cx+x2, cy+y2); // erase old painting
202  State++;
203  x2 = gx-cx;
204  y2 = gy-cy;
205  paintScale->drawLine(cx, cy, cx+x2, cy+y2); // paint new painting
206  }
207  else { cx = gx; cy = gy; }
208 
209 
210  p->setPen(Qt::SolidLine);
211  if(drawn) {
212  p->drawLine(x1+27, y1, x1+15, y1+12); // erase old cursor symbol
213  p->drawLine(x1+25, y1-2, x1+29, y1+2);
214  p->drawLine(x1+13, y1+10, x1+17, y1+14);
215  }
216  x1 = x;
217  y1 = y;
218  p->drawLine(x1+27, y1, x1+15, y1+12); // paint new cursor symbol
219  p->drawLine(x1+25, y1-2, x1+29, y1+2);
220  p->drawLine(x1+13, y1+10, x1+17, y1+14);
221 }
222 
223 // --------------------------------------------------------------------------
225 {
226  State++;
227  if(State > 2) {
228  x1 = y1 = 0;
229  State = 0;
230  return true; // painting is ready
231  }
232  return false;
233 }
234 
235 // --------------------------------------------------------------------------
236 // Checks if the coordinates x/y point to the painting.
237 // 5 is the precision the user must point onto the painting.
238 bool GraphicLine::getSelected(float fX, float fY, float w)
239 {
240  fX -= float(cx);
241  fY -= float(cy);
242 
243  if(fX < -w) {
244  if(fX < float(x2)-w) // is point between x coordinates ?
245  return false;
246  }
247  else {
248  if(fX > w)
249  if(fX > float(x2)+w)
250  return false;
251  }
252 
253  if(fY < -w) {
254  if(fY < float(y2)-w) // is point between y coordinates ?
255  return false;
256  }
257  else {
258  if(fY > w)
259  if(fY > float(y2)+w)
260  return false;
261  }
262 
263  float A = float(x2)*fY - fX*float(y2); // calculate the rectangle area spanned
264  A *= A; // avoid the need for square root
265 
266  if(A <= w*w*float(x2*x2 + y2*y2))
267  return true; // x/y lies on the graph line
268 
269  return false;
270 }
271 
272 // --------------------------------------------------------------------------
273 void GraphicLine::Bounding(int& _x1, int& _y1, int& _x2, int& _y2)
274 {
275  if(x2 < 0) { _x1 = cx+x2; _x2 = cx; }
276  else { _x1 = cx; _x2 = cx+x2; }
277 
278  if(y2 < 0) { _y1 = cy+y2; _y2 = cy; }
279  else { _y1 = cy; _y2 = cy+y2; }
280 }
281 
282 // --------------------------------------------------------------------------
283 // Rotates around the center.
285 {
286  cx += (x2>>1) - (y2>>1);
287  cy += (x2>>1) + (y2>>1);
288 
289  int tmp = x2;
290  x2 = y2;
291  y2 = -tmp;
292 }
293 
294 // --------------------------------------------------------------------------
295 // Mirrors about center line.
297 {
298  cy += y2;
299  y2 = -y2;
300 }
301 
302 // --------------------------------------------------------------------------
303 // Mirrors about center line.
305 {
306  cx += x2;
307  x2 = -x2;
308 }
309 
310 // --------------------------------------------------------------------------
311 // Calls the property dialog for the painting and changes them accordingly.
312 // If there were changes, it returns 'true'.
314 {
315  bool changed = false;
316 
317  FillDialog *d = new FillDialog(QObject::tr("Edit Line Properties"), false);
318  d->ColorButt->setPaletteBackgroundColor(Pen.color());
319  d->LineWidth->setText(QString::number(Pen.width()));
320  d->StyleBox->setCurrentItem(Pen.style()-1);
321 
322  if(d->exec() == QDialog::Rejected) {
323  delete d;
324  return false;
325  }
326 
327  if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
328  Pen.setColor(d->ColorButt->paletteBackgroundColor());
329  changed = true;
330  }
331  if(Pen.width() != d->LineWidth->text().toUInt()) {
332  Pen.setWidth(d->LineWidth->text().toUInt());
333  changed = true;
334  }
335  if(Pen.style() != (d->StyleBox->currentItem()+1)) {
336  Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
337  changed = true;
338  }
339 
340  delete d;
341  return changed;
342 }