Fixed map items collision detection over map limits
[situare] / src / map / frienditemshandler.h
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Sami Rämö - sami.ramo@ixonos.com
6
7     Situare is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     version 2 as published by the Free Software Foundation.
10
11     Situare 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 Situare; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19     USA.
20 */
21
22
23 #ifndef FRIENDITEMSHANDLER_H
24 #define FRIENDITEMSHANDLER_H
25
26 #include <QLinkedList>
27 #include <QObject>
28
29 class BaseLocationItem;
30 class FriendGroupItem;
31 class FriendLocationItem;
32 class MapScene;
33 class User;
34
35 /**
36  * @brief Handler for friend and friend group items
37  *
38  * Handles all friend map items. Colliding items and groups are grouped. All items are owned
39  * by MapScene.
40  *
41  * @author Sami Rämö - sami.ramo@ixonos.com
42  * @author Ville Tiensuu - ville.tiensuu@ixonos.com
43  */
44 class FriendItemsHandler : public QObject
45 {
46     Q_OBJECT
47
48 public:
49     /**
50       * @brief Constructor
51       *
52       * @param mapScene MapScene object
53       * @param parent Parent QObject
54       */
55     FriendItemsHandler(MapScene *mapScene, QObject *parent = 0);
56
57 /*******************************************************************************
58  * MEMBER FUNCTIONS AND SLOTS
59  ******************************************************************************/
60 private:
61     /**
62       * @brief Add new FriendLocationItem
63       *
64       * New FriendLocationItem is created, values are set and item is added to map.
65       * Item is also added to m_friendItems list.
66       *
67       * @param friendData Data for new friend
68       */
69     void addFriendItem(User *friendData);
70
71     /**
72       * @brief Group colliding friends
73       *
74       * Call checkFriendForCollidingFriends() for all visible FriendLocationItem items.
75       */
76     void checkAllFriendsForCollidingFriends();
77
78     /**
79       * @brief Join friends to colliding group
80       *
81       * Call checkGroupForCollidingFriends() for all FriendGroupItem items.
82       */
83     void checkAllGroupsForCollidingFriends();
84
85     /**
86       * @brief Check single FriendLocationItem for colliding FriendLocationItem items
87       *
88       * Check FriendLocationItem against another visible FriendLocationItem items. If collision is
89       * found, then new FriendGroupItem is made and colliding FriendLocationItem items are joined
90       * to this new FriendGroupItem.
91       *
92       * @param item FriendLocationItem to be checked
93       */
94     void checkFriendForCollidingFriends(FriendLocationItem *item);
95
96     /**
97       * @brief Check single FriendGroupItem for colliding FriendLocationItem
98       *
99       * Check FriendGroupItem against all visible FriendLocationItem items. Colliding
100       * FriendLocationItem items are joiden to given FriendGroupItem.
101       *
102       * @param group FriendGroupItem to be checked
103       */
104     void checkGroupForCollidingFriends(FriendGroupItem *group);
105
106     /**
107       * @brief Check single FriendGroupItem for colliding FriendGroupItem items
108       *
109       * Colliding FriendGroupItem items are merged. Item given as parameter remains and colliding
110       * items are deleted after their friend items are merged to remaining group.
111       *
112       * @param group FriendGroupItem to be checked
113       */
114     void checkGroupForCollidingGroups(FriendGroupItem *group);
115
116     /**
117     * @brief clean old friend data from m_mapScene and m_friendItems
118     *
119     * @param friendsList QList item of friend information
120     */
121     void cleanOldFriendData(const QList<User *> &friendsList);
122
123     /**
124     * @brief Check if items collide
125     *
126     * Does check if items sceneTransformedBoundingRect() does intersect. If item1's rect is
127     * over the limits of the map, then rect is translated to opposite side of the map and
128     * intersections are tested there too.
129     *
130     * @param item1 First item
131     * @param item2 Secont item
132     * @return True if collision was found, otherwise false
133     */
134     bool collides(BaseLocationItem *item1, BaseLocationItem *item2);
135
136     /**
137       * @brief Delete FriendLocationItem
138       *
139       * Drops item from all groups, removes it from scene and deletes the item.
140       *
141       * @param item Item to be deleted
142       */
143     void deleteFriendItem(FriendLocationItem *item);
144
145     /**
146       * @brief Drop FriendLocationItem from all FriendGroupItem groups
147       *
148       * @param item Item to be dropped.
149       */
150     void dropFriendFromAllGroups(FriendLocationItem *item);
151
152     /**
153       * @brief Drop all FriendLocationItem items, which are out of FriendGroupItem boundaries,
154       * from all FriendGroupItem items.
155       */
156     void dropOutOfGroupFriends();
157
158     /**
159       * @brief Merge all colliding groups
160       *
161       * Calls checkGroupForCollidingGroups() for all FriendGroupItem items.
162       */
163     void mergeCollidingGroups();
164
165     /**
166       * @brief Update FriendLocationItem data
167       *
168       * Position and image are updated.
169       *
170       * @param friendItem Item to be updated
171       * @param friendData New data for the item
172       */
173     void updateFriendItem(FriendLocationItem *friendItem, User *friendData);
174
175     /**
176     * @brief updates data member m_friendItems from given parameter
177     *
178     * @param friendsList QList item of friend information
179     */
180     void updateFriendItemList(const QList<User *> &friendsList);
181
182     /**
183     * @brief updates data member m_friendItems values that differs from given parameter
184     *
185     * @param friendsList QList item of friend information
186     */
187     void updateFriendLocationsAndImages(const QList<User *> &friendsList);
188
189 private slots:
190     /**
191     * @brief Slot for upgrading friend items and groups
192     *
193     * Does add and/or remove FriendLocationItem items if there are new friends
194     * or old ones deleted in the given list. Remaining FriensLocationItems are updated.
195     *
196     * @param friendsList QList item of friend information
197     */
198     void friendListUpdated(QList<User *> &friendsList);
199
200     /**
201       * @brief Re-factors all FriendLocationItem and FriendGroupItem items.
202       *
203       * Calls mergeCollidingGroups(), dropOutOfGroupFriends(), checkAllGroupsForCollidingFriends()
204       * and checkAllFriendsForCollidingFriends().
205       *
206       * @param zoomLevel Current view zoom level
207       */
208     void refactorFriendItems(int zoomLevel);
209
210 /*******************************************************************************
211  * SIGNALS
212  ******************************************************************************/
213 signals:
214     /**
215     * @brief Signal is emitted when location item is clicked.
216     *
217     * @param userIDs list of friends user IDs in the group
218     */
219     void locationItemClicked(const QList<QString> &userIDs);
220
221 /*******************************************************************************
222  * DATA MEMBERS
223  ******************************************************************************/
224 private:
225     QLinkedList<FriendGroupItem *> m_friendGroupItems; ///< All FriendGroupItem items
226     QLinkedList<FriendLocationItem *> m_friendItems; ///< List of friendLocationItems
227     MapScene *m_mapScene; ///< Pointer to MapScene
228     int m_zoomLevel; ///< Current view zoom level used for calculation of items bounding rect
229 };
230
231 #endif // FRIENDITEMSHANDLER_H