resolve mouse gestures through the action table too
This commit is contained in:
@@ -74,6 +74,23 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
// The action a left-button gesture triggers, with the Ctrl variant falling back to the
|
||||
// plain one wherever nothing is bound to it. That fallback is what keeps Ctrl+click
|
||||
// placing a building in builder mode and Ctrl+drag deconstructing an area: the modifier
|
||||
// only means something where an action claims it (REQ-UI-CONTROLS-CONTENT).
|
||||
ControlAction resolveLeftGesture(bool controlHeld, bool isDrag,
|
||||
const ControlContext& context)
|
||||
{
|
||||
if (controlHeld)
|
||||
{
|
||||
const ControlAction action = resolveMouseAction(
|
||||
isDrag ? MouseBinding::CtrlLeftDrag : MouseBinding::CtrlLeftClick, context);
|
||||
if (action != ControlAction::None) { return action; }
|
||||
}
|
||||
return resolveMouseAction(isDrag ? MouseBinding::LeftDrag : MouseBinding::LeftClick,
|
||||
context);
|
||||
}
|
||||
|
||||
// Keep only the filter entries whose item type is currently unlocked
|
||||
// (REQ-LOCK-UI-BLUEPRINT). An empty result means "accept all".
|
||||
std::vector<ItemType> filterUnlockedItems(const std::vector<ItemType>& filter,
|
||||
@@ -1142,33 +1159,47 @@ ControlContext GameWorldView::getControlContext() const
|
||||
void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
const WorldCoordinates coordinates = getCoordinates();
|
||||
const ControlContext context = getControlContext();
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
{
|
||||
if (event->button() == Qt::RightButton)
|
||||
{
|
||||
if (m_buildMode.isBuilderMode() && m_buildMode.isDraggingBelt())
|
||||
switch (resolveMouseAction(MouseBinding::RightClick, context))
|
||||
{
|
||||
// Cancel the in-progress belt drag without placing anything;
|
||||
// stay in belt builder mode (REQ-BLD-BELT-DRAG).
|
||||
case ControlAction::CancelBeltLine:
|
||||
// Drop the in-progress path without placing anything; belt builder
|
||||
// mode stays active (REQ-BLD-BELT-DRAG).
|
||||
m_buildMode.cancelBeltDrag();
|
||||
}
|
||||
else if (m_buildMode.getMode() != BuildMode::None)
|
||||
{
|
||||
break;
|
||||
case ControlAction::ExitMode:
|
||||
m_buildMode.exitCurrentMode();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const QPoint tile = coordinates.widgetToTile(event->pos());
|
||||
const bool controlHeld = (event->modifiers() & Qt::ControlModifier) != 0;
|
||||
|
||||
if (m_buildMode.isBuilderMode())
|
||||
// A press begins the click gesture; whether it turns out to be a drag is settled on
|
||||
// release, where the drag binding is resolved instead.
|
||||
switch (resolveLeftGesture(controlHeld, /*isDrag*/ false, context))
|
||||
{
|
||||
if (m_buildMode.getBuilderType() == BuildingType::Belt)
|
||||
case ControlAction::Place:
|
||||
case ControlAction::ApplySettings:
|
||||
if (m_buildMode.isBlueprintMode())
|
||||
{
|
||||
// Deferred placement: start the drag and show the path ghost; nothing
|
||||
// is placed until release (REQ-BLD-BELT-DRAG).
|
||||
placeBlueprintAtTile(tile);
|
||||
}
|
||||
else if (m_buildMode.getBuilderType() == BuildingType::Belt)
|
||||
{
|
||||
// Belts place by dragging, so the press only anchors the path and shows its
|
||||
// ghost; nothing is placed until release, and a plain click is the one-tile
|
||||
// case (REQ-BLD-BELT-DRAG).
|
||||
m_buildMode.beginBeltDrag(tile);
|
||||
m_cursorWorldPos = coordinates.widgetToWorld(event->pos());
|
||||
recomputeBeltDragPath(tile);
|
||||
@@ -1177,27 +1208,22 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
placeAtTile(tile);
|
||||
}
|
||||
}
|
||||
else if (m_buildMode.isBlueprintMode())
|
||||
{
|
||||
placeBlueprintAtTile(tile);
|
||||
}
|
||||
else if (m_buildMode.isDeconstructMode())
|
||||
{
|
||||
break;
|
||||
|
||||
case ControlAction::ToggleDeconstruct:
|
||||
// Start a deconstruct box drag; a plain click resolves as a 1x1 box on
|
||||
// release (REQ-BLD-DECONSTRUCT-CLICK, REQ-BLD-DECONSTRUCT-BOX).
|
||||
m_boxSelecting = true;
|
||||
m_boxStartTile = tile;
|
||||
m_boxCurrentTile = tile;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool ctrl = (event->modifiers() & Qt::ControlModifier) != 0;
|
||||
break;
|
||||
|
||||
case ControlAction::Select:
|
||||
case ControlAction::AddToSelection:
|
||||
// Only a click that hit nothing starts a box drag. Starting one on a hit
|
||||
// would re-resolve the same object as a 1x1 box on release and undo the
|
||||
// click: a Ctrl+click would toggle the building off, then straight back on.
|
||||
if (!selectAtPoint(tile, coordinates.widgetToWorld(event->pos()), ctrl))
|
||||
if (!selectAtPoint(tile, coordinates.widgetToWorld(event->pos()), controlHeld))
|
||||
{
|
||||
// selectAtPoint has already cleared the selection unless Ctrl is
|
||||
// preserving it for an additive drag.
|
||||
@@ -1205,6 +1231,10 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
m_boxStartTile = tile;
|
||||
m_boxCurrentTile = tile;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1347,7 +1377,11 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
const std::vector<BuildingId> boxIds =
|
||||
buildingsInBox(m_sim->getFactoryState(), m_boxStartTile, m_boxCurrentTile);
|
||||
|
||||
if (m_buildMode.isDeconstructMode())
|
||||
const bool controlHeld = (event->modifiers() & Qt::ControlModifier) != 0;
|
||||
const ControlAction dragAction =
|
||||
resolveLeftGesture(controlHeld, /*isDrag*/ true, getControlContext());
|
||||
|
||||
if (dragAction == ControlAction::DeconstructArea)
|
||||
{
|
||||
const FactoryState& factory = m_sim->getFactoryState();
|
||||
|
||||
@@ -1409,7 +1443,9 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
selectInBox((event->modifiers() & Qt::ControlModifier) != 0);
|
||||
// A Ctrl box adds and never deselects, where a plain one replaces
|
||||
// (REQ-UI-MULTI-SELECT).
|
||||
selectInBox(dragAction == ControlAction::AddAreaToSelection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user