55
66#include " mouseeventhandler.h"
77#include " renderedtarget.h"
8+ #include " projectloader.h"
9+ #include " spritemodel.h"
810
911using namespace scratchcpprender ;
1012
@@ -23,14 +25,20 @@ void MouseEventHandler::setStage(IRenderedTarget *stage)
2325 m_stage = stage;
2426}
2527
26- QQuickItem *MouseEventHandler::spriteRepeater () const
28+ ProjectLoader *MouseEventHandler::projectLoader () const
2729{
28- return m_spriteRepeater ;
30+ return m_projectLoader ;
2931}
3032
31- void MouseEventHandler::setSpriteRepeater (QQuickItem *repeater )
33+ void MouseEventHandler::setProjectLoader (ProjectLoader *newProjectLoader )
3234{
33- m_spriteRepeater = repeater;
35+ m_projectLoader = newProjectLoader;
36+
37+ if (m_projectLoader) {
38+ connect (m_projectLoader, &ProjectLoader::spritesChanged, this , &MouseEventHandler::getSprites);
39+ connect (m_projectLoader, &ProjectLoader::cloneCreated, this , &MouseEventHandler::addClone);
40+ connect (m_projectLoader, &ProjectLoader::cloneDeleted, this , &MouseEventHandler::removeClone);
41+ }
3442}
3543
3644bool MouseEventHandler::eventFilter (QObject *obj, QEvent *event)
@@ -76,34 +84,64 @@ bool MouseEventHandler::eventFilter(QObject *obj, QEvent *event)
7684 return QObject::eventFilter (obj, event);
7785}
7886
79- void MouseEventHandler::forwardPointEvent (QSinglePointEvent *event, QQuickItem *oldClickedItem )
87+ void scratchcpprender:: MouseEventHandler::getSprites ( )
8088{
81- Q_ASSERT (m_spriteRepeater );
89+ Q_ASSERT (m_projectLoader );
8290
83- if (!m_spriteRepeater )
91+ if (!m_projectLoader )
8492 return ;
8593
86- // Create list of sprites
87- std::vector<IRenderedTarget *> sprites;
88- int count = m_spriteRepeater->property (" count" ).toInt ();
89- sprites.reserve (count);
94+ m_sprites.clear ();
95+ const auto &spriteModels = m_projectLoader->spriteList ();
9096
91- for (int i = 0 ; i < count; i++ ) {
92- QQuickItem *sprite = nullptr ;
93- QMetaObject::invokeMethod (m_spriteRepeater, " itemAt " , Qt::DirectConnection, Q_RETURN_ARG (QQuickItem *, sprite), Q_ARG ( int , i) );
97+ for (SpriteModel *model : spriteModels ) {
98+ Q_ASSERT (model) ;
99+ IRenderedTarget * sprite = model-> renderedTarget ( );
94100 Q_ASSERT (sprite);
95- Q_ASSERT (dynamic_cast <IRenderedTarget *>(sprite));
96- Q_ASSERT (dynamic_cast <IRenderedTarget *>(sprite)->scratchTarget ());
97- sprites.push_back (dynamic_cast <IRenderedTarget *>(sprite));
101+ Q_ASSERT (sprite->scratchTarget ());
102+ m_sprites.push_back (sprite);
98103 }
104+ }
105+
106+ void scratchcpprender::MouseEventHandler::addClone (SpriteModel *model)
107+ {
108+ Q_ASSERT (model);
109+ IRenderedTarget *sprite = model->renderedTarget ();
110+ Q_ASSERT (sprite);
111+ Q_ASSERT (std::find_if (m_sprites.begin (), m_sprites.end (), [sprite](IRenderedTarget *renderedTarget) { return renderedTarget == sprite; }) == m_sprites.end ());
112+ m_sprites.push_back (sprite);
113+ }
114+
115+ void scratchcpprender::MouseEventHandler::removeClone (SpriteModel *model)
116+ {
117+ Q_ASSERT (model);
118+ IRenderedTarget *sprite = model->renderedTarget ();
119+ Q_ASSERT (sprite);
120+ m_sprites.erase (std::remove_if (m_sprites.begin (), m_sprites.end (), [sprite](IRenderedTarget *renderedTarget) { return renderedTarget == sprite; }), m_sprites.end ());
121+ Q_ASSERT (std::find_if (m_sprites.begin (), m_sprites.end (), [sprite](IRenderedTarget *renderedTarget) { return renderedTarget == sprite; }) == m_sprites.end ());
122+
123+ // Make sure the pointer is never used again after it becomes "dangling"
124+ if (m_clickedItem == sprite)
125+ m_clickedItem = nullptr ;
126+
127+ if (m_hoveredItem == sprite)
128+ m_hoveredItem = nullptr ;
129+ }
130+
131+ void MouseEventHandler::forwardPointEvent (QSinglePointEvent *event, QQuickItem *oldClickedItem)
132+ {
133+ Q_ASSERT (m_projectLoader);
134+
135+ if (!m_projectLoader)
136+ return ;
99137
100- // Sort the list by layer order
101- std::sort (sprites .begin (), sprites .end (), [](IRenderedTarget *t1, IRenderedTarget *t2) { return t1->scratchTarget ()->layerOrder () > t2->scratchTarget ()->layerOrder (); });
138+ // Sort sprite list by layer order
139+ std::sort (m_sprites .begin (), m_sprites .end (), [](IRenderedTarget *t1, IRenderedTarget *t2) { return t1->scratchTarget ()->layerOrder () > t2->scratchTarget ()->layerOrder (); });
102140
103141 // Find hovered sprite
104142 QQuickItem *hoveredItem = nullptr ;
105143
106- for (IRenderedTarget *sprite : sprites ) {
144+ for (IRenderedTarget *sprite : m_sprites ) {
107145 // contains() expects position in the item's coordinate system
108146 QPointF localPos = sprite->mapFromScene (event->scenePosition ());
109147
0 commit comments