summaryrefslogtreecommitdiffstats
path: root/kolf/floater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kolf/floater.cpp')
-rw-r--r--kolf/floater.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/kolf/floater.cpp b/kolf/floater.cpp
new file mode 100644
index 00000000..73612bc8
--- /dev/null
+++ b/kolf/floater.cpp
@@ -0,0 +1,277 @@
+#include <qlabel.h>
+#include <qslider.h>
+
+#include <kconfig.h>
+
+#include "floater.h"
+
+void FloaterGuide::aboutToDelete()
+{
+ game->removeItem(floater);
+ aboutToDie();
+ floater->aboutToDie();
+ delete floater;
+ almostDead = true;
+}
+
+void FloaterGuide::aboutToDie()
+{
+ if (almostDead)
+ return;
+ else
+ Wall::aboutToDie();
+}
+
+void FloaterGuide::moveBy(double dx, double dy)
+{
+ Wall::moveBy(dx, dy);
+ if (floater)
+ floater->reset();
+}
+
+void FloaterGuide::setPoints(int xa, int ya, int xb, int yb)
+{
+ if (fabs(xa - xb) > 0 || fabs(ya - yb) > 0)
+ {
+ Wall::setPoints(xa, ya, xb, yb);
+ if (floater)
+ floater->reset();
+ }
+}
+
+Config *FloaterGuide::config(QWidget *parent)
+{
+ return floater->config(parent);
+}
+
+/////////////////////////
+
+Floater::Floater(QRect rect, QCanvas *canvas)
+ : Bridge(rect, canvas), speedfactor(16)
+{
+ wall = 0;
+ setEnabled(true);
+ noUpdateZ = false;
+ haventMoved = true;
+ wall = new FloaterGuide(this, canvas);
+ wall->setPoints(100, 100, 200, 200);
+ wall->setPen(QPen(wall->pen().color().light(), wall->pen().width() - 1));
+ move(wall->endPoint().x(), wall->endPoint().y());
+
+ setTopWallVisible(false);
+ setBotWallVisible(false);
+ setLeftWallVisible(false);
+ setRightWallVisible(false);
+
+ newSize(width(), height());
+ moveBy(0, 0);
+ setSpeed(0);
+
+ editModeChanged(false);
+ reset();
+}
+
+void Floater::setGame(KolfGame *game)
+{
+ Bridge::setGame(game);
+
+ wall->setGame(game);
+}
+
+void Floater::editModeChanged(bool changed)
+{
+ if (changed)
+ wall->editModeChanged(true);
+ Bridge::editModeChanged(changed);
+ wall->setVisible(changed);
+}
+
+void Floater::advance(int phase)
+{
+ if (!isEnabled())
+ return;
+
+ Bridge::advance(phase);
+
+ if (phase == 1 && (xVelocity() || yVelocity()))
+ {
+ if (Vector(origin, QPoint(x(), y())).magnitude() > vector.magnitude())
+ {
+ vector.setDirection(vector.direction() + M_PI);
+ origin = (origin == wall->startPoint()? wall->endPoint() : wall->startPoint());
+
+ setVelocity(-xVelocity(), -yVelocity());
+ }
+ }
+}
+
+void Floater::reset()
+{
+ QPoint start = wall->startPoint() + QPoint(wall->x(), wall->y());
+ QPoint end = wall->endPoint() + QPoint(wall->x(), wall->y());
+
+ vector = Vector(end, start);
+ origin = end;
+
+ move(origin.x(), origin.y());
+ setSpeed(speed);
+}
+
+QPtrList<QCanvasItem> Floater::moveableItems() const
+{
+ QPtrList<QCanvasItem> ret(wall->moveableItems());
+ ret.append(wall);
+ ret.append(point);
+ return ret;
+}
+
+void Floater::aboutToDie()
+{
+ if (wall)
+ wall->setVisible(false);
+ Bridge::aboutToDie();
+ setEnabled(false);
+}
+
+void Floater::setSpeed(int news)
+{
+ if (!wall || news < 0)
+ return;
+ speed = news;
+
+ if (news == 0)
+ {
+ setVelocity(0, 0);
+ return;
+ }
+
+ const double factor = (double)speed / 3.5;
+ setVelocity(-cos(vector.direction()) * factor, -sin(vector.direction()) * factor);
+}
+
+void Floater::aboutToSave()
+{
+ setVelocity(0, 0);
+ noUpdateZ = true;
+ move(wall->endPoint().x() + wall->x(), wall->endPoint().y() + wall->y());
+ noUpdateZ = false;
+}
+
+void Floater::savingDone()
+{
+ setSpeed(speed);
+}
+
+void Floater::moveBy(double dx, double dy)
+{
+ if (!isEnabled())
+ return;
+
+ QCanvasItemList l = collisions(false);
+ for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it)
+ {
+ CanvasItem *item = dynamic_cast<CanvasItem *>(*it);
+
+ if (!noUpdateZ && item && item->canBeMovedByOthers())
+ item->updateZ(this);
+
+ if ((*it)->z() >= z())
+ {
+ if (item && item->canBeMovedByOthers() && collidesWith(*it))
+ {
+ if ((*it)->rtti() == Rtti_Ball)
+ {
+ //((Ball *)(*it))->setState(Rolling);
+ (*it)->moveBy(dx, dy);
+ if (game && game->hasFocus() && !game->isEditing() && game->curBall() == (Ball *)(*it))
+ game->ballMoved();
+ }
+ else if ((*it)->rtti() != Rtti_Putter)
+ (*it)->moveBy(dx, dy);
+ }
+ }
+ }
+
+ point->dontMove();
+ point->move(x() + width(), y() + height());
+
+ // this call must come after we have tested for collisions, otherwise we skip them when saving!
+ // that's a bad thing
+ QCanvasRectangle::moveBy(dx, dy);
+
+ // because we don't do Bridge::moveBy();
+ topWall->move(x(), y());
+ botWall->move(x(), y() - 1);
+ leftWall->move(x(), y());
+ rightWall->move(x(), y());
+
+ if (game && game->isEditing())
+ game->updateHighlighter();
+}
+
+void Floater::saveState(StateDB *db)
+{
+ db->setPoint(QPoint(x(), y()));
+}
+
+void Floater::loadState(StateDB *db)
+{
+ const QPoint moveTo = db->point();
+ move(moveTo.x(), moveTo.y());
+}
+
+void Floater::save(KConfig *cfg)
+{
+ cfg->writeEntry("speed", speed);
+ cfg->writeEntry("startPoint", QPoint(wall->startPoint().x() + wall->x(), wall->startPoint().y() + wall->y()));
+ cfg->writeEntry("endPoint", QPoint(wall->endPoint().x() + wall->x(), wall->endPoint().y() + wall->y()));
+
+ doSave(cfg);
+}
+
+void Floater::load(KConfig *cfg)
+{
+ move(firstPoint.x(), firstPoint.y());
+
+ QPoint start(wall->startPoint() + QPoint(wall->x(), wall->y()));
+ start = cfg->readPointEntry("startPoint", &start);
+ QPoint end(wall->endPoint() + QPoint(wall->x(), wall->y()));
+ end = cfg->readPointEntry("endPoint", &end);
+ wall->setPoints(start.x(), start.y(), end.x(), end.y());
+ wall->move(0, 0);
+
+ setSpeed(cfg->readNumEntry("speed", -1));
+
+ doLoad(cfg);
+ reset();
+}
+
+void Floater::firstMove(int x, int y)
+{
+ firstPoint = QPoint(x, y);
+}
+
+/////////////////////////
+
+FloaterConfig::FloaterConfig(Floater *floater, QWidget *parent)
+ : BridgeConfig(floater, parent)
+{
+ this->floater = floater;
+ m_vlayout->addStretch();
+
+ m_vlayout->addWidget(new QLabel(i18n("Moving speed"), this));
+ QHBoxLayout *hlayout = new QHBoxLayout(m_vlayout, spacingHint());
+ hlayout->addWidget(new QLabel(i18n("Slow"), this));
+ QSlider *slider = new QSlider(0, 20, 2, floater->curSpeed(), Qt::Horizontal, this);
+ hlayout->addWidget(slider);
+ hlayout->addWidget(new QLabel(i18n("Fast"), this));
+ connect(slider, SIGNAL(valueChanged(int)), this, SLOT(speedChanged(int)));
+}
+
+void FloaterConfig::speedChanged(int news)
+{
+ floater->setSpeed(news);
+ changed();
+}
+
+#include "floater.moc"