File indexing completed on 2024-04-21 04:02:02

0001 /*
0002     KBlackBox - A simple game inspired by an emacs module
0003 
0004     SPDX-FileCopyrightText: 1999-2000 Robert Cimrman <cimrman3@students.zcu.cz>
0005     SPDX-FileCopyrightText: 2007 Nicolas Roffet <nicolas-kde@roffet.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "kbbgraphicsitemonbox.h"
0011 
0012 #include <QGraphicsScene>
0013 #include <QGraphicsSceneMouseEvent>
0014 
0015 #include "kbbgraphicsiteminteractioninfo.h"
0016 #include "kbbscalablegraphicwidget.h"
0017 #include "kbbthememanager.h"
0018 
0019 
0020 
0021 //
0022 // Constructor / Destructor
0023 //
0024 
0025 KBBGraphicsItemOnBox::KBBGraphicsItemOnBox(KBBScalableGraphicWidget::itemType itemType, KBBScalableGraphicWidget* parent, KBBThemeManager* themeManager, const int boxPosition, const int columns, const int rows) : KBBGraphicsItem(itemType, parent->scene(), themeManager), KBBItemWithPosition()
0026 {
0027     m_widget = parent;
0028     m_columns = columns;
0029     m_rows = rows;
0030     m_itemType = itemType;
0031     
0032     setBoxPosition(boxPosition);
0033 
0034     if (isMovable()) {
0035         setAcceptDrops(true);
0036         setFlag(QGraphicsItem::ItemIsMovable);
0037     }
0038 }
0039 
0040 
0041 
0042 //
0043 // Public
0044 //
0045 
0046 int KBBGraphicsItemOnBox::position ()
0047 {
0048     return m_boxPosition;
0049 }
0050 
0051 
0052 
0053 //
0054 // Protected
0055 //
0056 
0057 void KBBGraphicsItemOnBox::removeInteractionInfos()
0058 {
0059 }
0060 
0061 
0062 
0063 //
0064 // Private
0065 //
0066 
0067 int KBBGraphicsItemOnBox::boxPosition(qreal x, qreal y)
0068 {
0069     int r = (int)((y - KBBScalableGraphicWidget::BORDER_SIZE)/KBBScalableGraphicWidget::RATIO);
0070     int c = (int)((x - KBBScalableGraphicWidget::BORDER_SIZE)/KBBScalableGraphicWidget::RATIO);
0071 
0072     if ((r<0) || (r>=m_rows) || (c<0) || (c>=m_columns)) {
0073         if (m_boxPosition>=m_columns*m_rows)
0074             // Item is outside of the board
0075             return m_boxPosition;
0076         else
0077             return NO_POSITION;
0078     } else
0079         return c+r*m_columns;
0080 }
0081 
0082 
0083 bool KBBGraphicsItemOnBox::isMovable()
0084 {
0085     return ((m_itemType==KBBScalableGraphicWidget::playerBall) || (m_itemType==KBBScalableGraphicWidget::unsureBall) || (m_itemType==KBBScalableGraphicWidget::markerNothing));
0086 }
0087 
0088 
0089 void KBBGraphicsItemOnBox::mousePressEvent (QGraphicsSceneMouseEvent* event)
0090 {
0091     m_dragXPos = x();
0092     m_dragYPos = y();
0093     m_dragX = event->scenePos().x();
0094     m_dragY = event->scenePos().y();
0095 
0096     if (isMovable()) {
0097         setCursor(Qt::ClosedHandCursor);
0098         removeInteractionInfos();
0099     }
0100 }
0101 
0102 
0103 void KBBGraphicsItemOnBox::mouseReleaseEvent (QGraphicsSceneMouseEvent* event)
0104 {
0105     // Let's Qt handle the drag en drop
0106     QGraphicsItem::mouseReleaseEvent(event);
0107 
0108     qreal dropX = event->scenePos().x();
0109     qreal dropY = event->scenePos().y();
0110 
0111     if ((dropX==m_dragX) && (dropY==m_dragY)) {
0112         setCursor(Qt::ArrowCursor);
0113         if ((position()!=NO_POSITION) && (position()<(m_columns*m_rows)))
0114             m_widget->mouseBoxClick(event->button(), position());
0115     } else if (isMovable()) {
0116         setCursor(Qt::ArrowCursor);
0117 
0118         if ((boxPosition(dropX, dropY)==NO_POSITION) || (boxPosition(dropX, dropY)==boxPosition(m_dragX, m_dragY)) || (boxPosition(dropX, dropY)>=m_columns*m_rows))
0119             // Cancel move
0120             setPos(m_dragXPos, m_dragYPos);
0121         else {
0122             if (m_itemType==KBBScalableGraphicWidget::markerNothing)
0123                 setBoxPosition(m_widget->moveMarkerNothing(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY)));
0124             else {
0125                 int newPos = m_widget->positionAfterMovingBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY));
0126 
0127                 // 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()...
0128                 if ((m_boxPosition==NO_POSITION) || (m_boxPosition>=(m_columns*m_rows))) {
0129                     if (newPos==m_boxPosition)
0130                         setPos(m_dragXPos, m_dragYPos);
0131                     else
0132                         m_widget->moveBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY));
0133                 } else
0134                     setBoxPosition(m_widget->moveBall(boxPosition(m_dragX, m_dragY), boxPosition(dropX, dropY)));
0135             }
0136         }
0137     }
0138 }
0139 
0140 
0141 void KBBGraphicsItemOnBox::setBoxPosition(int boxPosition)
0142 {
0143     m_boxPosition = boxPosition;
0144 
0145     if ((boxPosition!=NO_POSITION) && (boxPosition<m_columns*m_rows)) {
0146         QPointF p((qreal) (KBBScalableGraphicWidget::BORDER_SIZE + KBBScalableGraphicWidget::RATIO*(boxPosition % m_columns)), (qreal) (KBBScalableGraphicWidget::BORDER_SIZE + KBBScalableGraphicWidget::RATIO*(boxPosition / m_columns)));
0147         setPos(p);
0148     }
0149 }