My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rectangle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rectangle.cpp
3  ---------------
4  begin : Sat Nov 22 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 "rectangle.h"
19 #include "filldialog.h"
20 
21 #include <qpushbutton.h>
22 #include <qlineedit.h>
23 #include <qcombobox.h>
24 #include <qcheckbox.h>
25 
26 Rectangle::Rectangle(bool _filled)
27 {
28  Name = "Rectangle ";
29  isSelected = false;
30  Pen = QPen(QColor());
31  Brush = QBrush(QPen::lightGray);
32  filled = _filled;
33  cx = cy = 0;
34  x1 = x2 = 0;
35  y1 = y2 = 0;
36 }
37 
39 {
40 }
41 
42 // --------------------------------------------------------------------------
44 {
45  if(isSelected) {
46  p->Painter->setPen(QPen(QPen::darkGray,Pen.width()+5));
47  if(filled) p->Painter->setBrush(Brush);
48  p->drawRect(cx, cy, x2, y2);
49  p->Painter->setPen(QPen(QPen::white, Pen.width(), Pen.style()));
50  p->Painter->setBrush(QBrush::NoBrush);
51  p->drawRect(cx, cy, x2, y2);
52 
53  p->Painter->setPen(QPen(QPen::darkRed,2));
54  p->drawResizeRect(cx, cy+y2); // markers for changing the size
55  p->drawResizeRect(cx, cy);
56  p->drawResizeRect(cx+x2, cy+y2);
57  p->drawResizeRect(cx+x2, cy);
58  return;
59  }
60  p->Painter->setPen(Pen);
61  if(filled) p->Painter->setBrush(Brush);
62  p->drawRect(cx, cy, x2, y2);
63  p->Painter->setBrush(QBrush::NoBrush); // no filling for the next paintings
64 }
65 
66 // --------------------------------------------------------------------------
67 void Rectangle::paintScheme(QPainter *p)
68 {
69  p->drawRect(cx, cy, x2, y2);
70 }
71 
72 // --------------------------------------------------------------------------
73 void Rectangle::getCenter(int& x, int &y)
74 {
75  x = cx+(x2>>1);
76  y = cy+(y2>>1);
77 }
78 
79 // --------------------------------------------------------------------------
80 // Sets the center of the painting to x/y.
81 void Rectangle::setCenter(int x, int y, bool relative)
82 {
83  if(relative) { cx += x; cy += y; }
84  else { cx = x-(x2>>1); cy = y-(y2>>1); }
85 }
86 
87 // --------------------------------------------------------------------------
89 {
90  return new Rectangle();
91 }
92 
93 // --------------------------------------------------------------------------
94 Element* Rectangle::info(QString& Name, char* &BitmapFile, bool getNewOne)
95 {
96  Name = QObject::tr("Rectangle");
97  BitmapFile = (char *) "rectangle";
98 
99  if(getNewOne) return new Rectangle();
100  return 0;
101 }
102 
103 // --------------------------------------------------------------------------
104 Element* Rectangle::info_filled(QString& Name, char* &BitmapFile, bool getNewOne)
105 {
106  Name = QObject::tr("filled Rectangle");
107  BitmapFile = (char *) "filledrect";
108 
109  if(getNewOne) return new Rectangle(true);
110  return 0;
111 }
112 
113 // --------------------------------------------------------------------------
114 bool Rectangle::load(const QString& s)
115 {
116  bool ok;
117 
118  QString n;
119  n = s.section(' ',1,1); // cx
120  cx = n.toInt(&ok);
121  if(!ok) return false;
122 
123  n = s.section(' ',2,2); // cy
124  cy = n.toInt(&ok);
125  if(!ok) return false;
126 
127  n = s.section(' ',3,3); // x2
128  x2 = n.toInt(&ok);
129  if(!ok) return false;
130 
131  n = s.section(' ',4,4); // y2
132  y2 = n.toInt(&ok);
133  if(!ok) return false;
134 
135  n = s.section(' ',5,5); // color
136  QColor co;
137  co.setNamedColor(n);
138  Pen.setColor(co);
139  if(!Pen.color().isValid()) return false;
140 
141  n = s.section(' ',6,6); // thickness
142  Pen.setWidth(n.toInt(&ok));
143  if(!ok) return false;
144 
145  n = s.section(' ',7,7); // line style
146  Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
147  if(!ok) return false;
148 
149  n = s.section(' ',8,8); // fill color
150  co.setNamedColor(n);
151  Brush.setColor(co);
152  if(!Brush.color().isValid()) return false;
153 
154  n = s.section(' ',9,9); // fill style
155  Brush.setStyle((Qt::BrushStyle)n.toInt(&ok));
156  if(!ok) return false;
157 
158  n = s.section(' ',10,10); // filled
159  if(n.toInt(&ok) == 0) filled = false;
160  else filled = true;
161  if(!ok) return false;
162 
163  return true;
164 }
165 
166 // --------------------------------------------------------------------------
168 {
169  QString s = Name +
170  QString::number(cx) + " " + QString::number(cy) + " " +
171  QString::number(x2) + " " + QString::number(y2) + " " +
172  Pen.color().name() + " " + QString::number(Pen.width()) + " " +
173  QString::number(Pen.style()) + " " +
174  Brush.color().name() + " " + QString::number(Brush.style());
175  if(filled) s += " 1";
176  else s += " 0";
177  return s;
178 }
179 
180 // --------------------------------------------------------------------------
182 {
183  QString b = filled ?
184  QString (", QBrush (QColor (\"%1\"), %2)").
185  arg(Brush.color().name()).arg(toBrushString(Brush.style())) : "";
186  QString s =
187  QString ("new Area (%1, %2, %3, %4, "
188  "QPen (QColor (\"%5\"), %6, %7)%8)").
189  arg(cx).arg(cy).arg(x2).arg(y2).
190  arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style())).
191  arg(b);
192  s = "Rects.append (" + s + ");";
193  return s;
194 }
195 
196 // --------------------------------------------------------------------------
197 // Checks if the resize area was clicked.
198 bool Rectangle::resizeTouched(float fX, float fY, float len)
199 {
200  float fCX = float(cx), fCY = float(cy);
201  float fX2 = float(cx+x2), fY2 = float(cy+y2);
202 
203  State = -1;
204  if(fX < fCX-len) return false;
205  if(fY < fCY-len) return false;
206  if(fX > fX2+len) return false;
207  if(fY > fY2+len) return false;
208 
209  State = 0;
210  if(fX < fCX+len) State = 1;
211  else if(fX < fX2-len) { State = -1; return false; }
212  if(fY < fCY+len) State |= 2;
213  else if(fY < fY2-len) { State = -1; return false; }
214 
215  return true;
216 }
217 
218 // --------------------------------------------------------------------------
219 // Mouse move action during resize.
220 void Rectangle::MouseResizeMoving(int x, int y, QPainter *p)
221 {
222  paintScheme(p); // erase old painting
223  switch(State) {
224  case 0: x2 = x-cx; y2 = y-cy; // lower right corner
225  break;
226  case 1: x2 -= x-cx; cx = x; y2 = y-cy; // lower left corner
227  break;
228  case 2: x2 = x-cx; y2 -= y-cy; cy = y; // upper right corner
229  break;
230  case 3: x2 -= x-cx; cx = x; y2 -= y-cy; cy = y; // upper left corner
231  break;
232  }
233  if(x2 < 0) { State ^= 1; x2 *= -1; cx -= x2; }
234  if(y2 < 0) { State ^= 2; y2 *= -1; cy -= y2; }
235 
236  paintScheme(p); // paint new painting
237 }
238 
239 // --------------------------------------------------------------------------
240 // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
241 // x/y are coordinates without scaling.
243  QPainter *paintScale, int, int, int gx, int gy,
244  QPainter *p, int x, int y, bool drawn)
245 {
246  if(State > 0) {
247  if(State > 1)
248  paintScale->drawRect(x1, y1, x2-x1, y2-y1); // erase old painting
249  State++;
250  x2 = gx;
251  y2 = gy;
252  paintScale->drawRect(x1, y1, x2-x1, y2-y1); // paint new rectangle
253  }
254  else { x2 = gx; y2 = gy; }
255 
256 
257  p->setPen(Qt::SolidLine);
258  if(drawn) {
259  p->drawRect(cx+13, cy, 18, 12); // erase old cursor symbol
260  if(filled) { // hatched ?
261  p->drawLine(cx+14, cy+6, cx+19, cy+1);
262  p->drawLine(cx+26, cy+1, cx+17, cy+10);
263  p->drawLine(cx+29, cy+5, cx+24, cy+10);
264  }
265  }
266  cx = x;
267  cy = y;
268  p->drawRect(cx+13, cy, 18, 12); // paint new cursor symbol
269  if(filled) { // hatched ?
270  p->drawLine(cx+14, cy+6, cx+19, cy+1);
271  p->drawLine(cx+26, cy+1, cx+17, cy+10);
272  p->drawLine(cx+29, cy+5, cx+24, cy+10);
273  }
274 }
275 
276 // --------------------------------------------------------------------------
278 {
279  State++;
280  if(State == 1) {
281  x1 = x2;
282  y1 = y2; // first corner is determined
283  }
284  else {
285  if(x1 < x2) { cx = x1; x2 = x2-x1; } // cx/cy to upper left corner
286  else { cx = x2; x2 = x1-x2; }
287  if(y1 < y2) { cy = y1; y2 = y2-y1; }
288  else { cy = y2; y2 = y1-y2; }
289  x1 = y1 = 0;
290  State = 0;
291  return true; // rectangle is ready
292  }
293  return false;
294 }
295 
296 // --------------------------------------------------------------------------
297 // Checks if the coordinates x/y point to the painting.
298 bool Rectangle::getSelected(float fX, float fY, float w)
299 {
300  if(filled) {
301  if(int(fX) > cx+x2) return false; // coordinates outside the rectangle ?
302  if(int(fY) > cy+y2) return false;
303  if(int(fX) < cx) return false;
304  if(int(fY) < cy) return false;
305  }
306  else {
307  fX -= float(cx);
308  fY -= float(cy);
309  float fX2 = float(x2);
310  float fY2 = float(y2);
311 
312  if(fX > fX2+w) return false; // coordinates outside the rectangle ?
313  if(fY > fY2+w) return false;
314  if(fX < -w) return false;
315  if(fY < -w) return false;
316 
317  // coordinates inside the rectangle ?
318  if(fX < fX2-w) if(fX > w) if(fY < fY2-w) if(fY > w)
319  return false;
320  }
321 
322  return true;
323 }
324 
325 // --------------------------------------------------------------------------
326 // Rotates around the center.
328 {
329  cy += (y2-x2) >> 1;
330  cx += (x2-y2) >> 1;
331  int tmp = x2;
332  x2 = y2;
333  y2 = tmp;
334 }
335 
336 // --------------------------------------------------------------------------
337 // Mirrors about center line.
339 {
340  // nothing to do
341 }
342 
343 // --------------------------------------------------------------------------
344 // Mirrors about center line.
346 {
347  // nothing to do
348 }
349 
350 // --------------------------------------------------------------------------
351 // Calls the property dialog for the painting and changes them accordingly.
352 // If there were changes, it returns 'true'.
354 {
355  bool changed = false;
356 
357  FillDialog *d = new FillDialog(QObject::tr("Edit Rectangle Properties"));
358  d->ColorButt->setPaletteBackgroundColor(Pen.color());
359  d->LineWidth->setText(QString::number(Pen.width()));
360  d->StyleBox->setCurrentItem(Pen.style()-1);
361  d->FillColorButt->setPaletteBackgroundColor(Brush.color());
362  d->FillStyleBox->setCurrentItem(Brush.style());
363  d->CheckFilled->setChecked(filled);
365 
366  if(d->exec() == QDialog::Rejected) {
367  delete d;
368  return false;
369  }
370 
371  if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
372  Pen.setColor(d->ColorButt->paletteBackgroundColor());
373  changed = true;
374  }
375  if(Pen.width() != d->LineWidth->text().toUInt()) {
376  Pen.setWidth(d->LineWidth->text().toUInt());
377  changed = true;
378  }
379  if(Pen.style() != (Qt::PenStyle)(d->StyleBox->currentItem()+1)) {
380  Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
381  changed = true;
382  }
383  if(filled != d->CheckFilled->isChecked()) {
384  filled = d->CheckFilled->isChecked();
385  changed = true;
386  }
387  if(Brush.color() != d->FillColorButt->paletteBackgroundColor()) {
388  Brush.setColor(d->FillColorButt->paletteBackgroundColor());
389  changed = true;
390  }
391  if(Brush.style() != d->FillStyleBox->currentItem()) {
392  Brush.setStyle((Qt::BrushStyle)d->FillStyleBox->currentItem());
393  changed = true;
394  }
395 
396  delete d;
397  return changed;
398 }