1/*
2 * Copyright (c) 2022-2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { CanvasInput } from '../hcs/CanvasInput.js';
17import { X2DFast } from './graphics/X2DFast.js';
18import { Scr } from './XDefine.js';
19import { XTools } from './XTools.js';
20
21export var gl;
22var Mouse = {
23  MOUSE_LEFT: 0,
24  MOUSE_RILLER: 1,
25  MOUSE_RIGHT: 2,
26};
27
28var MouseEvent = {
29  LEFT_CLICK: 1,
30  LEFT_MOVE: 2,
31  LEFT_RELEASE: 3,
32  RIGHT_CLICK: 4,
33  RIGHT_MOVE: 5,
34  RIGHT_RELEASE: 6,
35};
36
37function touchStart(e) {
38  document.addEventListener('contextmenu', function (e) {
39    e.preventDefault();
40  });
41  e.preventDefault();
42  GLFrame.pinstance_.callbackProctouch(
43    MouseEvent.LEFT_CLICK,
44    e.touches[0].clientX,
45    e.touches[0].clientY
46  );
47}
48function touchMove(e) {
49  e.preventDefault();
50  GLFrame.pinstance_.callbackProctouch(
51    MouseEvent.LEFT_MOVE,
52    e.touches[0].clientX,
53    e.touches[0].clientY
54  );
55}
56function touchEnd(e) {
57  e.preventDefault();
58  GLFrame.pinstance_.callbackProctouch(
59    MouseEvent.LEFT_RELEASE,
60    e.changedTouches[0].clientX,
61    e.changedTouches[0].clientY
62  );
63}
64
65function mouseDown(e) {
66  e.preventDefault();
67  switch (e.button) {
68    case Mouse.MOUSE_LEFT:
69      GLFrame.pinstance_.callbackProctouch(
70        MouseEvent.LEFT_CLICK,
71        e.offsetX,
72        e.offsetY
73      );
74      break;
75    case Mouse.MOUSE_RIGHT:
76      GLFrame.pinstance_.callbackProctouch(
77        MouseEvent.RIGHT_CLICK,
78        e.offsetX,
79        e.offsetY
80      );
81      break;
82  }
83}
84function mouseMove(e) {
85  e.preventDefault();
86  GLFrame.pinstance_.callbackProctouch(
87    MouseEvent.LEFT_MOVE,
88    e.offsetX,
89    e.offsetY
90  );
91}
92function mouseUp(e) {
93  e.preventDefault();
94  switch (e.button) {
95    case Mouse.MOUSE_LEFT:
96      GLFrame.pinstance_.callbackProctouch(
97        MouseEvent.LEFT_RELEASE,
98        e.offsetX,
99        e.offsetY
100      );
101      break;
102    case Mouse.MOUSE_RIGHT:
103      GLFrame.pinstance_.callbackProctouch(
104        MouseEvent.RIGHT_RELEASE,
105        e.offsetX,
106        e.offsetY
107      );
108      break;
109  }
110}
111
112function keyDown(e) {
113  let ret = '';
114  if (e.ctrlKey) {
115    if (ret.length > 0) {
116      ret += '+';
117    }
118    ret += 'ctrl';
119  }
120  if (e.shiftKey) {
121    if (ret.length > 0) {
122      ret += '+';
123    }
124    ret += 'shift';
125  }
126  if (e.altKey) {
127    if (ret.length > 0) {
128      ret += '+';
129    }
130    ret += 'alt';
131  }
132  if (ret.length > 0) {
133    ret += '+';
134  }
135  ret += e.key;
136  GLFrame.pinstance_.callbackKey(1, ret);
137  if (!CanvasInput.FOCUS) {
138  }
139  if (ret === 'ctrl+z') {
140    e.preventDefault();
141  }
142}
143
144function mainLoop() {
145  GLFrame.pinstance_.callbackDraw();
146  window.requestAnimationFrame(mainLoop);
147}
148
149export class GLFrame {
150  static gi() {
151    return GLFrame.pinstance_;
152  }
153  constructor() {}
154
155  go(cvs, _draw = null, _touch = null, _key = null, _logic = null) {
156    gl = cvs.getContext('webgl', { premultipliedAlpha: false });
157
158    this.pCallbackDraw = _draw;
159    this.pCallbackTouch = _touch;
160    this.pCallbackKey = _key;
161    this.pCallbackLogic = _logic;
162
163    cvs.addEventListener('touchstart', touchStart);
164    cvs.addEventListener('touchmove', touchMove);
165    cvs.addEventListener('touchend', touchEnd);
166
167    cvs.addEventListener('mousedown', mouseDown);
168    cvs.addEventListener('mousemove', mouseMove);
169    cvs.addEventListener('mouseup', mouseUp);
170
171    document.addEventListener('contextmenu', function (e) {
172      e.preventDefault();
173    });
174
175    window.addEventListener('keydown', keyDown);
176    window.requestAnimationFrame(mainLoop);
177  }
178  callbackKey(type, code) {
179    if (this.pCallbackKey !== null) {
180      this.pCallbackKey(type, code);
181    }
182  }
183  callbackDraw() {
184    gl.clearColor(0.0, 0.0, 0.0, 1.0);
185    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
186
187    if (this.pCallbackDraw !== null) {
188      this.pCallbackDraw();
189    }
190  }
191  callbackProctouch(msg, x, y) {
192    XTools.MOUSE_POS.x = x;
193    XTools.MOUSE_POS.y = y;
194    if (msg === 1) {
195      CanvasInput.Hide(x, y);
196    }
197    if (this.pCallbackTouch !== null) {
198      x = (x * Scr.logicw) / Scr.width;
199      y = (y * Scr.logich) / Scr.height;
200      this.pCallbackTouch(msg, x, y);
201    }
202  }
203  resize() {
204    gl.viewport(0, 0, Scr.logicw, Scr.logich);
205    X2DFast.gi().resetMat();
206  }
207}
208
209GLFrame.pinstance_ = new GLFrame();
210