drgame-cc 1.0.45 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/drres/focus/focus_1/gesture.atlas +34 -0
- package/drres/focus/focus_1/gesture.atlas.meta +6 -0
- package/drres/focus/focus_1/gesture.json +1 -0
- package/drres/focus/focus_1/gesture.json.meta +10 -0
- package/drres/focus/focus_1/gesture.png +0 -0
- package/drres/{icons/pointer-yellow-60.png.meta → focus/focus_1/gesture.png.meta} +14 -14
- package/drres/focus/focus_1.meta +13 -0
- package/drres/focus/focus_2/gesture.atlas +41 -0
- package/drres/focus/focus_2/gesture.atlas.meta +6 -0
- package/drres/focus/focus_2/gesture.json +1 -0
- package/drres/focus/focus_2/gesture.json.meta +10 -0
- package/drres/focus/focus_2/gesture.png +0 -0
- package/drres/{icons/pointer-blue-60.png.meta → focus/focus_2/gesture.png.meta} +13 -13
- package/drres/focus/focus_2.meta +13 -0
- package/drres/focus/focus_3/gesture.atlas +34 -0
- package/drres/focus/focus_3/gesture.atlas.meta +6 -0
- package/drres/focus/focus_3/gesture.json +1 -0
- package/drres/focus/focus_3/gesture.json.meta +10 -0
- package/drres/focus/focus_3/gesture.png +0 -0
- package/drres/{icons/pointer-pink-60.png.meta → focus/focus_3/gesture.png.meta} +12 -12
- package/drres/focus/focus_3.meta +13 -0
- package/drres/focus/focus_4/gesture.atlas +20 -0
- package/drres/focus/focus_4/gesture.atlas.meta +6 -0
- package/drres/focus/focus_4/gesture.json +1 -0
- package/drres/focus/focus_4/gesture.json.meta +10 -0
- package/drres/focus/focus_4/gesture.png +0 -0
- package/drres/focus/focus_4/gesture.png.meta +38 -0
- package/drres/focus/focus_4.meta +13 -0
- package/drres/focus.meta +13 -0
- package/drres/prefab/ExitWin.prefab +2 -2
- package/drres/prefab/Toast.prefab +378 -378
- package/drscript/{ad/AdManager.ts.meta → BtnExtra.ts.meta} +1 -1
- package/drscript/Define.ts +17 -2
- package/drscript/{ad/AdSlot.ts.meta → Define.ts.meta} +1 -1
- package/drscript/{ad/AggregateAdProvider.ts.meta → ExitWin.ts.meta} +1 -1
- package/drscript/GameAnalytics.ts +37 -118
- package/drscript/{ad/IAdProvider.ts.meta → GameAnalytics.ts.meta} +1 -1
- package/drscript/HelperWin.ts.meta +10 -0
- package/drscript/Info.ts.meta +10 -0
- package/drscript/InternalUitl.ts.meta +10 -0
- package/drscript/KeyAdapter.ts +133 -0
- package/drscript/KeyAdapter.ts.meta +10 -0
- package/drscript/Loader.ts.meta +10 -0
- package/drscript/PlatformAdapter.ts +178 -192
- package/drscript/PlatformAdapter.ts.meta +10 -0
- package/drscript/README.md +91 -805
- package/drscript/README.md.meta +6 -0
- package/drscript/UIAdapter.ts +324 -0
- package/drscript/UIAdapter.ts.meta +10 -0
- package/drscript/WebBridge.ts +1 -1
- package/drscript/WebBridge.ts.meta +10 -0
- package/drscript/ad-sdk/reporters/superset-lewo.js +6 -0
- package/drscript/ad-sdk/types/enums.d.ts +1 -0
- package/drscript/ad-sdk.meta +13 -0
- package/drscript/ad.meta +13 -0
- package/drscript/component/AlertTip.ts +25 -0
- package/drscript/component/AlertTip.ts.meta +10 -0
- package/drscript/component/BtnExtra.ts +17 -0
- package/drscript/component/BtnExtra.ts.meta +10 -0
- package/drscript/{ExitWin.ts → component/ExitWin.ts} +6 -8
- package/drscript/component/ExitWin.ts.meta +10 -0
- package/drscript/{HelperWin.ts → component/HelperWin.ts} +5 -19
- package/drscript/component/HelperWin.ts.meta +10 -0
- package/drscript/component.meta +13 -0
- package/drscript/config.meta +13 -0
- package/drscript/core.meta +13 -0
- package/drscript/focus/FocusItem.ts +1 -19
- package/drscript/focus/FocusManager.ts +132 -170
- package/drscript/focus/FocusVisualLayer.ts +74 -163
- package/drscript/focus.meta +13 -0
- package/drscript/input/KeyboardMove.ts +40 -11
- package/drscript/input/KeyboardMove.ts.meta +10 -0
- package/drscript/input.meta +13 -0
- package/drscript/interface.meta +13 -0
- package/drscript/pinyin.meta +13 -0
- package/drscript/toast.meta +13 -0
- package/drscript/virtualgamepad.meta +13 -0
- package/package.json +1 -1
- package/drres/config/default.json +0 -108
- package/drres/config/default.json.meta +0 -6
- package/drres/icons/pointer-blue-60.png +0 -0
- package/drres/icons/pointer-pink-60.png +0 -0
- package/drres/icons/pointer-white-60.png +0 -0
- package/drres/icons/pointer-yellow-60.png +0 -0
- package/drscript/Info.ts +0 -78
- package/drscript/InternalUitl.ts +0 -65
- package/drscript/ad/AdManager.ts +0 -174
- package/drscript/ad/AdSlot.ts +0 -44
- package/drscript/ad/AggregateAdProvider.ts +0 -149
- package/drscript/ad/IAdProvider.ts +0 -39
- package/drscript/ad/MockAdProvider.ts +0 -36
- package/drscript/ad/MockAdProvider.ts.meta +0 -10
- package/drscript/ad/SelfAdProvider.ts +0 -41
- package/drscript/ad/SelfAdProvider.ts.meta +0 -10
- package/drscript/config/TvUiConfig.ts +0 -155
- package/drscript/config/TvUiConfig.ts.meta +0 -10
- package/drscript/config/TvUiConfigManager.ts +0 -133
- package/drscript/config/TvUiConfigManager.ts.meta +0 -10
- package/drscript/core/BackManager.ts +0 -38
- package/drscript/core/BackManager.ts.meta +0 -10
- package/drscript/core/NativeBridge.ts +0 -137
- package/drscript/core/NativeBridge.ts.meta +0 -10
- package/drscript/core/TvUi.ts +0 -69
- package/drscript/core/TvUi.ts.meta +0 -10
- package/drscript/core/TvUiRoot.ts +0 -137
- package/drscript/core/TvUiRoot.ts.meta +0 -10
- package/drscript/icon/IconConfig.ts +0 -7
- package/drscript/icon/IconConfig.ts.meta +0 -10
- package/drscript/icon/IconManager.ts +0 -97
- package/drscript/icon/IconManager.ts.meta +0 -10
- package/drscript/input/KeyCodeAdapter.ts +0 -23
- package/drscript/input/RemoteInputManager.ts +0 -105
- package/drscript/interface/ILobbyBridge.ts +0 -5
- package/drscript/toast/ToastComponent.ts +0 -35
- package/drscript/toast/ToastComponent.ts.meta +0 -10
- package/drscript/toast/ToastManager.ts +0 -66
- package/drscript/toast/ToastManager.ts.meta +0 -10
- package/drscript/toast/TvExitConfirmDialog.ts +0 -334
- package/drscript/toast/TvExitConfirmDialog.ts.meta +0 -10
- package/drscript/toast/UIFunctions.ts +0 -150
- package/drscript/toast/UIFunctions.ts.meta +0 -10
|
@@ -1,116 +1,73 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import KeyCodeAdapter, { TvRemoteKey } from "../input/KeyCodeAdapter";
|
|
3
|
-
import FocusScope from "./FocusScope";
|
|
4
|
-
|
|
5
|
-
export interface FocusOptions {
|
|
6
|
-
root?: cc.Node;
|
|
7
|
-
scopeId?: string;
|
|
8
|
-
focusId?: string;
|
|
9
|
-
iconKey?: string;
|
|
10
|
-
up?: string;
|
|
11
|
-
down?: string;
|
|
12
|
-
left?: string;
|
|
13
|
-
right?: string;
|
|
14
|
-
onClick?: Function;
|
|
15
|
-
onFocus?: Function;
|
|
16
|
-
onBlur?: Function;
|
|
17
|
-
focusScale?: number;
|
|
18
|
-
showCursor?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface FocusCursorOptions {
|
|
22
|
-
basePath?: string;
|
|
23
|
-
normalPath?: string;
|
|
24
|
-
focusPath?: string;
|
|
25
|
-
corner?: string;
|
|
26
|
-
width?: number;
|
|
27
|
-
height?: number;
|
|
28
|
-
offsetX?: number;
|
|
29
|
-
offsetY?: number;
|
|
30
|
-
}
|
|
1
|
+
import { KeyCode } from "../ad-sdk/ad-sdk";
|
|
31
2
|
|
|
32
3
|
export interface FocusRuntimeItem {
|
|
33
4
|
node: cc.Node;
|
|
34
|
-
root?: cc.Node;
|
|
35
|
-
scopeId: string;
|
|
36
|
-
focusId: string;
|
|
37
|
-
iconKey?: string;
|
|
38
|
-
up?: string;
|
|
39
|
-
down?: string;
|
|
40
|
-
left?: string;
|
|
41
|
-
right?: string;
|
|
42
|
-
onClick?: Function;
|
|
43
5
|
onFocus?: Function;
|
|
44
6
|
onBlur?: Function;
|
|
45
|
-
|
|
46
|
-
baseScaleX: number;
|
|
47
|
-
baseScaleY: number;
|
|
7
|
+
onClick?: Function;
|
|
48
8
|
focusScale: number;
|
|
49
9
|
showCursor: boolean;
|
|
10
|
+
offset: cc.Vec2;
|
|
50
11
|
}
|
|
51
12
|
|
|
52
13
|
type FocusListener = (item: FocusRuntimeItem | null, previous?: FocusRuntimeItem | null) => void;
|
|
53
14
|
|
|
15
|
+
interface ScopeInfo {
|
|
16
|
+
scopeId: string;
|
|
17
|
+
lastNodeUuid: string;
|
|
18
|
+
/** 绑定的窗口/场景节点(用于返回键自动处理) */
|
|
19
|
+
node?: cc.Node;
|
|
20
|
+
/** 节点类型 */
|
|
21
|
+
nodeType?: "window" | "scene";
|
|
22
|
+
/** 自定义返回回调 */
|
|
23
|
+
onBack?: () => boolean | void;
|
|
24
|
+
}
|
|
25
|
+
|
|
54
26
|
export default class FocusManager {
|
|
55
27
|
private static readonly FOCUS_SCALE_ACTION_TAG: number = 9911;
|
|
56
28
|
private static readonly BASE_SCALE_X_KEY: string = "__tvFocusBaseScaleX";
|
|
57
29
|
private static readonly BASE_SCALE_Y_KEY: string = "__tvFocusBaseScaleY";
|
|
58
30
|
private static items: FocusRuntimeItem[] = [];
|
|
59
|
-
private static itemMap: { [
|
|
60
|
-
private static
|
|
61
|
-
private static
|
|
31
|
+
private static itemMap: { [uuid: string]: FocusRuntimeItem } = {};
|
|
32
|
+
private static scopeMap: { [uuid: string]: string } = {};
|
|
33
|
+
private static currentNodeUuid: string = "";
|
|
34
|
+
private static scopes: ScopeInfo[] = [{ scopeId: "page", lastNodeUuid: "" }];
|
|
62
35
|
private static activeScopeId: string = "page";
|
|
63
36
|
private static listeners: FocusListener[] = [];
|
|
64
|
-
private static cursorOptions: FocusCursorOptions | null = null;
|
|
65
37
|
|
|
66
|
-
|
|
67
|
-
this.cursorOptions = options;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public static getCursor(): FocusCursorOptions | null {
|
|
71
|
-
return this.cursorOptions;
|
|
72
|
-
}
|
|
38
|
+
private static readonly DEFAULT_FOCUS_SCALE = 1.08;
|
|
73
39
|
|
|
74
|
-
public static register(target: cc.Node | any, options:
|
|
40
|
+
public static register(target: cc.Node | any, options: { scopeId?: string; onFocus?: Function; onBlur?: Function; onClick?: Function; focusScale?: number; showCursor?: boolean; offset?: cc.Vec2 } = {}): void {
|
|
75
41
|
let node = this.resolveNode(target);
|
|
76
42
|
if (!node) return;
|
|
77
43
|
let component = this.resolveComponent(target, node);
|
|
78
|
-
let previousItem = this.findItemByNode(node);
|
|
79
|
-
let previousBaseScale = previousItem ? { x: previousItem.baseScaleX, y: previousItem.baseScaleY } : null;
|
|
80
44
|
this.unregister(node);
|
|
81
45
|
|
|
82
|
-
let
|
|
83
|
-
this.
|
|
84
|
-
|
|
46
|
+
let uuid = node.uuid;
|
|
47
|
+
this.getNodeBaseScale(node);
|
|
48
|
+
|
|
49
|
+
let scopeId = options.scopeId || (component && component.scopeId) || this.activeScopeId || "page";
|
|
50
|
+
this.scopeMap[uuid] = scopeId;
|
|
85
51
|
|
|
86
52
|
let item: FocusRuntimeItem = {
|
|
87
53
|
node: node,
|
|
88
|
-
root: options.root,
|
|
89
|
-
scopeId: options.scopeId || (component && component.scopeId) || this.activeScopeId || "page",
|
|
90
|
-
focusId: focusId,
|
|
91
|
-
iconKey: options.iconKey || (component && component.iconKey) || "",
|
|
92
|
-
up: options.up || (component && component.up) || "",
|
|
93
|
-
down: options.down || (component && component.down) || "",
|
|
94
|
-
left: options.left || (component && component.left) || "",
|
|
95
|
-
right: options.right || (component && component.right) || "",
|
|
96
|
-
onClick: options.onClick,
|
|
97
54
|
onFocus: options.onFocus || (component && component.onFocus),
|
|
98
55
|
onBlur: options.onBlur || (component && component.onBlur),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
showCursor: options.showCursor !== false
|
|
56
|
+
onClick: options.onClick,
|
|
57
|
+
focusScale: options.focusScale || (component && component.focusScale) || this.DEFAULT_FOCUS_SCALE,
|
|
58
|
+
showCursor: options.showCursor !== false,
|
|
59
|
+
offset: options.offset || cc.v2(0, 0)
|
|
104
60
|
};
|
|
105
61
|
|
|
106
62
|
this.items.push(item);
|
|
107
|
-
this.itemMap[
|
|
63
|
+
this.itemMap[uuid] = item;
|
|
108
64
|
this.ensureFocus();
|
|
109
65
|
}
|
|
110
66
|
|
|
111
67
|
public static unregister(target: cc.Node | any) {
|
|
112
68
|
let node = this.resolveNode(target);
|
|
113
69
|
if (!node) return;
|
|
70
|
+
delete this.scopeMap[node.uuid];
|
|
114
71
|
for (let i = this.items.length - 1; i >= 0; i--) {
|
|
115
72
|
if (this.items[i].node == node) {
|
|
116
73
|
this.removeItemAt(i);
|
|
@@ -123,21 +80,25 @@ export default class FocusManager {
|
|
|
123
80
|
if (!root) return;
|
|
124
81
|
for (let i = this.items.length - 1; i >= 0; i--) {
|
|
125
82
|
let item = this.items[i];
|
|
126
|
-
if (
|
|
83
|
+
if (this.isChildOf(item.node, root)) {
|
|
84
|
+
delete this.scopeMap[item.node.uuid];
|
|
127
85
|
this.removeItemAt(i);
|
|
128
86
|
}
|
|
129
87
|
}
|
|
130
88
|
this.ensureFocus();
|
|
131
89
|
}
|
|
132
90
|
|
|
133
|
-
|
|
134
|
-
if (!
|
|
91
|
+
private static unregisterByUuid(uuid: string) {
|
|
92
|
+
if (!uuid) return;
|
|
135
93
|
for (let i = this.items.length - 1; i >= 0; i--) {
|
|
136
|
-
if (this.items[i].
|
|
94
|
+
if (this.items[i].node.uuid == uuid) {
|
|
95
|
+
delete this.scopeMap[uuid];
|
|
96
|
+
this.removeItemAt(i);
|
|
97
|
+
}
|
|
137
98
|
}
|
|
138
99
|
}
|
|
139
100
|
|
|
140
|
-
public static registerButtons(root: cc.Node
|
|
101
|
+
public static registerButtons(root: cc.Node) {
|
|
141
102
|
if (!root) return;
|
|
142
103
|
this.unregisterByRoot(root);
|
|
143
104
|
this.walk(root, (node: cc.Node) => {
|
|
@@ -145,31 +106,36 @@ export default class FocusManager {
|
|
|
145
106
|
let button = node.getComponent(cc.Button);
|
|
146
107
|
if (!button) return;
|
|
147
108
|
this.register(node, {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
iconKey: options.iconKey,
|
|
151
|
-
focusScale: options.focusScale || 1.08,
|
|
109
|
+
scopeId: this.activeScopeId,
|
|
110
|
+
focusScale: this.DEFAULT_FOCUS_SCALE,
|
|
152
111
|
onClick: () => this.invokeButton(button)
|
|
153
112
|
});
|
|
154
113
|
});
|
|
114
|
+
|
|
155
115
|
this.ensureFocus();
|
|
156
116
|
}
|
|
157
117
|
|
|
158
|
-
public static pushScope(scopeId: string,
|
|
118
|
+
public static pushScope(scopeId: string, options?: { node?: cc.Node; nodeType?: "window" | "scene"; onBack?: () => boolean | void; skipEnsureFocus?: boolean }) {
|
|
159
119
|
scopeId = scopeId || "modal";
|
|
160
120
|
let currentScope = this.getActiveScope();
|
|
161
|
-
if (currentScope) currentScope.
|
|
121
|
+
if (currentScope) currentScope.lastNodeUuid = this.currentNodeUuid;
|
|
162
122
|
for (let i = 0; i < this.scopes.length; i++) {
|
|
163
123
|
if (this.scopes[i].scopeId == scopeId) {
|
|
164
124
|
this.scopes.splice(i, 1);
|
|
165
125
|
break;
|
|
166
126
|
}
|
|
167
127
|
}
|
|
168
|
-
this.scopes.push(
|
|
128
|
+
this.scopes.push({ scopeId, lastNodeUuid: "", node: options?.node, nodeType: options?.nodeType, onBack: options?.onBack });
|
|
169
129
|
this.activeScopeId = scopeId;
|
|
170
|
-
this.
|
|
171
|
-
if (
|
|
172
|
-
|
|
130
|
+
this.setFocusByUuid("", true);
|
|
131
|
+
if (!options?.skipEnsureFocus) this.ensureFocus();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** 移除作用域并清理其下所有注册焦点 */
|
|
135
|
+
public static removeScope(node: cc.Node) {
|
|
136
|
+
if (!node) return;
|
|
137
|
+
this.popScope(node.uuid);
|
|
138
|
+
this.unregisterByRoot(node);
|
|
173
139
|
}
|
|
174
140
|
|
|
175
141
|
public static popScope(scopeId?: string) {
|
|
@@ -181,22 +147,42 @@ export default class FocusManager {
|
|
|
181
147
|
break;
|
|
182
148
|
}
|
|
183
149
|
}
|
|
150
|
+
// 清理已弹出作用域下的所有条目
|
|
151
|
+
for (let i = this.items.length - 1; i >= 0; i--) {
|
|
152
|
+
if (this.scopeMap[this.items[i].node.uuid] == target) {
|
|
153
|
+
this.removeItemAt(i);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
184
156
|
let active = this.scopes[this.scopes.length - 1];
|
|
185
157
|
this.activeScopeId = active ? active.scopeId : "page";
|
|
186
|
-
let restored = active && active.
|
|
158
|
+
let restored = active && active.lastNodeUuid ? this.focus(active.lastNodeUuid) : false;
|
|
187
159
|
if (!restored) {
|
|
188
|
-
this.
|
|
160
|
+
this.setFocusByUuid("", true);
|
|
189
161
|
this.ensureFocus();
|
|
190
162
|
}
|
|
191
163
|
}
|
|
192
164
|
|
|
165
|
+
/** 获取最顶层绑定了节点的作用域(排除 page) */
|
|
166
|
+
public static getTopNodeScope(): ScopeInfo | null {
|
|
167
|
+
for (let i = this.scopes.length - 1; i >= 1; i--) {
|
|
168
|
+
if (this.scopes[i].node) return this.scopes[i];
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** 获取所有作用域(只读副本) */
|
|
174
|
+
public static getScopes(): ReadonlyArray<ScopeInfo> {
|
|
175
|
+
return this.scopes;
|
|
176
|
+
}
|
|
177
|
+
|
|
193
178
|
public static reset() {
|
|
194
179
|
let old = this.getCurrentFocusItem();
|
|
195
180
|
if (old) this.setFocusVisual(old, false, true);
|
|
196
181
|
this.items = [];
|
|
197
182
|
this.itemMap = {};
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
183
|
+
this.scopeMap = {};
|
|
184
|
+
this.currentNodeUuid = "";
|
|
185
|
+
this.scopes = [{ scopeId: "page", lastNodeUuid: "" }];
|
|
200
186
|
this.activeScopeId = "page";
|
|
201
187
|
this.emitFocusChanged(null, old);
|
|
202
188
|
}
|
|
@@ -216,15 +202,11 @@ export default class FocusManager {
|
|
|
216
202
|
}
|
|
217
203
|
}
|
|
218
204
|
if (!item || !this.isItemActive(item) || !this.isInActiveScope(item)) return false;
|
|
219
|
-
this.
|
|
205
|
+
this.setFocusByUuid(item.node.uuid);
|
|
220
206
|
return true;
|
|
221
207
|
}
|
|
222
208
|
|
|
223
|
-
public static
|
|
224
|
-
return this.focus(node);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
public static move(direction: TvUiDirection): boolean {
|
|
209
|
+
public static move(direction: KeyCode): boolean {
|
|
228
210
|
this.cleanup();
|
|
229
211
|
let current = this.getCurrentFocusItem();
|
|
230
212
|
if (!current) {
|
|
@@ -232,22 +214,19 @@ export default class FocusManager {
|
|
|
232
214
|
return !!this.getCurrentFocusItem();
|
|
233
215
|
}
|
|
234
216
|
|
|
235
|
-
let explicitId = current[direction];
|
|
236
|
-
if (explicitId && this.focus(explicitId)) return true;
|
|
237
|
-
|
|
238
217
|
let vector = this.getDirectionVector(direction);
|
|
239
|
-
let currentCenter = this.getWorldCenter(current.node);
|
|
218
|
+
let currentCenter = this.getWorldCenter(current.node).add(current.offset);
|
|
240
219
|
let best: FocusRuntimeItem | null = null;
|
|
241
220
|
let bestScore = Number.MAX_VALUE;
|
|
242
221
|
|
|
243
222
|
for (let i = 0; i < this.items.length; i++) {
|
|
244
223
|
let item = this.items[i];
|
|
245
224
|
if (item == current || !this.isItemActive(item) || !this.isInActiveScope(item)) continue;
|
|
246
|
-
let center = this.getWorldCenter(item.node);
|
|
225
|
+
let center = this.getWorldCenter(item.node).add(item.offset);
|
|
247
226
|
let dx = center.x - currentCenter.x;
|
|
248
227
|
let dy = center.y - currentCenter.y;
|
|
249
|
-
if (vector.x != 0 && dx * vector.x <=
|
|
250
|
-
if (vector.y != 0 && dy * vector.y <=
|
|
228
|
+
if (vector.x != 0 && dx * vector.x <= 0) continue;
|
|
229
|
+
if (vector.y != 0 && dy * vector.y <= 0) continue;
|
|
251
230
|
let primary = vector.x != 0 ? Math.abs(dx) : Math.abs(dy);
|
|
252
231
|
let secondary = vector.x != 0 ? Math.abs(dy) : Math.abs(dx);
|
|
253
232
|
let score = primary + secondary * 2;
|
|
@@ -258,7 +237,7 @@ export default class FocusManager {
|
|
|
258
237
|
}
|
|
259
238
|
|
|
260
239
|
if (best) {
|
|
261
|
-
this.
|
|
240
|
+
this.setFocusByUuid(best.node.uuid);
|
|
262
241
|
return true;
|
|
263
242
|
}
|
|
264
243
|
return this.moveByOrder(direction == "left" || direction == "down" ? -1 : 1);
|
|
@@ -272,40 +251,18 @@ export default class FocusManager {
|
|
|
272
251
|
item.onClick();
|
|
273
252
|
return true;
|
|
274
253
|
}
|
|
275
|
-
|
|
276
|
-
|
|
254
|
+
let focusItem = item.node.getComponent("FocusItem") as any;
|
|
255
|
+
if (focusItem && focusItem.onConfirm) {
|
|
256
|
+
focusItem.onConfirm();
|
|
277
257
|
return true;
|
|
278
258
|
}
|
|
279
259
|
this.invokeButton(item.node.getComponent(cc.Button));
|
|
280
260
|
return true;
|
|
281
261
|
}
|
|
282
262
|
|
|
283
|
-
public static back(): boolean {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
public static handleKey(keyCode: number): boolean {
|
|
288
|
-
let key = KeyCodeAdapter.toRemoteKey(keyCode);
|
|
289
|
-
if (key == TvRemoteKey.Ok) return this.confirm();
|
|
290
|
-
if (key == TvRemoteKey.Left) return this.move("left");
|
|
291
|
-
if (key == TvRemoteKey.Right) return this.move("right");
|
|
292
|
-
if (key == TvRemoteKey.Up) return this.move("up");
|
|
293
|
-
if (key == TvRemoteKey.Down) return this.move("down");
|
|
294
|
-
if (key == TvRemoteKey.Back) return this.back();
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
public static clickCurrent(): boolean {
|
|
299
|
-
return this.confirm();
|
|
300
|
-
}
|
|
301
|
-
|
|
302
263
|
public static getCurrentFocusItem(): FocusRuntimeItem | null {
|
|
303
|
-
let item = this.itemMap[this.
|
|
304
|
-
return this.isItemActive(item) ? item : null;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
public static getActiveScopeId(): string {
|
|
308
|
-
return this.activeScopeId;
|
|
264
|
+
let item = this.itemMap[this.currentNodeUuid];
|
|
265
|
+
return (item && this.isItemActive(item) && this.isInActiveScope(item)) ? item : null;
|
|
309
266
|
}
|
|
310
267
|
|
|
311
268
|
public static onFocusChanged(listener: FocusListener) {
|
|
@@ -318,8 +275,8 @@ export default class FocusManager {
|
|
|
318
275
|
if (index >= 0) this.listeners.splice(index, 1);
|
|
319
276
|
}
|
|
320
277
|
|
|
321
|
-
private static
|
|
322
|
-
if (
|
|
278
|
+
private static setFocusByUuid(uuid: string, silent: boolean = false) {
|
|
279
|
+
if (uuid == this.currentNodeUuid && uuid) {
|
|
323
280
|
let current = this.getCurrentFocusItem();
|
|
324
281
|
if (current && !silent) {
|
|
325
282
|
this.setFocusVisual(current, true);
|
|
@@ -329,11 +286,11 @@ export default class FocusManager {
|
|
|
329
286
|
}
|
|
330
287
|
let previous: FocusRuntimeItem | null = this.getCurrentFocusItem();
|
|
331
288
|
if (previous) this.setFocusVisual(previous, false);
|
|
332
|
-
this.
|
|
289
|
+
this.currentNodeUuid = uuid || "";
|
|
333
290
|
let current: FocusRuntimeItem | null = this.getCurrentFocusItem();
|
|
334
291
|
if (current) {
|
|
335
292
|
let scope = this.getActiveScope();
|
|
336
|
-
if (scope) scope.
|
|
293
|
+
if (scope) scope.lastNodeUuid = current.node.uuid;
|
|
337
294
|
this.setFocusVisual(current, true);
|
|
338
295
|
}
|
|
339
296
|
if (!silent) this.emitFocusChanged(current, previous);
|
|
@@ -344,8 +301,9 @@ export default class FocusManager {
|
|
|
344
301
|
if (!item || !item.node || !item.node.isValid) return;
|
|
345
302
|
this.setButtonSpriteVisual(item, focused);
|
|
346
303
|
item.node.stopActionByTag(this.FOCUS_SCALE_ACTION_TAG);
|
|
347
|
-
let
|
|
348
|
-
let
|
|
304
|
+
let baseScale = this.getNodeBaseScale(item.node);
|
|
305
|
+
let targetScaleX = focused ? baseScale.x * item.focusScale : baseScale.x;
|
|
306
|
+
let targetScaleY = focused ? baseScale.y * item.focusScale : baseScale.y;
|
|
349
307
|
if (immediate) {
|
|
350
308
|
item.node.setScale(targetScaleX, targetScaleY);
|
|
351
309
|
} else {
|
|
@@ -353,8 +311,8 @@ export default class FocusManager {
|
|
|
353
311
|
action.setTag(this.FOCUS_SCALE_ACTION_TAG);
|
|
354
312
|
item.node.runAction(action);
|
|
355
313
|
}
|
|
356
|
-
if (focused && item.onFocus) item.onFocus
|
|
357
|
-
if (!focused && item.onBlur) item.onBlur
|
|
314
|
+
if (focused && item.onFocus) item.onFocus();
|
|
315
|
+
if (!focused && item.onBlur) item.onBlur();
|
|
358
316
|
}
|
|
359
317
|
|
|
360
318
|
private static setButtonSpriteVisual(item: FocusRuntimeItem, focused: boolean) {
|
|
@@ -368,18 +326,33 @@ export default class FocusManager {
|
|
|
368
326
|
if (spriteFrame) sprite.spriteFrame = spriteFrame;
|
|
369
327
|
}
|
|
370
328
|
|
|
329
|
+
private static _ensureFocusPending: boolean = false;
|
|
330
|
+
|
|
371
331
|
private static ensureFocus() {
|
|
372
332
|
this.cleanup();
|
|
373
333
|
if (this.getCurrentFocusItem()) return;
|
|
374
334
|
let activeScope = this.getActiveScope();
|
|
375
|
-
if (activeScope && activeScope.
|
|
335
|
+
if (activeScope && activeScope.lastNodeUuid && this.focus(activeScope.lastNodeUuid)) return;
|
|
376
336
|
for (let i = 0; i < this.items.length; i++) {
|
|
377
337
|
let item = this.items[i];
|
|
378
338
|
if (this.isItemActive(item) && this.isInActiveScope(item)) {
|
|
379
|
-
this.
|
|
339
|
+
this.setFocusByUuid(item.node.uuid);
|
|
380
340
|
return;
|
|
381
341
|
}
|
|
382
342
|
}
|
|
343
|
+
// 有注册的按钮但暂无活跃节点,可能是节点尚未完全初始化,延迟重试
|
|
344
|
+
if (this.items.length > 0 && !this._ensureFocusPending) {
|
|
345
|
+
this._ensureFocusPending = true;
|
|
346
|
+
setTimeout(() => {
|
|
347
|
+
this._ensureFocusPending = false;
|
|
348
|
+
this.ensureFocus();
|
|
349
|
+
}, 50);
|
|
350
|
+
}
|
|
351
|
+
// 既无注册项也无焦点,清除焦点状态
|
|
352
|
+
if (this.items.length === 0) {
|
|
353
|
+
this.currentNodeUuid = "";
|
|
354
|
+
this.emitFocusChanged(null, null);
|
|
355
|
+
}
|
|
383
356
|
}
|
|
384
357
|
|
|
385
358
|
private static moveByOrder(step: number): boolean {
|
|
@@ -390,13 +363,13 @@ export default class FocusManager {
|
|
|
390
363
|
if (activeItems.length <= 0) return false;
|
|
391
364
|
let index = 0;
|
|
392
365
|
for (let i = 0; i < activeItems.length; i++) {
|
|
393
|
-
if (activeItems[i].
|
|
366
|
+
if (activeItems[i].node.uuid == this.currentNodeUuid) {
|
|
394
367
|
index = i;
|
|
395
368
|
break;
|
|
396
369
|
}
|
|
397
370
|
}
|
|
398
371
|
let next = (index + step + activeItems.length) % activeItems.length;
|
|
399
|
-
this.
|
|
372
|
+
this.setFocusByUuid(activeItems[next].node.uuid);
|
|
400
373
|
return true;
|
|
401
374
|
}
|
|
402
375
|
|
|
@@ -404,10 +377,11 @@ export default class FocusManager {
|
|
|
404
377
|
let item = this.items[index];
|
|
405
378
|
if (!item) return;
|
|
406
379
|
this.setFocusVisual(item, false, true);
|
|
407
|
-
delete this.itemMap[item.
|
|
380
|
+
delete this.itemMap[item.node.uuid];
|
|
381
|
+
delete this.scopeMap[item.node.uuid];
|
|
408
382
|
this.items.splice(index, 1);
|
|
409
|
-
if (this.
|
|
410
|
-
this.
|
|
383
|
+
if (this.currentNodeUuid == item.node.uuid) {
|
|
384
|
+
this.currentNodeUuid = "";
|
|
411
385
|
this.emitFocusChanged(null, item);
|
|
412
386
|
}
|
|
413
387
|
}
|
|
@@ -426,10 +400,10 @@ export default class FocusManager {
|
|
|
426
400
|
}
|
|
427
401
|
|
|
428
402
|
private static isInActiveScope(item?: FocusRuntimeItem | null): boolean {
|
|
429
|
-
return !!item && item.
|
|
403
|
+
return !!item && this.scopeMap[item.node.uuid] == this.activeScopeId;
|
|
430
404
|
}
|
|
431
405
|
|
|
432
|
-
private static getActiveScope():
|
|
406
|
+
private static getActiveScope(): ScopeInfo | null {
|
|
433
407
|
for (let i = this.scopes.length - 1; i >= 0; i--) {
|
|
434
408
|
if (this.scopes[i].scopeId == this.activeScopeId) return this.scopes[i];
|
|
435
409
|
}
|
|
@@ -441,10 +415,10 @@ export default class FocusManager {
|
|
|
441
415
|
return cc.v2(box.x + box.width / 2, box.y + box.height / 2);
|
|
442
416
|
}
|
|
443
417
|
|
|
444
|
-
private static getDirectionVector(direction:
|
|
445
|
-
if (direction ==
|
|
446
|
-
if (direction ==
|
|
447
|
-
if (direction ==
|
|
418
|
+
private static getDirectionVector(direction: KeyCode): cc.Vec2 {
|
|
419
|
+
if (direction == KeyCode.Left) return cc.v2(-1, 0);
|
|
420
|
+
if (direction == KeyCode.Right) return cc.v2(1, 0);
|
|
421
|
+
if (direction == KeyCode.Up) return cc.v2(0, 1);
|
|
448
422
|
return cc.v2(0, -1);
|
|
449
423
|
}
|
|
450
424
|
|
|
@@ -479,15 +453,7 @@ export default class FocusManager {
|
|
|
479
453
|
return target;
|
|
480
454
|
}
|
|
481
455
|
|
|
482
|
-
private static
|
|
483
|
-
if (!node) return null;
|
|
484
|
-
for (let i = 0; i < this.items.length; i++) {
|
|
485
|
-
if (this.items[i].node == node) return this.items[i];
|
|
486
|
-
}
|
|
487
|
-
return null;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
private static getNodeBaseScale(node: cc.Node, preferred?: { x: number, y: number } | null): { x: number, y: number } {
|
|
456
|
+
private static getNodeBaseScale(node: cc.Node): { x: number, y: number } {
|
|
491
457
|
let nodeAny: any = node as any;
|
|
492
458
|
let storedX = nodeAny[this.BASE_SCALE_X_KEY];
|
|
493
459
|
let storedY = nodeAny[this.BASE_SCALE_Y_KEY];
|
|
@@ -495,7 +461,7 @@ export default class FocusManager {
|
|
|
495
461
|
return { x: storedX, y: storedY };
|
|
496
462
|
}
|
|
497
463
|
|
|
498
|
-
let baseScale =
|
|
464
|
+
let baseScale = {
|
|
499
465
|
x: this.readScale(node, "scaleX"),
|
|
500
466
|
y: this.readScale(node, "scaleY")
|
|
501
467
|
};
|
|
@@ -516,10 +482,6 @@ export default class FocusManager {
|
|
|
516
482
|
return typeof value == "number" && isFinite(value);
|
|
517
483
|
}
|
|
518
484
|
|
|
519
|
-
private static createFocusId(node: cc.Node): string {
|
|
520
|
-
return "focus_" + (node.name || "node") + "_" + this.items.length;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
485
|
private static walk(node: cc.Node, visitor: (node: cc.Node) => void) {
|
|
524
486
|
visitor(node);
|
|
525
487
|
for (let i = 0; i < node.childrenCount; i++) {
|
|
@@ -535,4 +497,4 @@ export default class FocusManager {
|
|
|
535
497
|
}
|
|
536
498
|
return false;
|
|
537
499
|
}
|
|
538
|
-
}
|
|
500
|
+
}
|