/usr/src/castle-game-engine-5.0.0/window/castlewindowtouch.pas is in castle-game-engine-src 5.0.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | {
Copyright 2013-2014 Michalis Kamburelis.
This file is part of "Castle Game Engine".
"Castle Game Engine" is free software; see the file COPYING.txt,
included in this distribution, for details about the copyright.
"Castle Game Engine" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
}
{ Window with controls for easy navigation on touch interfaces. }
unit CastleWindowTouch;
interface
uses Classes, CastleWindow, CastleControls, CastleCameras;
type
TTouchCtlInterface = (etciNone, etciCtlWalkCtlRotate, etciCtlWalkDragRotate,
etciCtlFlyCtlWalkDragRotate, etciCtlPanXYDragRotate);
TCastleWindowTouch = class(TCastleWindow)
private
FAutomaticTouchInterface: boolean;
LeftTouchCtl, RightTouchCtl: TCastleTouchControl;
FTouchInterface: TTouchCtlInterface;
procedure UpdateTouchController(const LeftSide, CtlVisible: boolean;
const Mode: TCastleTouchCtlMode = ctcmWalking);
procedure SetTouchInterface(const Value: TTouchCtlInterface);
procedure SetAutomaticTouchInterface(const Value: boolean);
{ Sets touch controls depending on the current navigation mode.
Should be called each time after navigation mode changed. }
procedure UpdateAutomaticTouchInterface;
protected
procedure NavigationInfoChanged; override;
procedure DoUpdate; override;
public
{ Configure touch controls to be displayed on the window.
This automatically manages under the hood 0, 1 or 2
TCastleTouchControl instances, placing them at suitable positions
and handling their operations.
Note that you can set AutomaticTouchInterface = @true to have this property
automatically adjusted. (In which case you should not set this directly.) }
property TouchInterface: TTouchCtlInterface
read FTouchInterface write SetTouchInterface;
published
{ Automatically adjust TouchInterface (showing / hiding proper
touch controls) based on the current navigation type.
The navigation type is obtained from the camera of the default viewport,
see TCastleWindow.NavigationType. }
property AutomaticTouchInterface: boolean
read FAutomaticTouchInterface write SetAutomaticTouchInterface
default false;
end;
implementation
uses SysUtils, CastleUIControls, CastleUtils;
procedure TCastleWindowTouch.DoUpdate;
var
I: Integer;
C: TUIControl;
Tx, Ty, Tz, TLength, Rx, Ry, Rz, RAngle: Double;
begin
inherited;
if (LeftTouchCtl<>nil) or (RightTouchCtl<>nil) then
begin
Tx := 0; Ty := 0; Tz := 0; TLength := 0;
Rx := 0; Ry := 0; Rz := 0; RAngle := 0;
if LeftTouchCtl <> nil then
begin
LeftTouchCtl.GetSensorTranslation(Tx, Ty, Tz, TLength);
LeftTouchCtl.GetSensorRotation(Rx, Ry, Rz, RAngle);
end;
if RightTouchCtl <> nil then
begin
RightTouchCtl.GetSensorTranslation(Tx, Ty, Tz, TLength);
RightTouchCtl.GetSensorRotation(Rx, Ry, Rz, RAngle);
end;
{ send to all 2D controls, including viewports }
for I := 0 to Controls.Count - 1 do
begin
C := Controls[I];
if C.PositionInside(MousePosition) then
begin
C.SensorTranslation(Tx, Ty, Tz, TLength, Fps.UpdateSecondsPassed);
C.SensorRotation(Rx, Ry, Rz, RAngle, Fps.UpdateSecondsPassed);
end;
end;
end;
end;
procedure TCastleWindowTouch.UpdateTouchController(
const LeftSide, CtlVisible: boolean; const Mode: TCastleTouchCtlMode);
var
aNewCtl: TCastleTouchControl;
begin
// left controller
if LeftSide and (LeftTouchCtl<>nil) then
begin
if CtlVisible then
LeftTouchCtl.TouchMode := Mode else
FreeAndNil(LeftTouchCtl); // this automatically removes LeftTouchCtl from Controls list
Exit;
end;
// right controller
if (not LeftSide) and (RightTouchCtl<>nil) then
begin
if CtlVisible then
RightTouchCtl.TouchMode := Mode else
FreeAndNil(RightTouchCtl); // this automatically removes RightTouchCtl from Controls list
Exit;
end;
if not CtlVisible then Exit;
aNewCtl := TCastleTouchControl.Create(self);
aNewCtl.TouchMode := Mode;
if LeftSide then
aNewCtl.Position := tpLeft else
aNewCtl.Position := tpRight;
Controls.InsertFront(aNewCtl);
if LeftSide then
LeftTouchCtl := aNewCtl else
RightTouchCtl := aNewCtl;
end;
procedure TCastleWindowTouch.SetTouchInterface(const Value: TTouchCtlInterface);
var
WalkCamera: TWalkCamera;
begin
if FTouchInterface <> Value then
begin
FTouchInterface := Value;
WalkCamera := nil;
if SceneManager.Camera <> nil then
begin
if SceneManager.Camera is TUniversalCamera then
WalkCamera := (SceneManager.Camera as TUniversalCamera).Walk else
if SceneManager.Camera is TWalkCamera then
WalkCamera := SceneManager.Camera as TWalkCamera;
end;
if Value = etciCtlWalkCtlRotate then
begin
UpdateTouchController(true, true, ctcmWalking);
UpdateTouchController(false, true, ctcmHeadRotation);
if WalkCamera<>nil then
WalkCamera.MouseDragMode := cwdmNone;
end else
if Value = etciCtlWalkDragRotate then
begin
UpdateTouchController(true, false);
UpdateTouchController(false, true, ctcmWalking);
if WalkCamera<>nil then
WalkCamera.MouseDragMode := cwdmDragToRotate;
end else
if Value = etciCtlFlyCtlWalkDragRotate then
begin
UpdateTouchController(true, true, ctcmFlyUpdown);
UpdateTouchController(false, true, ctcmWalking);
if WalkCamera<>nil then
WalkCamera.MouseDragMode := cwdmDragToRotate;
end else
if Value = etciCtlPanXYDragRotate then
begin
UpdateTouchController(true, false);
UpdateTouchController(false, true, ctcmPanXY);
if WalkCamera<>nil then
WalkCamera.MouseDragMode := cwdmDragToRotate;
end else
begin
UpdateTouchController(true, false);
UpdateTouchController(false, false);
if WalkCamera <> nil then
WalkCamera.MouseDragMode := cwdmDragToWalk;
end;
end;
end;
procedure TCastleWindowTouch.UpdateAutomaticTouchInterface;
begin
if AutomaticTouchInterface then
begin
case NavigationType of
ntNone: TouchInterface := etciNone;
ntWalk: TouchInterface := etciCtlWalkDragRotate;
ntFly: TouchInterface := etciCtlFlyCtlWalkDragRotate;
ntExamine: TouchInterface := etciCtlPanXYDragRotate;
ntTurntable: TouchInterface := etciCtlPanXYDragRotate;
else raise EInternalError.Create('TCastleWindowTouch.UpdateAutomaticTouchInterface not implemented for this NavigationType value');
end;
end;
end;
procedure TCastleWindowTouch.SetAutomaticTouchInterface(const Value: boolean);
begin
if FAutomaticTouchInterface <> Value then
begin
FAutomaticTouchInterface := Value;
{ change NavigationType immediately, in case we just set
AutomaticTouchInterface := true }
UpdateAutomaticTouchInterface;
end;
end;
procedure TCastleWindowTouch.NavigationInfoChanged;
begin
inherited;
UpdateAutomaticTouchInterface;
end;
end.
|