Last active
July 28, 2021 22:22
-
-
Save michaliskambi/c86f73c0aa3d94de8a736557a1c41e7b to your computer and use it in GitHub Desktop.
Simple code detecting double-click in CGE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ 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