Files
dota_factory/src/ui/HeaderBar.cpp

133 lines
4.1 KiB
C++

#include "HeaderBar.h"
#include <cmath>
#include <string>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSignalMapper>
#include "Command.h"
#include "CommandRequestedEvent.h"
#include "EventManager.h"
#include "SpeedChangeRequestedEvent.h"
#include "Tick.h"
const double HeaderBar::kSpeeds[] = { 0.0, 0.5, 1.0, 2.0, 10.0 };
const int HeaderBar::kSpeedCount = 5;
HeaderBar::HeaderBar(QWidget* parent)
: QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(8, 4, 8, 4);
layout->setSpacing(8);
m_timeLabel = new QLabel("00:00", this);
m_blocksLabel = new QLabel(tr("Blocks: 0"), this);
m_artifactsLabel = new QLabel(tr("Artifacts: 0/?"), this);
m_bossLabel = new QLabel(tr("Boss Wave #1 Next boss: 5:00"), this);
layout->addWidget(m_timeLabel);
layout->addWidget(m_blocksLabel);
layout->addWidget(m_artifactsLabel);
layout->addStretch();
layout->addWidget(m_bossLabel);
// Asteroid expansion button, to the left of the speed buttons (REQ-UI-HEADER,
// REQ-UI-EXPAND-BUTTON). Caption/enabled state are set on the first
// ExpansionCostChangedEvent; clicking requests an ExpandAsteroidCommand.
m_expandButton = new QPushButton(tr("Expand"), this);
layout->addWidget(m_expandButton);
connect(m_expandButton, &QPushButton::clicked, this, []() {
EventManager::getInstance()->sendEventImmediately(
std::make_shared<CommandRequestedEvent>(
std::make_shared<ExpandAsteroidCommand>()));
});
const char* labels[] = { "0x", "0.5x", "1x", "2x", "10x" };
QSignalMapper* mapper = new QSignalMapper(this);
for (int i = 0; i < kSpeedCount; ++i)
{
QPushButton* btn = new QPushButton(labels[i], this);
btn->setCheckable(true);
btn->setChecked(i == 2);
layout->addWidget(btn);
m_speedButtons.push_back(btn);
mapper->setMapping(btn, i);
connect(btn, &QPushButton::clicked, mapper, qOverload<>(&QSignalMapper::map));
}
connect(mapper, qOverload<int>(&QSignalMapper::mapped), this, &HeaderBar::onSpeedButton);
setFixedHeight(sizeHint().height());
registerForEvents();
}
HeaderBar::~HeaderBar()
{
unregisterForEvents();
}
void HeaderBar::handleEvent(std::shared_ptr<const TickAdvancedEvent> event)
{
const int totalSeconds = static_cast<int>(ticksToSeconds(event->tick));
m_timeLabel->setText(
QString("%1:%2")
.arg(totalSeconds / 60, 2, 10, QChar('0'))
.arg(totalSeconds % 60, 2, 10, QChar('0')));
}
void HeaderBar::handleEvent(std::shared_ptr<const BuildingBlocksChangedEvent> event)
{
m_blocks = event->blocks;
m_blocksLabel->setText(tr("Blocks: %1").arg(event->blocks));
updateExpandButton();
}
void HeaderBar::handleEvent(std::shared_ptr<const ExpansionCostChangedEvent> event)
{
m_expansionCost = event->cost;
updateExpandButton();
}
void HeaderBar::updateExpandButton()
{
m_expandButton->setText(tr("Expand: %1 Blocks").arg(m_expansionCost));
m_expandButton->setEnabled(m_blocks >= m_expansionCost);
}
void HeaderBar::handleEvent(std::shared_ptr<const GameSpeedChangedEvent> event)
{
for (int i = 0; i < kSpeedCount; ++i)
{
m_speedButtons[static_cast<std::size_t>(i)]->setChecked(
std::abs(kSpeeds[i] - event->speed) < 0.001);
}
}
void HeaderBar::handleEvent(std::shared_ptr<const BossWaveUpdatedEvent> event)
{
const int bossSeconds = static_cast<int>(
ticksToSeconds(event->countdownTicks > 0 ? event->countdownTicks : 0));
m_bossLabel->setText(
tr("Boss Wave #%1 Next boss: %2:%3")
.arg(event->counter)
.arg(bossSeconds / 60)
.arg(bossSeconds % 60, 2, 10, QChar('0')));
}
void HeaderBar::handleEvent(std::shared_ptr<const ArtifactCountChangedEvent> event)
{
m_artifactsLabel->setText(tr("Artifacts: %1/%2").arg(event->count).arg(event->winCount));
}
void HeaderBar::onSpeedButton(int index)
{
if (index >= 0 && index < kSpeedCount)
{
EventManager::getInstance()->sendEventImmediately(
std::make_shared<SpeedChangeRequestedEvent>(kSpeeds[index]));
}
}