File indexing completed on 2022-11-29 18:38:56

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 "kbbscalablegraphicwidget.h"
0011 
0012 
0013 
0014 #include <QAction>
0015 #include <QFont>
0016 #include <QGraphicsScene>
0017 #include <QLCDNumber>
0018 #include <QResizeEvent>
0019 
0020 
0021 #include <KGamePopupItem>
0022 #include <QIcon>
0023 #include <KLocalizedString>
0024 #include <QPushButton>
0025 
0026 
0027 #include "kbbballsonboard.h"
0028 #include "kbbgamedoc.h"
0029 #include "kbbgraphicsitemball.h"
0030 #include "kbbgraphicsitemballrepository.h"
0031 #include "kbbgraphicsitemblackbox.h"
0032 #include "kbbgraphicsitemcursor.h"
0033 #include "kbbgraphicsitemlaser.h"
0034 #include "kbbgraphicsitemonbox.h"
0035 #include "kbbgraphicsitemray.h"
0036 #include "kbbgraphicsitemrayresult.h"
0037 #include "kbbgraphicsitemset.h"
0038 #include "kbbthememanager.h"
0039 
0040 
0041 
0042 //
0043 // Constructor / Destructor
0044 //
0045 
0046 KBBScalableGraphicWidget::KBBScalableGraphicWidget(KBBGameDoc* gameDoc, KBBThemeManager* themeManager, QAction* done)
0047 {
0048     m_gameDoc = gameDoc;
0049     m_themeManager = themeManager;
0050     m_columns = -2;
0051     m_rows = -2;
0052     m_pause = false;
0053     m_ballNumber = 0;
0054     m_doneAction = done;
0055     m_cursorFollowsMouse = false;
0056 
0057     setFrameStyle(QFrame::NoFrame);
0058     setCacheMode(QGraphicsView::CacheBackground);
0059     setMinimumSize(QSize(MINIMUM_SIZE, MINIMUM_SIZE));
0060 
0061 
0062     m_scene = new QGraphicsScene( 0, 0, 2*BORDER_SIZE, 2*BORDER_SIZE, this );
0063     
0064     m_blackbox = new KBBGraphicsItemBlackBox(this, m_scene, m_themeManager, false);
0065     m_blackbox->setKBBScalableGraphicWidget(this);
0066     m_balls = new KBBGraphicsItemSet(m_scene);
0067     m_cursor = new KBBGraphicsItemCursor(this, m_themeManager);
0068     connect(m_cursor, &KBBGraphicsItemCursor::cursorAtNewPosition, this, &KBBScalableGraphicWidget::cursorAtNewPosition);
0069     m_markersNothing = new KBBGraphicsItemSet(m_scene);
0070     m_ballsSolution = new KBBGraphicsItemSet(m_scene);
0071     m_ballsUnsure = new KBBGraphicsItemSet(m_scene);
0072     m_lasers = new KBBGraphicsItemSet(m_scene);
0073     m_rayResults = new KBBGraphicsItemSet(m_scene);
0074     
0075     m_playerRay = new KBBGraphicsItemRay(playerRay, m_scene, m_themeManager);
0076     m_solutionRay = new KBBGraphicsItemRay(solutionRay, m_scene, m_themeManager);
0077     
0078     // Information message about the score
0079     m_infoScore = new KGamePopupItem();
0080     m_infoScore->setMessageIcon(QPixmap()); // No icon, because they are no scalable.
0081     m_scene->addItem(m_infoScore); // it hides itself by default
0082 
0083     m_ballRepository = new KBBGraphicsItemBallRepository(this, themeManager);
0084 
0085     setScene(m_scene);
0086 
0087     m_doneButton = new QPushButton(m_doneAction->text(), this);
0088     m_doneButton->setIcon(QIcon(m_doneAction->icon()));
0089     m_doneButton->setWhatsThis(m_doneAction->whatsThis());
0090     connect(m_doneButton, &QPushButton::clicked, m_doneAction, &QAction::trigger);
0091     QFont font;
0092     font.setPointSize(m_doneButton->font().pointSize()+2);
0093     font.setBold(true);
0094     m_doneButton->setFont(font);
0095 
0096     m_score = new QLCDNumber(3, this);
0097     m_score->setFrameStyle(QFrame::NoFrame);
0098     m_score->setMaximumWidth(m_doneButton->width());
0099     m_score->setFixedHeight((int)(1.5*m_doneButton->height()));
0100     m_score->setToolTip(i18n("Score"));
0101     m_score->setWhatsThis(i18n("<qt><p>This is <b>your score</b>. You should try to get the lowest possible.</p><p>The score increases:<ul><li>with time: <b>1 point</b> per second.</li><li>with the use of lasers:<ul><li><b>3 points</b> if the laser beam hits a ball or exits at the entry point,</li><li><b>9 points</b> if it exits at another entry point.</li></ul></li></ul></p><p>Your score is set to <b>999</b> at the end of the game if you make a mistake.</p></qt>"));
0102 
0103     // TODO: not displayed... :(
0104     setWhatsThis(i18n("<qt><p>This is the <b>main game area</b>.</p><ul><li>The <b>black box</b> is in the center.</li><li>On the left, there are the <b>balls</b> you have to place over the black box.</li><li>Around the black box, there are <b>lasers</b> that are replaced with <b>interaction information</b> if you use them.</li></ul></qt>"));
0105     connect(m_blackbox, &KBBGraphicsItemBlackBox::hoverMoved, this, &KBBScalableGraphicWidget::hoverMovePosition);
0106 
0107 }
0108 
0109 
0110 KBBScalableGraphicWidget::~KBBScalableGraphicWidget()
0111 {
0112     delete m_balls;
0113     delete m_markersNothing;
0114     delete m_ballsSolution;
0115     delete m_ballsUnsure;
0116     delete m_lasers;
0117     delete m_rayResults;
0118 
0119     delete m_ballRepository;
0120 
0121     delete m_scene;
0122 }
0123 
0124 
0125 
0126 //
0127 // Public
0128 //
0129 
0130 void KBBScalableGraphicWidget::addBall(int boxPosition)
0131 {
0132     addBall(boxPosition, KBBGraphicsItemOnBox::NO_POSITION);
0133 }
0134 
0135 
0136 void KBBScalableGraphicWidget::addBall(int boxPosition, int outsidePosition)
0137 {
0138     if (!m_pause && m_inputAccepted && (!m_balls->containsVisible(boxPosition))&& (!m_ballsUnsure->containsVisible(boxPosition))) {
0139         m_boardBallsPlaced->add(boxPosition);
0140         m_balls->insert(new KBBGraphicsItemBall(playerBall, this, m_themeManager, boxPosition, m_columns, m_rows));
0141         m_markersNothing->remove(boxPosition);
0142         if (outsidePosition==KBBGraphicsItemOnBox::NO_POSITION) {
0143             outsidePosition = m_ballRepository->ballToTake();
0144         }
0145         if (outsidePosition!=KBBGraphicsItemSet::NO_INDEX)
0146             m_ballRepository->removeBall(outsidePosition);
0147 
0148         updateDoneButton();
0149     }
0150 }
0151 
0152 
0153 void KBBScalableGraphicWidget::addBallUnsure(const int boxPosition)
0154 {
0155     addBall(boxPosition);
0156     setBallUnsure(boxPosition, true);
0157 }
0158 
0159 
0160 void KBBScalableGraphicWidget::addMarkerNothing(const int boxPosition)
0161 {
0162     if (!m_pause && m_inputAccepted && (!m_markersNothing->containsVisible(boxPosition))) {
0163         m_markersNothing->insert(new KBBGraphicsItemOnBox(markerNothing, this, m_themeManager, boxPosition, m_columns, m_rows));
0164         m_balls->remove(boxPosition);
0165         m_ballsUnsure->remove(boxPosition);
0166         m_boardBallsPlaced->remove(boxPosition);
0167     }
0168 }
0169 
0170 
0171 void KBBScalableGraphicWidget::drawRay(const int borderPosition)
0172 {
0173     if (!m_pause) {
0174         if (!m_inputAccepted) {
0175             m_solutionRay->draw(m_boardBalls, borderPosition);
0176         }
0177         m_playerRay->draw(m_boardBallsPlaced, borderPosition);
0178     }
0179 }
0180 
0181 
0182 void KBBScalableGraphicWidget::mouseBorderClick(const int borderPosition)
0183 {
0184     useLaser(borderPosition);
0185     m_cursor->setBorderPosition(borderPosition);
0186     m_cursor->hide();
0187 }
0188 
0189 
0190 void KBBScalableGraphicWidget::mouseBoxClick(const Qt::MouseButton button, int boxPosition)
0191 {
0192     m_cursor->setBoxPosition(boxPosition);
0193     if (button==Qt::RightButton)
0194         switchMarker();
0195     else
0196         switchBall();
0197     m_cursor->hide();
0198 }
0199 
0200 
0201 int KBBScalableGraphicWidget::moveBall(const int boxPositionFrom, const int boxPositionTo)
0202 {
0203     int newPos = positionAfterMovingBall(boxPositionFrom, boxPositionTo);
0204 
0205     if (!m_pause && m_inputAccepted && (!m_balls->containsVisible(boxPositionTo)) && (!m_ballsUnsure->containsVisible(boxPositionTo))) {
0206         m_markersNothing->remove(boxPositionTo);
0207         if (boxPositionFrom>=m_columns*m_rows) {
0208             // ball moved from outside of the board
0209             addBall(boxPositionTo, boxPositionFrom);
0210         } else {
0211             // ball moved from a board position
0212             m_boardBallsPlaced->remove(boxPositionFrom);
0213             m_boardBallsPlaced->add(boxPositionTo);
0214         }
0215     }
0216 
0217     return newPos;
0218 }
0219 
0220 
0221 int KBBScalableGraphicWidget::moveMarkerNothing(const int boxPositionFrom, const int boxPositionTo)
0222 {
0223     if (!m_pause && m_inputAccepted && (!m_markersNothing->containsVisible(boxPositionTo))) {
0224         removeBall(boxPositionTo);
0225         return boxPositionTo;
0226     } else
0227         return boxPositionFrom;
0228 }
0229 
0230 
0231 void KBBScalableGraphicWidget::newGame(int columns, int rows, int ballNumber)
0232 {
0233     m_rayNumber = 0;
0234     m_boardBallsPlaced = m_gameDoc->m_ballsPlaced;
0235     setPause(false);
0236     m_ballNumber = ballNumber;
0237 
0238     // remove old ray results, all placed balls, all markers "nothing" and all solutions
0239     m_rayResults->clear();
0240     m_balls->clear();
0241     m_ballsUnsure->clear();
0242     m_markersNothing->clear();
0243     m_ballsSolution->clear();
0244 
0245     // Reorganize lasers
0246     if ((columns!=m_columns) || (rows!=m_rows)) {
0247         // not the same amount of lasers: We can destroy them and create some new ones
0248         m_lasers->clear();
0249         for (int i=0; i<2*(columns + rows); i++)
0250             m_lasers->insert(new KBBGraphicsItemLaser(this, m_themeManager, i, columns, rows));
0251     } else {
0252         // same amount of lasers: We "recycle" them. (Just destroying them and re-creating them is not working fine: some lasers remain hidden until the next resize... Strange bug with QGraphicsView...)
0253         for (int i=0; i<2*(m_columns + m_rows); i++)
0254             m_lasers->setVisible(i, true);
0255     }
0256 
0257     m_ballRepository->newGame(columns, rows, ballNumber);
0258 
0259     // set the new size if needed
0260     if (m_columns!=columns || m_rows!=rows) {
0261         m_columns = columns;
0262         m_rows = rows;
0263         m_blackbox->setSize(m_columns, m_rows);
0264         m_cursor->setBoardSize(m_columns, m_rows);
0265         m_scene->setSceneRect(m_ballRepository->x() - RATIO, 0, m_columns*RATIO + 2*BORDER_SIZE - m_ballRepository->x() + RATIO, m_rows*RATIO + 2*BORDER_SIZE);
0266     }
0267     resizeEvent(nullptr);
0268     setInputAccepted(true);
0269 }
0270 
0271 
0272 void KBBScalableGraphicWidget::popupText(const QString& text, int time)
0273 {
0274     if (text.isEmpty())
0275         m_infoScore->forceHide();
0276     else {
0277         m_infoScore->setMessageTimeout(time);
0278         m_infoScore->showMessage(text, KGamePopupItem::TopLeft, KGamePopupItem::ReplacePrevious);
0279     }
0280 }
0281 
0282 
0283 int KBBScalableGraphicWidget::positionAfterMovingBall(const int boxPositionFrom, const int boxPositionTo) const
0284 {
0285     if (!m_pause && m_inputAccepted && (!m_balls->containsVisible(boxPositionTo)) && (!m_ballsUnsure->containsVisible(boxPositionTo))) {
0286         return boxPositionTo;
0287     } else
0288         return boxPositionFrom;
0289 }
0290 
0291 
0292 void KBBScalableGraphicWidget::setPause(bool state)
0293 {
0294     m_pause = state;
0295     for (int i=0;i<2*(m_rows+m_columns);i++) {
0296         if (m_rayResults->containsVisible(i))
0297             m_rayResults->item(i)->setPause(state);
0298     }
0299 
0300     updateDoneButton();
0301 }
0302 
0303 
0304 void KBBScalableGraphicWidget::resizeEvent( QResizeEvent* )
0305 {
0306     // 1. Compute the size of m_rectBackground
0307     const qreal sW = m_scene->width();
0308     const qreal sH = m_scene->height();
0309     const qreal wW = width();
0310     const qreal wH = height();
0311     const qreal offset = (sH+sW)/100 ;
0312     if (sH*wW > sW*wH) {
0313         // The widget is larger than the scene
0314         qreal w =  wW*sH/wH;
0315         m_rectBackground.setRect((sW-w)/2-offset+m_ballRepository->x()-RATIO, -offset, w + 2*offset, sH + 2*offset);
0316     } else {
0317         // The scene is larger than the widget (or as large)
0318         qreal h =  wH*sW/wW;
0319         m_rectBackground.setRect(-offset+m_ballRepository->x()-RATIO, (sH-h)/2-offset, sW + 2*offset, h + 2*offset);
0320     }
0321     
0322     // 2. Resize the scene to fit in the widget
0323     fitInView(m_ballRepository->x()-RATIO, 0, m_columns*RATIO + 2*BORDER_SIZE - m_ballRepository->x() + RATIO, m_rows*RATIO + 2*BORDER_SIZE, Qt::KeepAspectRatio);
0324 
0325 
0326     m_doneButton->move(OFFSET_DONE_BUTTON, height() - m_doneButton->height() - OFFSET_DONE_BUTTON);
0327     m_score->move(OFFSET_DONE_BUTTON, height() - m_score->height() - m_doneButton->height() - 3*OFFSET_DONE_BUTTON);
0328 }
0329 
0330 
0331 void KBBScalableGraphicWidget::removeAllBalls()
0332 {
0333     for (int i=0;i<m_columns*m_rows;i++) {
0334         removeBall(i);
0335     }
0336 }
0337 
0338 
0339 void KBBScalableGraphicWidget::removeBall(const int boxPosition)
0340 {
0341     if (!m_pause && m_inputAccepted) {
0342         m_balls->remove(boxPosition);
0343         m_ballsUnsure->remove(boxPosition);
0344         m_boardBallsPlaced->remove(boxPosition);
0345         m_ballRepository->fillBallsOutside(m_gameDoc->m_ballsPlaced->count());
0346 
0347         updateDoneButton();
0348     }
0349 }
0350 
0351 
0352 void KBBScalableGraphicWidget::removeRay()
0353 {
0354     m_playerRay->hide();
0355     m_solutionRay->hide();
0356 }
0357 
0358 
0359 QGraphicsScene* KBBScalableGraphicWidget::scene()
0360 {
0361     return m_scene;
0362 }
0363 
0364 
0365 void KBBScalableGraphicWidget::setScore(int score)
0366 {
0367     m_score->display(score);
0368 }
0369 
0370 
0371 void KBBScalableGraphicWidget::solve(const bool continueGame)
0372 {
0373     m_boardBalls = m_gameDoc->m_balls;
0374     
0375     setInputAccepted(continueGame);
0376     if (!continueGame)
0377         setPause(false);
0378     
0379     for (int i=0; i<(m_columns * m_rows); i++) {
0380         if ((m_balls->containsVisible(i) || m_ballsUnsure->containsVisible(i)) && m_boardBalls->contains(i)) {
0381             m_ballsSolution->remove(i); // For the sandbox mode: a solution ball could already be here.
0382             m_ballsSolution->insert(new KBBGraphicsItemBall(rightPlayerBall, this, m_themeManager, i, m_columns, m_rows));
0383         }
0384         if ((m_balls->containsVisible(i) || m_ballsUnsure->containsVisible(i)) && !m_boardBalls->contains(i))
0385             m_ballsSolution->insert(new KBBGraphicsItemOnBox(wrongPlayerBall, this, m_themeManager, i, m_columns, m_rows));
0386         if (!m_balls->containsVisible(i) && !m_ballsUnsure->containsVisible(i) && m_boardBalls->contains(i))
0387             m_ballsSolution->insert(new KBBGraphicsItemBall(solutionBall, this, m_themeManager, i, m_columns, m_rows));
0388     }
0389 }
0390 
0391 
0392 
0393 //
0394 // Public slots
0395 //
0396 
0397 void KBBScalableGraphicWidget::cursorAtNewPosition(int borderPosition)
0398 {
0399     removeRay();
0400     if ((borderPosition!=KBBGraphicsItemCursor::NO_POSITION) && m_cursor->isVisible())
0401         drawRay(borderPosition);
0402 
0403     // highlight
0404     for (int i=0;i<2*(m_rows+m_columns);i++) {
0405         if (m_rayResults->containsVisible(i))
0406             m_rayResults->item(i)->highlight(false);
0407     }
0408     if (m_rayResults->containsVisible(borderPosition))
0409         m_rayResults->item(borderPosition)->highlightBoth(true);
0410 
0411 }
0412 
0413 
0414 void KBBScalableGraphicWidget::keyboardEnter()
0415 {
0416     if (m_cursor->isVisible()) {
0417         if (m_cursor->borderPosition() != KBBGraphicsItemCursor::NO_POSITION)
0418             useLaser(m_cursor->borderPosition());
0419         else
0420             switchBall();
0421     }
0422     m_cursor->show();
0423 }
0424 
0425 
0426 void KBBScalableGraphicWidget::keyboardMoveDown()
0427 {
0428     if (m_cursor->isVisible())
0429         m_cursor->moveDown();
0430     m_cursor->show();
0431 }
0432 
0433 
0434 void KBBScalableGraphicWidget::keyboardMoveLeft()
0435 {
0436     if (m_cursor->isVisible())
0437         m_cursor->moveLeft();
0438     m_cursor->show();
0439 }
0440 
0441 
0442 void KBBScalableGraphicWidget::keyboardMoveRight()
0443 {
0444     if (m_cursor->isVisible())
0445         m_cursor->moveRight();
0446     m_cursor->show();
0447 }
0448 
0449 
0450 void KBBScalableGraphicWidget::keyboardMoveUp()
0451 {
0452     if (m_cursor->isVisible())
0453         m_cursor->moveUp();
0454     m_cursor->show();
0455 }
0456 
0457 
0458 void KBBScalableGraphicWidget::keyboardSpace()
0459 {
0460     if (m_cursor->isVisible()) {
0461         if (m_cursor->boxPosition() != KBBGraphicsItemCursor::NO_POSITION)
0462             switchMarker();
0463     }
0464     m_cursor->show();
0465 }
0466 
0467 
0468 
0469 //
0470 // Protected
0471 //
0472 
0473 void KBBScalableGraphicWidget::drawBackground(QPainter* painter, const QRectF&)
0474 {
0475     m_themeManager->svgRenderer()->render(painter, m_themeManager->elementId(background), m_rectBackground);
0476 }
0477 
0478 
0479 
0480 //
0481 // Private
0482 //
0483 
0484 void KBBScalableGraphicWidget::removeMarkerNothing(const int boxPosition)
0485 {
0486     if (!m_pause && m_inputAccepted) {
0487         m_markersNothing->remove(boxPosition);
0488     }
0489 }
0490 
0491 
0492 void KBBScalableGraphicWidget::setBallUnsure(const int boxPosition, const bool unsure)
0493 {
0494     if (!m_pause && m_inputAccepted) {
0495         if (unsure) {
0496             m_balls->remove(boxPosition);
0497             m_ballsUnsure->insert(new KBBGraphicsItemBall(unsureBall, this, m_themeManager, boxPosition, m_columns, m_rows));
0498         } else {
0499             m_ballsUnsure->remove(boxPosition);
0500             m_balls->insert(new KBBGraphicsItemBall(playerBall, this, m_themeManager, boxPosition, m_columns, m_rows));
0501         }
0502     }
0503 }
0504 
0505 
0506 void KBBScalableGraphicWidget::setInputAccepted(bool inputAccepted)
0507 {
0508     m_inputAccepted = inputAccepted;
0509     if (m_inputAccepted) {
0510         setFocusPolicy( Qt::StrongFocus );
0511         setFocus();
0512     } else {
0513         setFocusPolicy( Qt::NoFocus );
0514         clearFocus();
0515     }
0516 
0517     updateDoneButton();
0518 }
0519 
0520 
0521 void KBBScalableGraphicWidget::switchBall()
0522 {
0523     if ((m_balls->containsVisible(m_cursor->boxPosition())) || (m_ballsUnsure->containsVisible(m_cursor->boxPosition())))
0524         removeBall(m_cursor->boxPosition());
0525     else if (m_ballRepository->ballToTake() != KBBGraphicsItemSet::NO_INDEX)
0526         addBall(m_cursor->boxPosition());
0527 }
0528 
0529 
0530 void KBBScalableGraphicWidget::switchMarker()
0531 {
0532     if (m_balls->containsVisible(m_cursor->boxPosition()))
0533         setBallUnsure(m_cursor->boxPosition(), true);
0534     else if (m_markersNothing->containsVisible(m_cursor->boxPosition()))
0535         removeMarkerNothing(m_cursor->boxPosition());
0536         else{
0537         removeBall(m_cursor->boxPosition());
0538         addMarkerNothing(m_cursor->boxPosition());
0539         }
0540 }
0541 
0542 
0543 void KBBScalableGraphicWidget::updateDoneButton()
0544 {
0545     m_doneButton->setEnabled(m_doneAction->isEnabled());
0546     m_doneButton->setToolTip(m_doneAction->toolTip());
0547 }
0548 
0549 
0550 void KBBScalableGraphicWidget::useLaser(const int incomingPosition)
0551 {
0552     if (!m_pause && m_gameDoc->mayShootRay(incomingPosition) && m_inputAccepted && m_lasers->containsVisible(incomingPosition)) {
0553         const int outgoingPosition = m_gameDoc->shootRay(incomingPosition);
0554         
0555         KBBGraphicsItemRayResult* inRay;
0556         KBBGraphicsItemRayResult* outRay;
0557         
0558         int rayNumberOrReflection = 0;
0559         if (outgoingPosition==KBBGameDoc::HIT_POSITION)
0560             rayNumberOrReflection = KBBGameDoc::HIT_POSITION;
0561         if ((outgoingPosition!=incomingPosition) && (outgoingPosition!=KBBGameDoc::HIT_POSITION)) {
0562             m_rayNumber++;
0563             m_lasers->setVisible(outgoingPosition, false);
0564             m_rayResults->insert(outRay = new KBBGraphicsItemRayResult(this, m_themeManager, m_scene, outgoingPosition, m_columns, m_rows, m_rayNumber));
0565             rayNumberOrReflection = m_rayNumber;
0566         }
0567         m_rayResults->insert(inRay = new KBBGraphicsItemRayResult(this, m_themeManager, m_scene, incomingPosition, m_columns, m_rows, rayNumberOrReflection));
0568         
0569         if ((outgoingPosition!=incomingPosition) && (outgoingPosition!=KBBGameDoc::HIT_POSITION)) {
0570             inRay->setOpposite(outRay);
0571             outRay->setOpposite(inRay);
0572         }
0573         
0574         m_scene->update();
0575         m_lasers->setVisible(incomingPosition, false);
0576 
0577         popupText(QString()); // To Remove any displayed text quicker.
0578 
0579         cursorAtNewPosition(incomingPosition);
0580     }
0581 }
0582 
0583 void KBBScalableGraphicWidget::hoverMovePosition(int pos)
0584 {
0585     if (m_cursorFollowsMouse)
0586     {
0587         m_cursor->show();
0588         m_cursor->setBoxPosition(pos);
0589         m_cursor->updatePositions();
0590     }
0591 }
0592 
0593 void KBBScalableGraphicWidget::toggleCursor()
0594 {
0595     m_cursorFollowsMouse = !m_cursorFollowsMouse;
0596     if (m_cursorFollowsMouse == false){
0597         m_cursor->hide();
0598     }
0599 }
0600 
0601 void KBBScalableGraphicWidget::cursorOff() {
0602     m_cursor->hide();
0603 }
0604