draw selection rect only if mouse has moved
This commit is contained in:
@@ -148,6 +148,7 @@ GameWorldView::GameWorldView(Simulation* sim, const GameConfig* config,
|
||||
, m_debugDraw(false)
|
||||
, m_rng(std::random_device{}())
|
||||
, m_boxSelecting(false)
|
||||
, m_boxDragMoved(false)
|
||||
, m_gameOverShown(false)
|
||||
, m_schematicChoiceShown(false)
|
||||
{
|
||||
@@ -300,6 +301,10 @@ void GameWorldView::onFrame()
|
||||
{
|
||||
m_boxCurrentTile =
|
||||
getCoordinates().widgetToTile(mapFromGlobal(QCursor::pos()));
|
||||
// The cursor has not travelled a pixel, so the drag threshold above never
|
||||
// trips; but the scroll has grown the box past the tile it started on,
|
||||
// which has to become visible.
|
||||
if (m_boxCurrentTile != m_boxStartTile) { m_boxDragMoved = true; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,8 +425,9 @@ void GameWorldView::paintGL()
|
||||
|
||||
WorldRenderFrame GameWorldView::makeRenderFrame() const
|
||||
{
|
||||
return WorldRenderFrame{m_selection, m_buildMode, m_activeBeams, m_boxSelecting,
|
||||
m_boxStartTile, m_boxCurrentTile, m_debugDraw};
|
||||
return WorldRenderFrame{m_selection, m_buildMode, m_activeBeams,
|
||||
m_boxSelecting, m_boxDragMoved, m_boxStartTile,
|
||||
m_boxCurrentTile, m_debugDraw};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1224,6 +1230,8 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
m_boxSelecting = true;
|
||||
m_boxStartTile = tile;
|
||||
m_boxCurrentTile = tile;
|
||||
m_boxStartPos = event->pos();
|
||||
m_boxDragMoved = false;
|
||||
break;
|
||||
|
||||
case ControlAction::Select:
|
||||
@@ -1238,6 +1246,8 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
m_boxSelecting = true;
|
||||
m_boxStartTile = tile;
|
||||
m_boxCurrentTile = tile;
|
||||
m_boxStartPos = event->pos();
|
||||
m_boxDragMoved = false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1349,6 +1359,14 @@ void GameWorldView::mouseMoveEvent(QMouseEvent* event)
|
||||
const QPoint tile = coordinates.widgetToTile(event->pos());
|
||||
m_cursorWorldPos = coordinates.widgetToWorld(event->pos());
|
||||
|
||||
// A press is a drag once the cursor has travelled far enough from it; below that
|
||||
// it stays a click and shows no rectangle (REQ-UI-MULTI-SELECT).
|
||||
if (m_boxSelecting
|
||||
&& (event->pos() - m_boxStartPos).manhattanLength() >= kBoxDragThresholdPixels)
|
||||
{
|
||||
m_boxDragMoved = true;
|
||||
}
|
||||
|
||||
if (m_buildMode.isBuilderMode())
|
||||
{
|
||||
m_buildMode.setGhostTile(tile);
|
||||
|
||||
@@ -260,6 +260,11 @@ private:
|
||||
// paused or slowed, instead of fading on wall-clock time (REQ-SHP-FIRING-BEAM).
|
||||
static constexpr Tick kBeamLifetimeTicks = secondsToTicks(0.3);
|
||||
|
||||
// How far the cursor must travel from the press position, in widget pixels
|
||||
// (Manhattan distance), before a box drag shows its rectangle
|
||||
// (REQ-UI-MULTI-SELECT).
|
||||
static constexpr int kBoxDragThresholdPixels = 2;
|
||||
|
||||
Simulation* m_sim;
|
||||
const GameConfig* m_config;
|
||||
const VisualsConfig* m_visuals;
|
||||
@@ -310,6 +315,15 @@ private:
|
||||
bool m_boxSelecting;
|
||||
QPoint m_boxStartTile;
|
||||
QPoint m_boxCurrentTile;
|
||||
// Where the button went down, in widget pixels; the origin the drag threshold
|
||||
// below measures from. Pixels, not tiles: the threshold separates a click from a
|
||||
// drag, which is a hand-steadiness question and not a tile-sized one.
|
||||
QPoint m_boxStartPos;
|
||||
// Whether the cursor has moved far enough from m_boxStartPos for this to read as
|
||||
// a drag. Until it has, the rectangle is not drawn (REQ-UI-MULTI-SELECT): a plain
|
||||
// click would otherwise flash a one-tile rectangle. Sticky for the rest of the
|
||||
// drag, so coming back to the press position does not hide the rectangle again.
|
||||
bool m_boxDragMoved;
|
||||
|
||||
// Interprets this widget's key events into semantic actions and publishes them
|
||||
// (REQ-UI-HOTKEYS). Owned here for now because this is the widget that holds
|
||||
|
||||
@@ -1019,8 +1019,9 @@ void WorldRenderer::drawOverlays(QPainter& painter, const WorldCoordinates& coor
|
||||
}
|
||||
}
|
||||
|
||||
// Box-select rectangle
|
||||
if (frame.isBoxSelecting)
|
||||
// Box-select rectangle. Not drawn until the drag has moved far enough to read as
|
||||
// one, so a plain click does not flash a rectangle (REQ-UI-MULTI-SELECT).
|
||||
if (frame.isBoxSelecting && frame.isBoxDragMoved)
|
||||
{
|
||||
const QPoint tl(std::min(frame.boxStartTile.x(), frame.boxCurrentTile.x()),
|
||||
std::min(frame.boxStartTile.y(), frame.boxCurrentTile.y()));
|
||||
|
||||
@@ -55,6 +55,9 @@ struct WorldRenderFrame
|
||||
const BuildModeController& buildMode;
|
||||
const std::vector<ActiveBeam>& beams;
|
||||
bool isBoxSelecting;
|
||||
// Whether that box drag has passed the movement threshold that tells it apart
|
||||
// from a click; until it has, the rectangle is not drawn (REQ-UI-MULTI-SELECT).
|
||||
bool isBoxDragMoved;
|
||||
QPoint boxStartTile;
|
||||
QPoint boxCurrentTile;
|
||||
bool isDebugDrawEnabled;
|
||||
|
||||
Reference in New Issue
Block a user