The button leaves the header bar for the world, centered on the columns the next purchase unlocks and panning with them until it leaves the view. Those columns now take a lighter tint than the locked ground behind them, so the boundary between the two says how far one purchase reaches. Nothing in the code reported a scroll: the camera knew it had moved and told only the hover. A ViewScrolledEvent says it now, which is what a widget keeping a place in the world rather than on the screen needs. The panels want none of it -- they are placed against the screen and stay put as the world moves under them -- so the button is placed after their pass and never joins the rectangles they step around. Its face is two lines, "Expand" over the cost. That makes the cost a display of its own, so it carries the building-block tooltip the way every other item value does, on hover alone since the click buys the expansion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
100 lines
3.4 KiB
C++
100 lines
3.4 KiB
C++
#include "ExpandButton.h"
|
|
|
|
#include <QLabel>
|
|
#include <QPalette>
|
|
#include <QPixmap>
|
|
#include <QVBoxLayout>
|
|
|
|
#include "Command.h"
|
|
#include "CommandRequestedEvent.h"
|
|
#include "EventManager.h"
|
|
#include "FloatingLayoutInvalidatedEvent.h"
|
|
#include "IconCaption.h"
|
|
#include "ItemIconCache.h"
|
|
#include "ItemTooltip.h"
|
|
#include "Simulation.h"
|
|
#include "TooltipTrigger.h"
|
|
|
|
ExpandButton::ExpandButton(const ItemTooltipContext& context, QWidget* parent)
|
|
: OptionButton(parent)
|
|
, m_context(context)
|
|
{
|
|
QVBoxLayout* face = new QVBoxLayout(this);
|
|
face->setContentsMargins(8, 4, 8, 4);
|
|
face->setSpacing(1);
|
|
|
|
// Names the action, not an item, so it says nothing of its own and stays out of the
|
|
// mouse's way -- a click anywhere on the face reaches the button beneath it.
|
|
QLabel* actionLabel = new QLabel(tr("Expand"), this);
|
|
actionLabel->setAlignment(Qt::AlignCenter);
|
|
actionLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
|
face->addWidget(actionLabel);
|
|
|
|
// The cost line, deliberately not transparent to the mouse: it names an item and has
|
|
// to be hoverable to explain it. Hover only, the click being the button's
|
|
// (REQ-UI-ITEM-VALUE-TOOLTIP). A label ignores presses, so they still reach the
|
|
// button.
|
|
m_costLabel = new QLabel(this);
|
|
m_costLabel->setAlignment(Qt::AlignCenter);
|
|
face->addWidget(m_costLabel);
|
|
ItemTooltip::attachTo(*m_costLabel, m_context, kBlockItemId,
|
|
TooltipTrigger::Trigger::HoverOnly);
|
|
|
|
// Carries no payload: the simulation derives the cost and the column count from its
|
|
// own expansion counter (REQ-EXP-UNLOCK, REQ-GW-ASTEROID-EXPAND).
|
|
connect(this, &QPushButton::clicked, this, []() {
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<CommandRequestedEvent>(
|
|
std::make_shared<ExpandAsteroidCommand>()));
|
|
});
|
|
|
|
refresh();
|
|
registerForEvents();
|
|
}
|
|
|
|
ExpandButton::~ExpandButton()
|
|
{
|
|
unregisterForEvents();
|
|
}
|
|
|
|
void ExpandButton::handleEvent(std::shared_ptr<const ExpansionCostChangedEvent> /*event*/)
|
|
{
|
|
refresh();
|
|
}
|
|
|
|
void ExpandButton::handleEvent(std::shared_ptr<const BuildingBlocksChangedEvent> /*event*/)
|
|
{
|
|
refresh();
|
|
}
|
|
|
|
void ExpandButton::refresh()
|
|
{
|
|
const int blocks = m_context.sim->getBuildingBlocksStock();
|
|
const int expansionCost = m_context.sim->getCurrentExpansionCost();
|
|
|
|
setEnabled(blocks >= expansionCost);
|
|
|
|
// The cost reads as it does everywhere else: the number, then the block icon in place
|
|
// of a trailing `Blocks` word (REQ-UI-BLOCKS-ICON, REQ-UI-ITEM-ICON). With no icon
|
|
// file the word comes back, since nothing else on the line would name the item.
|
|
const QPixmap icon = m_context.itemIcons->getInlineIcon(kBlockItemId, font());
|
|
if (icon.isNull())
|
|
{
|
|
m_costLabel->setPixmap(QPixmap());
|
|
m_costLabel->setText(tr("%1 Blocks").arg(expansionCost));
|
|
}
|
|
else
|
|
{
|
|
m_costLabel->setText(QString());
|
|
m_costLabel->setPixmap(renderCaptionWithIcon(
|
|
QString::number(expansionCost), icon, font(),
|
|
palette().color(isEnabled() ? QPalette::Active : QPalette::Disabled,
|
|
QPalette::ButtonText)));
|
|
}
|
|
|
|
// A cost of a different width re-centers the button on its columns, which is the
|
|
// owner's to do (ui/FloatingPanel.h, MainWindow::placeExpandButton).
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<FloatingLayoutInvalidatedEvent>());
|
|
}
|