1//
2// KBlackBox
3//
4// A simple game inspired by an emacs module
5//
6/***************************************************************************
7 * Copyright (c) 1999-2000, Robert Cimrman *
8 * cimrman3@students.zcu.cz *
9 * *
10 * Copyright (c) 2007, Nicolas Roffet *
11 * nicolas-kde@roffet.com *
12 * *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA *
28 ***************************************************************************/
29
30#include "kbbgraphicsitemonbox.h"
31
32
33
34#include <QGraphicsScene>
35#include <QGraphicsSceneMouseEvent>
36
37
38#include "kbbgraphicsitem.h"
39#include "kbbgraphicsiteminteractioninfo.h"
40#include "kbbitemwithposition.h"
41#include "kbbscalablegraphicwidget.h"
42#include "kbbthememanager.h"
43
44
45
46//
47// Constructor / Destructor
48//
49
50KBBGraphicsItemOnBox::KBBGraphicsItemOnBox(KBBScalableGraphicWidget::itemType itemType, KBBScalableGraphicWidget* parent, KBBThemeManager* themeManager, const int boxPosition, const int columns, const int rows) : KBBGraphicsItem(itemType, parent->scene(), themeManager), KBBItemWithPosition()
51{
52 m_widget = parent;
53 m_columns = columns;
54 m_rows = rows;
55 m_itemType = itemType;
56
57 setBoxPosition(boxPosition);
58
59 if (isMovable()) {
60 setAcceptDrops(true);
61 setFlag(QGraphicsItem::ItemIsMovable);
62 }
63}
64
65
66
67//
68// Public
69//
70
71int KBBGraphicsItemOnBox::position ()
72{
73 return m_boxPosition;
74}
75
76
77
78//
79// Protected
80//
81
82void KBBGraphicsItemOnBox::removeInteractionInfos()
83{
84}
85
86
87
88//
89// Private
90//
91
92int KBBGraphicsItemOnBox::boxPosition(qreal x, qreal y)
93{
94 int r = (int)((y - KBBScalableGraphicWidget::BORDER_SIZE)/KBBScalableGraphicWidget::RATIO);
95 int c = (int)((x - KBBScalableGraphicWidget::BORDER_SIZE)/KBBScalableGraphicWidget::RATIO);
96
97 if ((r<0) || (r>=m_rows) || (c<0) || (c>=m_columns)) {
98 if (m_boxPosition>=m_columns*m_rows)
99 // Item is outside of the board
100 return m_boxPosition;
101 else
102 return NO_POSITION;
103 } else
104 return c+r*m_columns;
105}
106
107
108bool KBBGraphicsItemOnBox::isMovable()
109{
110 return ((m_itemType==KBBScalableGraphicWidget::playerBall) || (m_itemType==KBBScalableGraphicWidget::unsureBall) || (m_itemType==KBBScalableGraphicWidget::markerNothing));
111}
112
113
114void KBBGraphicsItemOnBox::mousePressEvent (QGraphicsSceneMouseEvent* event)
115{
116 m_dragXPos = x();
117 m_dragYPos = y();
118 m_dragX = event->scenePos().x();
119 m_dragY = event->scenePos().y();
120
121 if (isMovable()) {
122 setCursor(Qt::ClosedHandCursor);
123 removeInteractionInfos();
124 }
125}
126
127
128void KBBGraphicsItemOnBox::mouseReleaseEvent (QGraphicsSceneMouseEvent* event)
129{
130 // Let's Qt handle the drag en drop
131 QGraphicsItem::mouseReleaseEvent(event);
132
133 qreal dropX = event->scenePos().x();
134 qreal dropY = event->scenePos().y();
135
136 if ((dropX==m_dragX) && (dropY==m_dragY)) {
137 setCursor(Qt::ArrowCursor);
138 if ((position()!=NO_POSITION) && (position()<(m_columns*m_rows)))
139 m_widget->mouseBoxClick(event->button(), position());
140 } else if (isMovable()) {
141 setCursor(Qt::ArrowCursor);
142
143 if ((boxPosition(dropX, dropY)==NO_POSITION) || (boxPosition(dropX, dropY)==boxPosition(m_dragX, m_dragY)) || (boxPosition(dropX, dropY)>=m_columns*m_rows))
144 // Cancel move
145 setPos(m_dragXPos, m_dragYPos);
146 else {
147 if (m_itemType==KBBScalableGraphicWidget::markerNothing)
148 setBoxPosition(m_widget->moveMarkerNothing(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY)));
149 else {
150 int newPos = m_widget->positionAfterMovingBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY));
151
152 // if we do move from outside the board. Because in this case and if the move is OK, we will destroy ourself to put a "real" new ball over the board... So we cannot do anything else more after calling m_widget->moveBall()...
153 if ((m_boxPosition==NO_POSITION) || (m_boxPosition>=(m_columns*m_rows))) {
154 if (newPos==m_boxPosition)
155 setPos(m_dragXPos, m_dragYPos);
156 else
157 m_widget->moveBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY));
158 } else
159 setBoxPosition(m_widget->moveBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY)));
160 }
161 }
162 }
163}
164
165
166void KBBGraphicsItemOnBox::setBoxPosition(int boxPosition)
167{
168 m_boxPosition = boxPosition;
169
170 if ((boxPosition!=NO_POSITION) && (boxPosition<m_columns*m_rows)) {
171 QPointF p((qreal) (KBBScalableGraphicWidget::BORDER_SIZE + KBBScalableGraphicWidget::RATIO*(boxPosition % m_columns)), (qreal) (KBBScalableGraphicWidget::BORDER_SIZE + KBBScalableGraphicWidget::RATIO*(boxPosition / m_columns)));
172 setPos(p);
173 }
174}
175