1 /*******************************************************************
2
3 Part of the Fritzing project - http://fritzing.org
4 Copyright (c) 2007-2014 Fachhochschule Potsdam - http://fh-potsdam.de
5
6 Fritzing is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Fritzing is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Fritzing. If not, see <http://www.gnu.org/licenses/>.
18
19 ********************************************************************
20
21 $Revision: 6141 $:
22 $Author: cohen@irascible.com $:
23 $Date: 2012-07-04 21:20:05 +0200 (Mi, 04. Jul 2012) $
24
25 ********************************************************************/
26
27 #include "cursormaster.h"
28 #include "../debugdialog.h"
29
30
31 #include <QApplication>
32 #include <QBitmap>
33 #include <QString>
34 #include <QKeyEvent>
35 #include <QEvent>
36 #include <QGraphicsItem>
37 #include <QGraphicsPixmapItem>
38 #include <QGraphicsScene>
39 #include <QGraphicsView>
40 #include <QGraphicsSceneMouseEvent>
41 #include <QTimer>
42
43 QCursor * CursorMaster::BendpointCursor = NULL;
44 QCursor * CursorMaster::NewBendpointCursor = NULL;
45 QCursor * CursorMaster::MakeWireCursor = NULL;
46 QCursor * CursorMaster::MakeCurveCursor = NULL;
47 QCursor * CursorMaster::RubberbandCursor = NULL;
48 QCursor * CursorMaster::MoveCursor = NULL;
49 QCursor * CursorMaster::BendlegCursor = NULL;
50 QCursor * CursorMaster::RotateCursor = NULL;
51 QCursor * CursorMaster::ScaleCursor = NULL;
52
53 //static QTimer timer;
54
55 CursorMaster CursorMaster::TheCursorMaster;
56 static QList<QObject *> Listeners;
57
58 static QHash<QGraphicsScene *, QGraphicsPixmapItem *> CursorItems;
59 static QList<QCursor **> Cursors;
60
61
CursorMaster()62 CursorMaster::CursorMaster() : QObject()
63 {
64 m_blocked = false;
65 }
66
cleanup()67 void CursorMaster::cleanup() {
68 foreach (QCursor ** cursor, Cursors) {
69 delete *cursor;
70 }
71 Cursors.clear();
72 }
73
initCursors()74 void CursorMaster::initCursors()
75 {
76 if (BendpointCursor == NULL) {
77 //timer.setSingleShot(true);
78 //timer.setInterval(0);
79 //connect(&timer, SIGNAL(timeout()), &TheCursorMaster, SLOT(moveCursor()));
80
81 QStringList names;
82 QStringList masks;
83
84 names << ":resources/images/cursor/bendpoint.bmp"
85 << ":resources/images/cursor/new_bendpoint.bmp"
86 << ":resources/images/cursor/make_wire.bmp"
87 << ":resources/images/cursor/curve.bmp"
88 << ":resources/images/cursor/rubberband_move.bmp"
89 << ":resources/images/cursor/part_move.bmp"
90 << ":resources/images/cursor/bendleg.bmp"
91 << ":resources/images/cursor/rotate.bmp"
92 << ":resources/images/cursor/scale.bmp";
93
94 masks << ":resources/images/cursor/bendpoint_mask.bmp"
95 << ":resources/images/cursor/new_bendpoint_mask.bmp"
96 << ":resources/images/cursor/make_wire_mask.bmp"
97 << ":resources/images/cursor/curve_mask.bmp"
98 << ":resources/images/cursor/rubberband_move_mask.bmp"
99 << ":resources/images/cursor/part_move_mask.bmp"
100 << ":resources/images/cursor/bendleg_mask.bmp"
101 << ":resources/images/cursor/rotate_mask.bmp"
102 << ":resources/images/cursor/scale_mask.bmp";
103
104 Cursors << &BendpointCursor
105 << &NewBendpointCursor
106 << &MakeWireCursor
107 << &MakeCurveCursor
108 << &RubberbandCursor
109 << &MoveCursor
110 << &BendlegCursor
111 << &RotateCursor
112 << &ScaleCursor;
113
114 for (int i = 0; i < Cursors.count(); i++) {
115 QBitmap bitmap1(names.at(i));
116 QBitmap bitmap1m(masks.at(i));
117 *Cursors.at(i) = new QCursor(bitmap1, bitmap1m, 0, 0);
118 }
119
120 QApplication::instance()->installEventFilter(instance());
121 }
122 }
123
instance()124 CursorMaster * CursorMaster::instance()
125 {
126 return &TheCursorMaster;
127 }
128
addCursor(QObject * object,const QCursor & cursor)129 void CursorMaster::addCursor(QObject * object, const QCursor & cursor)
130 {
131 if (m_blocked) return;
132
133 if (object == NULL) return;
134
135
136 /*
137 QGraphicsItem * item = dynamic_cast<QGraphicsItem *>(object);
138 if (item == NULL) return;
139
140 QGraphicsScene * scene = item->scene();
141 if (scene == NULL) return;
142
143 QGraphicsView * view = dynamic_cast<QGraphicsView *>(scene->parent());
144 if (view == NULL) return;
145
146 QGraphicsPixmapItem * pixmapItem = CursorItems.value(scene, NULL);
147 if (pixmapItem == NULL) {
148 pixmapItem = new QGraphicsPixmapItem();
149 pixmapItem->setZValue(10000); // always on top
150 pixmapItem->setVisible(true);
151 pixmapItem->setAcceptedMouseButtons(0);
152 pixmapItem->setAcceptDrops(false);
153 pixmapItem->setAcceptTouchEvents(false);
154 pixmapItem->setAcceptHoverEvents(false);
155 pixmapItem->setEnabled(false);
156 pixmapItem->setFlags(QGraphicsItem::ItemIgnoresTransformations);
157 CursorItems.insert(scene, pixmapItem);
158 scene->addItem(pixmapItem);
159 scene->installEventFilter(this);
160 }
161
162 pixmapItem->setPixmap(*cursor.mask());
163 pixmapItem->setPos(view->mapToScene(view->mapFromGlobal(QCursor::pos())) + cursor.hotSpot());
164 */
165
166 if (Listeners.contains(object)) {
167 if (Listeners.first() != object) {
168 Listeners.removeOne(object);
169 Listeners.push_front(object);
170 }
171 //DebugDialog::debug(QString("changing cursor %1").arg((long) object));
172 QApplication::changeOverrideCursor(cursor);
173 return;
174 }
175
176 Listeners.push_front(object);
177 connect(object, SIGNAL(destroyed(QObject *)), this, SLOT(deleteCursor(QObject *)));
178 QApplication::setOverrideCursor(cursor);
179 //DebugDialog::debug(QString("addding cursor %1").arg((long) object));
180 }
181
removeCursor(QObject * object)182 void CursorMaster::removeCursor(QObject * object)
183 {
184 if (object == NULL) return;
185
186 if (Listeners.contains(object)) {
187 disconnect(object, SIGNAL(destroyed(QObject *)), this, SLOT(deleteCursor(QObject *)));
188 Listeners.removeOne(object);
189 QApplication::restoreOverrideCursor();
190 //DebugDialog::debug(QString("removing cursor %1").arg((long) object));
191 }
192
193
194 /*
195 QGraphicsItem * item = dynamic_cast<QGraphicsItem *>(object);
196 if (item == NULL) return;
197
198 QGraphicsScene * scene = item->scene();
199 if (scene == NULL) return;
200
201 QGraphicsPixmapItem * pixmapItem = CursorItems.value(scene, NULL);
202 if (pixmapItem == NULL) return;
203
204 pixmapItem->hide();
205 */
206 }
207
deleteCursor(QObject * object)208 void CursorMaster::deleteCursor(QObject * object)
209 {
210 removeCursor(object);
211 }
212
eventFilter(QObject * object,QEvent * event)213 bool CursorMaster::eventFilter(QObject * object, QEvent * event)
214 {
215 Q_UNUSED(object);
216 //QGraphicsScene * scene = NULL;
217
218 switch (event->type()) {
219 case QEvent::KeyPress:
220 case QEvent::KeyRelease:
221 //scene = dynamic_cast<QGraphicsScene *>(object);
222 //DebugDialog::debug(QString("event filter %1").arg(object->metaObject()->className()));
223 //if (scene)
224 {
225 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
226 foreach (QObject * listener, Listeners) {
227 if (listener) {
228 dynamic_cast<CursorKeyListener *>(listener)->cursorKeyEvent(keyEvent->modifiers());
229 break;
230 }
231 }
232 }
233 break;
234 /*
235 case QEvent::GraphicsSceneMouseMove:
236
237 scene = dynamic_cast<QGraphicsScene *>(object);
238 if (scene) {
239 QGraphicsPixmapItem * pixmapItem = CursorItems.value(scene, NULL);
240 if (pixmapItem) {
241 timer.setProperty("loc", ((QGraphicsSceneMouseEvent *) event)->scenePos());
242 timer.setUserData(1, (QObjectUserData *) pixmapItem);
243 }
244 }
245 break;
246
247 case QEvent::Leave:
248 scene = dynamic_cast<QGraphicsScene *>(object);
249 if (scene) {
250 QGraphicsPixmapItem * pixmapItem = CursorItems.value(scene, NULL);
251 if (pixmapItem) {
252 //DebugDialog::debug("pos", ((QGraphicsSceneMouseEvent *) event)->scenePos());
253 pixmapItem->hide();
254 }
255 }
256 break;
257 */
258 default:
259 break;
260 }
261
262
263 return false;
264 }
265
moveCursor()266 void CursorMaster::moveCursor() {
267 //QObject * t = sender();
268 //if (t == NULL) return;
269
270 //QPointF p = t->property("loc").toPointF();
271 //QGraphicsPixmapItem * item = (QGraphicsPixmapItem *) t->userData(1);
272
273 //DebugDialog::debug("move", p);
274 //item->setPos(p); // + cursor->hotspot
275 //item->show();
276 }
277
block()278 void CursorMaster::block() {
279 m_blocked = true;
280 }
281
unblock()282 void CursorMaster::unblock() {
283 m_blocked = false;
284 }
285