1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Designer of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "grid_p.h" |
30 | |
31 | #include <QtCore/qstring.h> |
32 | #include <QtCore/qvector.h> |
33 | #include <QtGui/qpainter.h> |
34 | #include <QtWidgets/qwidget.h> |
35 | #include <QtGui/qevent.h> |
36 | |
37 | QT_BEGIN_NAMESPACE |
38 | |
39 | static const bool defaultSnap = true; |
40 | static const bool defaultVisible = true; |
41 | static const int DEFAULT_GRID = 10; |
42 | static const char* KEY_VISIBLE = "gridVisible" ; |
43 | static const char* KEY_SNAPX = "gridSnapX" ; |
44 | static const char* KEY_SNAPY = "gridSnapY" ; |
45 | static const char* KEY_DELTAX = "gridDeltaX" ; |
46 | static const char* KEY_DELTAY = "gridDeltaY" ; |
47 | |
48 | // Insert a value into the serialization map unless default |
49 | template <class T> |
50 | static inline void valueToVariantMap(T value, T defaultValue, const QString &key, QVariantMap &v, bool forceKey) { |
51 | if (forceKey || value != defaultValue) |
52 | v.insert(akey: key, avalue: QVariant(value)); |
53 | } |
54 | |
55 | // Obtain a value form QVariantMap |
56 | template <class T> |
57 | static inline bool valueFromVariantMap(const QVariantMap &v, const QString &key, T &value) { |
58 | const QVariantMap::const_iterator it = v.constFind(akey: key); |
59 | const bool found = it != v.constEnd(); |
60 | if (found) |
61 | value = qvariant_cast<T>(it.value()); |
62 | return found; |
63 | } |
64 | |
65 | namespace qdesigner_internal |
66 | { |
67 | |
68 | Grid::Grid() : |
69 | m_visible(defaultVisible), |
70 | m_snapX(defaultSnap), |
71 | m_snapY(defaultSnap), |
72 | m_deltaX(DEFAULT_GRID), |
73 | m_deltaY(DEFAULT_GRID) |
74 | { |
75 | } |
76 | |
77 | bool Grid::fromVariantMap(const QVariantMap& vm) |
78 | { |
79 | Grid grid; |
80 | bool anyData = valueFromVariantMap(v: vm, key: QLatin1String(KEY_VISIBLE), value&: grid.m_visible); |
81 | anyData |= valueFromVariantMap(v: vm, key: QLatin1String(KEY_SNAPX), value&: grid.m_snapX); |
82 | anyData |= valueFromVariantMap(v: vm, key: QLatin1String(KEY_SNAPY), value&: grid.m_snapY); |
83 | anyData |= valueFromVariantMap(v: vm, key: QLatin1String(KEY_DELTAX), value&: grid.m_deltaX); |
84 | anyData |= valueFromVariantMap(v: vm, key: QLatin1String(KEY_DELTAY), value&: grid.m_deltaY); |
85 | if (!anyData) |
86 | return false; |
87 | if (grid.m_deltaX == 0 || grid.m_deltaY == 0) { |
88 | qWarning(msg: "Attempt to set invalid grid with a spacing of 0." ); |
89 | return false; |
90 | } |
91 | *this = grid; |
92 | return true; |
93 | } |
94 | |
95 | QVariantMap Grid::toVariantMap(bool forceKeys) const |
96 | { |
97 | QVariantMap rc; |
98 | addToVariantMap(vm&: rc, forceKeys); |
99 | return rc; |
100 | } |
101 | |
102 | void Grid::addToVariantMap(QVariantMap& vm, bool forceKeys) const |
103 | { |
104 | valueToVariantMap(value: m_visible, defaultValue: defaultVisible, key: QLatin1String(KEY_VISIBLE), v&: vm, forceKey: forceKeys); |
105 | valueToVariantMap(value: m_snapX, defaultValue: defaultSnap, key: QLatin1String(KEY_SNAPX), v&: vm, forceKey: forceKeys); |
106 | valueToVariantMap(value: m_snapY, defaultValue: defaultSnap, key: QLatin1String(KEY_SNAPY), v&: vm, forceKey: forceKeys); |
107 | valueToVariantMap(value: m_deltaX, defaultValue: DEFAULT_GRID, key: QLatin1String(KEY_DELTAX), v&: vm, forceKey: forceKeys); |
108 | valueToVariantMap(value: m_deltaY, defaultValue: DEFAULT_GRID, key: QLatin1String(KEY_DELTAY), v&: vm, forceKey: forceKeys); |
109 | } |
110 | |
111 | void Grid::paint(QWidget *widget, QPaintEvent *e) const |
112 | { |
113 | QPainter p(widget); |
114 | paint(p, widget, e); |
115 | } |
116 | |
117 | void Grid::paint(QPainter &p, const QWidget *widget, QPaintEvent *e) const |
118 | { |
119 | p.setPen(widget->palette().dark().color()); |
120 | |
121 | if (m_visible) { |
122 | const int xstart = (e->rect().x() / m_deltaX) * m_deltaX; |
123 | const int ystart = (e->rect().y() / m_deltaY) * m_deltaY; |
124 | |
125 | const int xend = e->rect().right(); |
126 | const int yend = e->rect().bottom(); |
127 | |
128 | using Points = QVector<QPointF>; |
129 | static Points points; |
130 | points.clear(); |
131 | |
132 | for (int x = xstart; x <= xend; x += m_deltaX) { |
133 | points.reserve(asize: (yend - ystart) / m_deltaY + 1); |
134 | for (int y = ystart; y <= yend; y += m_deltaY) |
135 | points.push_back(t: QPointF(x, y)); |
136 | p.drawPoints( points: &(*points.begin()), pointCount: points.count()); |
137 | points.clear(); |
138 | } |
139 | } |
140 | } |
141 | |
142 | int Grid::snapValue(int value, int grid) const |
143 | { |
144 | const int rest = value % grid; |
145 | const int absRest = (rest < 0) ? -rest : rest; |
146 | int offset = 0; |
147 | if (2 * absRest > grid) |
148 | offset = 1; |
149 | if (rest < 0) |
150 | offset *= -1; |
151 | return (value / grid + offset) * grid; |
152 | } |
153 | |
154 | QPoint Grid::snapPoint(const QPoint &p) const |
155 | { |
156 | const int sx = m_snapX ? snapValue(value: p.x(), grid: m_deltaX) : p.x(); |
157 | const int sy = m_snapY ? snapValue(value: p.y(), grid: m_deltaY) : p.y(); |
158 | return QPoint(sx, sy); |
159 | } |
160 | |
161 | int Grid::widgetHandleAdjustX(int x) const |
162 | { |
163 | return m_snapX ? (x / m_deltaX) * m_deltaX + 1 : x; |
164 | } |
165 | |
166 | int Grid::widgetHandleAdjustY(int y) const |
167 | { |
168 | return m_snapY ? (y / m_deltaY) * m_deltaY + 1 : y; |
169 | } |
170 | |
171 | bool Grid::equals(const Grid &rhs) const |
172 | { |
173 | return m_visible == rhs.m_visible && |
174 | m_snapX == rhs.m_snapX && |
175 | m_snapY == rhs.m_snapY && |
176 | m_deltaX == rhs.m_deltaX && |
177 | m_deltaY == rhs.m_deltaY; |
178 | } |
179 | } |
180 | |
181 | QT_END_NAMESPACE |
182 | |