You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Graphik.drawButton (graphik.py:42-51) invokes its function argument from inside the draw call, guarded only by the mouse's current position and the current state of button 1:
mouse=pygame.mouse.get_pos()
if (xpos+width>mouse[0] >xposandypos+height>mouse[1] >ypos):
click=pygame.mouse.get_pressed()
ifclick[0] ==1:
function()
pygame.mouse.get_pressed() reports whether the button is currently held, not whether a press occurred since the last frame. Because drawButton is called once per frame from a render loop, holding the mouse over the button fires function() once per frame for as long as the button stays down — potentially hundreds of times for a single perceived click.
Scope
drawButton has no caller in this repository today; main.py uses only drawRectangle and drawText. The defect is therefore latent rather than currently observable, but Graphik is presented as a reusable rendering component (see #5, #11), so the first caller written against this method will hit it.
Related
The uncapped render loop tracked in #19 makes the repeat rate unbounded, so the two interact: with a frame cap in place a held click would fire at the cap rate, and without one it fires as fast as the machine can redraw.
Suggested resolution
Edge-detect the press rather than sampling the held state. Two options:
Track the previous frame's button state on the Graphik instance and fire only on the up -> down transition.
Move click handling out of the draw call entirely and drive it from pygame.MOUSEBUTTONDOWN events, which are already edge-triggered. This fits the event-handler registration surface proposed for RenderWindow in Create a RenderWindow class to manage Pygame initialization #6, and keeps drawButton purely a drawing operation.
The second option is the cleaner separation and is the one recommended here, though it changes the method's signature and so warrants a decision before implementation.
Acceptance criteria
A single press-and-hold over a button results in exactly one invocation of the callback.
The behavior is covered by a unit test under tests/ with pygame mocked, driving several frames with the button held.
Summary
Graphik.drawButton(graphik.py:42-51) invokes itsfunctionargument from inside the draw call, guarded only by the mouse's current position and the current state of button 1:pygame.mouse.get_pressed()reports whether the button is currently held, not whether a press occurred since the last frame. BecausedrawButtonis called once per frame from a render loop, holding the mouse over the button firesfunction()once per frame for as long as the button stays down — potentially hundreds of times for a single perceived click.Scope
drawButtonhas no caller in this repository today;main.pyuses onlydrawRectangleanddrawText. The defect is therefore latent rather than currently observable, butGraphikis presented as a reusable rendering component (see #5, #11), so the first caller written against this method will hit it.Related
The uncapped render loop tracked in #19 makes the repeat rate unbounded, so the two interact: with a frame cap in place a held click would fire at the cap rate, and without one it fires as fast as the machine can redraw.
Suggested resolution
Edge-detect the press rather than sampling the held state. Two options:
Graphikinstance and fire only on theup -> downtransition.pygame.MOUSEBUTTONDOWNevents, which are already edge-triggered. This fits the event-handler registration surface proposed forRenderWindowin Create aRenderWindowclass to manage Pygame initialization #6, and keepsdrawButtonpurely a drawing operation.The second option is the cleaner separation and is the one recommended here, though it changes the method's signature and so warrants a decision before implementation.
Acceptance criteria
tests/withpygamemocked, driving several frames with the button held.This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson