]> git.sven.stormbind.net Git - sven/vym.git/blob - src/frameobj.cpp
Replace Pierre as the maintainer
[sven/vym.git] / src / frameobj.cpp
1 #include "frameobj.h"
2
3 #include <QColor>
4 #include <QDebug>
5 #include <QGraphicsScene>
6
7 #include "misc.h" //for roof function
8
9 /////////////////////////////////////////////////////////////////
10 // FrameObj
11 /////////////////////////////////////////////////////////////////
12 FrameObj::FrameObj(QGraphicsItem *parent) : MapObj(parent) { init(); }
13
14 FrameObj::~FrameObj() { clear(); }
15
16 void FrameObj::init()
17 {
18     type = NoFrame;
19     clear();
20     borderWidth = 1;
21     penColor = QColor(Qt::black);
22     brushColor = QColor(Qt::white);
23     includeChildren = false;
24 }
25
26 void FrameObj::clear()
27 {
28     switch (type) {
29     case NoFrame:
30         break;
31     case Rectangle:
32         delete rectFrame;
33         break;
34     case RoundedRectangle:
35         delete pathFrame;
36         break;
37     case Ellipse:
38         delete ellipseFrame;
39         break;
40     case Cloud:
41         delete pathFrame;
42         break;
43     }
44     type = NoFrame;
45     padding = 0; // No frame requires also no padding
46     xsize = 0;
47 }
48
49 void FrameObj::move(double x, double y)
50 {
51     switch (type) {
52     case NoFrame:
53         break;
54     case Rectangle:
55         rectFrame->setPos(x, y);
56         break;
57     case RoundedRectangle:
58         pathFrame->setPos(x, y);
59         break;
60     case Ellipse:
61         ellipseFrame->setPos(x, y);
62         break;
63     case Cloud:
64         pathFrame->setPos(x, y);
65         break;
66     }
67 }
68
69 void FrameObj::moveBy(double x, double y) { MapObj::moveBy(x, y); }
70
71 void FrameObj::positionBBox() {}
72
73 void FrameObj::calcBBoxSize() {}
74
75 void FrameObj::setRect(const QRectF &r)
76 {
77     bbox = r;
78     switch (type) {
79     case NoFrame:
80         break;
81
82     case Rectangle:
83         rectFrame->setRect(
84             QRectF(bbox.x(), bbox.y(), bbox.width(), bbox.height()));
85         break;
86
87     case RoundedRectangle: {
88         QPointF tl = bbox.topLeft();
89         QPointF tr = bbox.topRight();
90         QPointF bl = bbox.bottomLeft();
91         QPointF br = bbox.bottomRight();
92         QPainterPath path;
93
94         qreal n = 10;
95         path.moveTo(tl.x() + n / 2, tl.y());
96
97         // Top path
98         path.lineTo(tr.x() - n, tr.y());
99         path.arcTo(tr.x() - n, tr.y(), n, n, 90, -90);
100         path.lineTo(br.x(), br.y() - n);
101         path.arcTo(br.x() - n, br.y() - n, n, n, 0, -90);
102         path.lineTo(bl.x() + n, br.y());
103         path.arcTo(bl.x(), bl.y() - n, n, n, -90, -90);
104         path.lineTo(tl.x(), tl.y() + n);
105         path.arcTo(tl.x(), tl.y(), n, n, 180, -90);
106         pathFrame->setPath(path);
107     } break;
108     case Ellipse:
109         ellipseFrame->setRect(
110             QRectF(bbox.x(), bbox.y(), bbox.width(), bbox.height()));
111         xsize = 20; // max(bbox.width(), bbox.height()) / 4;
112         break;
113
114     case Cloud:
115         QPointF tl = bbox.topLeft();
116         QPointF tr = bbox.topRight();
117         QPointF bl = bbox.bottomLeft();
118         QPainterPath path;
119         path.moveTo(tl);
120
121         float w = bbox.width();  // width
122         float h = bbox.height(); // height
123         int n = w / 40;          // number of intervalls
124         float d = w / n;         // width of interwall
125
126         // Top path
127         for (float i = 0; i < n; i++) {
128             path.cubicTo(tl.x() + i * d, tl.y() - 100 * roof((i + 0.5) / n),
129                          tl.x() + (i + 1) * d,
130                          tl.y() - 100 * roof((i + 0.5) / n),
131                          tl.x() + (i + 1) * d + 20 * roof((i + 1) / n),
132                          tl.y() - 50 * roof((i + 1) / n));
133         }
134         // Right path
135         n = h / 20;
136         d = h / n;
137         for (float i = 0; i < n; i++) {
138             path.cubicTo(tr.x() + 100 * roof((i + 0.5) / n), tr.y() + i * d,
139                          tr.x() + 100 * roof((i + 0.5) / n),
140                          tr.y() + (i + 1) * d, tr.x() + 60 * roof((i + 1) / n),
141                          tr.y() + (i + 1) * d);
142         }
143         n = w / 60;
144         d = w / n;
145         // Bottom path
146         for (float i = n; i > 0; i--) {
147             path.cubicTo(bl.x() + i * d, bl.y() + 100 * roof((i - 0.5) / n),
148                          bl.x() + (i - 1) * d,
149                          bl.y() + 100 * roof((i - 0.5) / n),
150                          bl.x() + (i - 1) * d + 20 * roof((i - 1) / n),
151                          bl.y() + 50 * roof((i - 1) / n));
152         }
153         // Left path
154         n = h / 20;
155         d = h / n;
156         for (float i = n; i > 0; i--) {
157             path.cubicTo(tl.x() - 100 * roof((i - 0.5) / n), tr.y() + i * d,
158                          tl.x() - 100 * roof((i - 0.5) / n),
159                          tr.y() + (i - 1) * d, tl.x() - 60 * roof((i - 1) / n),
160                          tr.y() + (i - 1) * d);
161         }
162         pathFrame->setPath(path);
163         xsize = 50;
164         break;
165     }
166 }
167
168 void FrameObj::setPadding(const int &i) { padding = i; }
169
170 int FrameObj::getPadding()
171 {
172     if (type == NoFrame)
173         return 0;
174     else
175         return padding;
176 }
177
178 qreal FrameObj::getTotalPadding() { return xsize + padding + borderWidth; }
179
180 qreal FrameObj::getXPadding() { return xsize; }
181
182 void FrameObj::setBorderWidth(const int &i)
183 {
184     borderWidth = i;
185     repaint();
186 }
187
188 int FrameObj::getBorderWidth() { return borderWidth; }
189
190 FrameObj::FrameType FrameObj::getFrameType() { return type; }
191
192 FrameObj::FrameType FrameObj::getFrameType(const QString &s)
193 {
194     if (s == "Rectangle")
195         return Rectangle;
196     else if (s == "RoundedRectangle")
197         return RoundedRectangle;
198     else if (s == "Ellipse")
199         return Ellipse;
200     else if (s == "Cloud")
201         return Cloud;
202     return NoFrame;
203 }
204
205 QString FrameObj::getFrameTypeName()
206 {
207     switch (type) {
208     case Rectangle:
209         return "Rectangle";
210         break;
211     case RoundedRectangle:
212         return "RoundedRectangle";
213         break;
214     case Ellipse:
215         return "Ellipse";
216         break;
217     case Cloud:
218         return "Cloud";
219         break;
220     default:
221         return "NoFrame";
222     }
223 }
224
225 void FrameObj::setFrameType(const FrameType &t)
226 {
227     if (t != type) {
228         clear();
229         type = t;
230         switch (type) {
231         case NoFrame:
232             break;
233         case Rectangle:
234             rectFrame = scene()->addRect(QRectF(0, 0, 0, 0), QPen(penColor),
235                                          brushColor);
236             rectFrame->setZValue(dZ_FRAME_LOW);
237             rectFrame->setParentItem(this);
238             rectFrame->show();
239             break;
240         case RoundedRectangle: {
241             QPainterPath path;
242             pathFrame = scene()->addPath(path, QPen(penColor), brushColor);
243             pathFrame->setZValue(dZ_FRAME_LOW);
244             pathFrame->setParentItem(this);
245             pathFrame->show();
246         } break;
247         case Ellipse:
248             ellipseFrame = scene()->addEllipse(QRectF(0, 0, 0, 0),
249                                                QPen(penColor), brushColor);
250             ellipseFrame->setZValue(dZ_FRAME_LOW);
251             ellipseFrame->setParentItem(this);
252             ellipseFrame->show();
253             break;
254         case Cloud: {
255             QPainterPath path;
256             pathFrame = scene()->addPath(path, QPen(penColor), brushColor);
257             pathFrame->setZValue(dZ_FRAME_LOW);
258             pathFrame->setParentItem(this);
259             pathFrame->show();
260             break;
261         }
262         }
263     }
264     setVisibility(visible);
265 }
266
267 void FrameObj::setFrameType(const QString &t)
268 {
269     if (t == "Rectangle")
270         FrameObj::setFrameType(Rectangle);
271     else if (t == "RoundedRectangle")
272         FrameObj::setFrameType(RoundedRectangle);
273     else if (t == "Ellipse")
274         FrameObj::setFrameType(Ellipse);
275     else if (t == "Cloud")
276         FrameObj::setFrameType(Cloud);
277     else
278         FrameObj::setFrameType(NoFrame);
279 }
280
281 void FrameObj::setPenColor(QColor col)
282 {
283     penColor = col;
284     repaint();
285 }
286
287 QColor FrameObj::getPenColor() { return penColor; }
288
289 void FrameObj::setBrushColor(QColor col)
290 {
291     brushColor = col;
292     repaint();
293 }
294
295 QColor FrameObj::getBrushColor() { return brushColor; }
296
297 void FrameObj::setFrameIncludeChildren(bool b) { includeChildren = b; }
298
299 bool FrameObj::getFrameIncludeChildren() { return includeChildren; }
300
301 void FrameObj::repaint()
302 {
303     QPen pen;
304     pen.setColor(penColor);
305     pen.setWidth(borderWidth);
306     QBrush brush(brushColor);
307     switch (type) {
308     case Rectangle:
309         rectFrame->setPen(pen);
310         rectFrame->setBrush(brush);
311         break;
312     case RoundedRectangle:
313         pathFrame->setPen(pen);
314         pathFrame->setBrush(brush);
315         break;
316     case Ellipse:
317         ellipseFrame->setPen(pen);
318         ellipseFrame->setBrush(brush);
319         break;
320     case Cloud:
321         pathFrame->setPen(pen);
322         pathFrame->setBrush(brush);
323         break;
324     default:
325         break;
326     }
327 }
328
329 void FrameObj::setZValue(double z)
330 {
331     switch (type) {
332     case NoFrame:
333         break;
334     case Rectangle:
335         rectFrame->setZValue(z);
336         break;
337     case RoundedRectangle:
338         pathFrame->setZValue(z);
339         break;
340     case Ellipse:
341         ellipseFrame->setZValue(z);
342         break;
343     case Cloud:
344         pathFrame->setZValue(z);
345         break;
346     }
347 }
348
349 void FrameObj::setVisibility(bool v)
350 {
351     MapObj::setVisibility(v);
352     switch (type) {
353     case NoFrame:
354         break;
355     case Rectangle:
356         if (visible)
357             rectFrame->show();
358         else
359             rectFrame->hide();
360         break;
361     case RoundedRectangle:
362         if (visible)
363             pathFrame->show();
364         else
365             pathFrame->hide();
366         break;
367     case Ellipse:
368         if (visible)
369             ellipseFrame->show();
370         else
371             ellipseFrame->hide();
372         break;
373     case Cloud:
374         if (visible)
375             pathFrame->show();
376         else
377             pathFrame->hide();
378         break;
379     }
380 }
381
382 QString FrameObj::saveToDir()
383 {
384     QString frameTypeAttr = attribut("frameType", getFrameTypeName());
385     if (type == NoFrame)
386         return singleElement("frame", frameTypeAttr);
387
388     QString penColAttr = attribut("penColor", penColor.name());
389     QString brushColAttr = attribut("brushColor", brushColor.name());
390     QString paddingAttr = attribut("padding", QString::number(padding));
391     QString borderWidthAttr =
392         attribut("borderWidth", QString::number(borderWidth));
393     QString incChildren;
394     if (includeChildren)
395         incChildren = attribut("includeChildren", "true");
396     return singleElement("frame", frameTypeAttr + penColAttr + brushColAttr +
397                                       paddingAttr + borderWidthAttr +
398                                       incChildren);
399 }