Skip to content

Instantly share code, notes, and snippets.

@michaliskambi
Last active July 28, 2021 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaliskambi/c86f73c0aa3d94de8a736557a1c41e7b to your computer and use it in GitHub Desktop.
Save michaliskambi/c86f73c0aa3d94de8a736557a1c41e7b to your computer and use it in GitHub Desktop.
Simple code detecting double-click in CGE
{ Sample that shows how to detect double-click in CGE.
Copy this code e.g. over CGE example
examples/user_interface/state_events/code/gamestatemain.pas
to test. }
{ Main state, where most of the application logic takes place. }
unit GameStateMain;
interface
uses Classes, Math,
CastleUIState, CastleComponentSerialize, CastleUIControls, CastleControls,
CastleKeysMouse, CastleVectors, CastleTimeUtils;
type
{ Main state, where most of the application logic takes place. }
TStateMain = class(TUIState)
private
HasLastMousePressPosition: Boolean;
LastMousePressPosition: TVector2;
LastMousePressTime: TTimerResult;
public
constructor Create(AOwner: TComponent); override;
procedure Start; override;
function Press(const Event: TInputPressRelease): Boolean; override;
procedure Update(const SecondsPassed: Single; var HandleInput: Boolean); override;
end;
var
StateMain: TStateMain;
implementation
uses SysUtils, CastleLog;
const
MaxDistanceForDoubleClick = 10;
MaxTimeForDoubleClick = 0.2;
{ TStateMain ----------------------------------------------------------------- }
constructor TStateMain.Create(AOwner: TComponent);
begin
inherited;
DesignUrl := 'castle-data:/gamestatemain.castle-user-interface';
end;
procedure TStateMain.Start;
begin
inherited;
HasLastMousePressPosition := false;
end;
function TStateMain.Press(const Event: TInputPressRelease): Boolean;
begin
Result := inherited;
if Result then Exit; // allow the ancestor to handle keys
if Event.IsMouseButton(buttonLeft) then
begin
if HasLastMousePressPosition and
(PointsDistance(Event.Position, LastMousePressPosition) < MaxDistanceForDoubleClick) and
(LastMousePressTime.ElapsedTime < MaxTimeForDoubleClick) then
begin
WritelnLog('Detected double-click!');
// Double-click handled, so forget about previous press event and do not store this press event.
HasLastMousePressPosition := false;
end else
begin
// Make single-click, if we have an unprocessed press event that wasn't double-click (because of too far distance).
if HasLastMousePressPosition then
WritelnLog('Detected single-click! (because next press too far)');
HasLastMousePressPosition := true;
LastMousePressPosition := Event.Position;
LastMousePressTime := Timer;
end;
Exit(true); // event was handled
end;
end;
procedure TStateMain.Update(const SecondsPassed: Single; var HandleInput: Boolean);
begin
inherited;
// Make single-click, if we have an unprocessed press event that cannot become double-click anymore.
if HasLastMousePressPosition and
(LastMousePressTime.ElapsedTime >= MaxTimeForDoubleClick) then
begin
WritelnLog('Detected single-click! (waiting too long for double click)');
// Single-click handled, so forget about previous press event and do not store this press event.
HasLastMousePressPosition := false;
end;
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment