diff --git a/.creator/asset-template/typescript/Custom Script Template Help Documentation.url b/.creator/asset-template/typescript/Custom Script Template Help Documentation.url new file mode 100644 index 0000000..7606df0 --- /dev/null +++ b/.creator/asset-template/typescript/Custom Script Template Help Documentation.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://docs.cocos.com/creator/manual/en/scripting/setup.html#custom-script-template \ No newline at end of file diff --git a/.creator/default-meta.json b/.creator/default-meta.json new file mode 100644 index 0000000..abb1239 --- /dev/null +++ b/.creator/default-meta.json @@ -0,0 +1,5 @@ +{ + "image": { + "type": "sprite-frame" + } +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..ed8aa20 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,42 @@ +module.exports = { + env: { + browser: true, + node: true + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended' + ], + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module' + }, + plugins: [ + '@typescript-eslint' + ], + globals: {}, + rules: { + 'no-useless-escape': 0, + 'prefer-spread': 0, + 'prefer-const': 0, + 'comma-spacing': 'error', + 'space-infix-ops': 'error', + 'no-constant-condition': 0, + 'no-inner-declarations': 0, + '@typescript-eslint/no-namespace': 0, + '@typescript-eslint/no-empty-interface': 0, + 'arrow-spacing': ['error', { before: true, after: true }], + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 1 }], + 'space-before-function-paren': ['error', { 'anonymous': 'always', 'named': 'never', 'asyncArrow': 'always' }], + '@typescript-eslint/ban-types': 0, + '@typescript-eslint/ban-ts-comment': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/semi': ['error', 'always'], + '@typescript-eslint/quotes': ['error', 'single'], + '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/object-curly-spacing': ['error', 'always'], + '@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true, ignoreProperties: true }], + } +}; \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..673e33a --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +#///////////////////////////////////////////////////////////////////////////// +# Fireball Projects +#///////////////////////////////////////////////////////////////////////////// + +!/profiles/v2/packages/builder.json +!/extensions/app/ +!/extensions/pkg/ + +/temp/ +/build/ +/library/ +/profiles/ +/local/logs/ +/local/local.json +/local/layout.editor.json +#///////////////////////////////////////////////////////////////////////////// +# npm files +#///////////////////////////////////////////////////////////////////////////// + +npm-debug.log +/node_modules +/web-template/node_modules + +#///////////////////////////////////////////////////////////////////////////// +# Logs and databases +#///////////////////////////////////////////////////////////////////////////// + +*.log +*.sql +*.sqlite + +#///////////////////////////////////////////////////////////////////////////// +# files for debugger +#///////////////////////////////////////////////////////////////////////////// + +*.sln +*.pidb +*.suo + +#///////////////////////////////////////////////////////////////////////////// +# OS generated files +#///////////////////////////////////////////////////////////////////////////// + +.DS_Store +ehthumbs.db +Thumbs.db + +#///////////////////////////////////////////////////////////////////////////// +# WebStorm files +#///////////////////////////////////////////////////////////////////////////// + +.idea/ + +#////////////////////////// +# VS Code files +#////////////////////////// + +.vscode/ +!.vscode/settings.json \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4b3eeeb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 向前 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/assets/app-appinit.meta b/assets/app-appinit.meta new file mode 100644 index 0000000..e7bb441 --- /dev/null +++ b/assets/app-appinit.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "5aa02f13-d2f9-4d73-a79e-58b9fe6eca78", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app-appinit/.app-appinit.md b/assets/app-appinit/.app-appinit.md new file mode 100644 index 0000000..535f528 --- /dev/null +++ b/assets/app-appinit/.app-appinit.md @@ -0,0 +1,2 @@ +1、框架初始化首屏 +2、不可删除此文件夹 \ No newline at end of file diff --git a/assets/app-appinit/res.meta b/assets/app-appinit/res.meta new file mode 100644 index 0000000..222c6bb --- /dev/null +++ b/assets/app-appinit/res.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "e1ee8c84-c9c2-4a48-8e6e-9e242ed718f3", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app-appinit/res/logo.png b/assets/app-appinit/res/logo.png new file mode 100644 index 0000000..d052be2 Binary files /dev/null and b/assets/app-appinit/res/logo.png differ diff --git a/assets/app-appinit/res/logo.png.meta b/assets/app-appinit/res/logo.png.meta new file mode 100644 index 0000000..cf67ff3 --- /dev/null +++ b/assets/app-appinit/res/logo.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "2a89c2f6-f894-47db-88e9-1017df6fbf0d", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "2a89c2f6-f894-47db-88e9-1017df6fbf0d@6c48a", + "displayName": "logo", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "2a89c2f6-f894-47db-88e9-1017df6fbf0d", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "2a89c2f6-f894-47db-88e9-1017df6fbf0d@f9941", + "displayName": "logo", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": -2.5, + "offsetY": 1, + "trimX": 0, + "trimY": 1, + "width": 982, + "height": 801, + "rawWidth": 987, + "rawHeight": 805, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -491, + -400.5, + 0, + 491, + -400.5, + 0, + -491, + 400.5, + 0, + 491, + 400.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 804, + 982, + 804, + 0, + 3, + 982, + 3 + ], + "nuv": [ + 0, + 0.0037267080745341614, + 0.9949341438703141, + 0.0037267080745341614, + 0, + 0.9987577639751553, + 0.9949341438703141, + 0.9987577639751553 + ], + "minPos": [ + -491, + -400.5, + 0 + ], + "maxPos": [ + 491, + 400.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "2a89c2f6-f894-47db-88e9-1017df6fbf0d@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "2a89c2f6-f894-47db-88e9-1017df6fbf0d@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-appinit/res/singleColor.png b/assets/app-appinit/res/singleColor.png new file mode 100644 index 0000000..09fa6c5 Binary files /dev/null and b/assets/app-appinit/res/singleColor.png differ diff --git a/assets/app-appinit/res/singleColor.png.meta b/assets/app-appinit/res/singleColor.png.meta new file mode 100644 index 0000000..fc1f516 --- /dev/null +++ b/assets/app-appinit/res/singleColor.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132@6c48a", + "displayName": "singleColor", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132@f9941", + "displayName": "singleColor", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 2, + "height": 2, + "rawWidth": 2, + "rawHeight": 2, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -1, + -1, + 0, + 1, + -1, + 0, + -1, + 1, + 0, + 1, + 1, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 2, + 2, + 2, + 0, + 0, + 2, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -1, + -1, + 0 + ], + "maxPos": [ + 1, + 1, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "hasAlpha": false, + "redirect": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132@6c48a" + } +} diff --git a/assets/app-appinit/view.meta b/assets/app-appinit/view.meta new file mode 100644 index 0000000..eda2d0e --- /dev/null +++ b/assets/app-appinit/view.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "2d1f88c5-c88d-43c1-9bad-8c188f9314e0", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app-appinit/view/AppInit.prefab b/assets/app-appinit/view/AppInit.prefab new file mode 100644 index 0000000..4519c6a --- /dev/null +++ b/assets/app-appinit/view/AppInit.prefab @@ -0,0 +1,502 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "AppInit", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "AppInit", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 10 + } + ], + "_active": true, + "_components": [ + { + "__id__": 18 + }, + { + "__id__": 20 + }, + { + "__id__": 22 + } + ], + "_prefab": { + "__id__": 24 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "bg", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1bUhFF79dG46Ne46ZRxKpC" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 227, + "g": 235, + "b": 228, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "a4cadc68-5c93-4683-8ee0-cf3bb6acb132@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f0x+xHB+BD77gwz9qesmbl" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 2, + "_originalHeight": 2, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "fd5ETT07RFqrFUq6p6ErCa" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "0fJ7SovSVCVawCNYpB3WTW", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "logo", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + }, + { + "__id__": 13 + }, + { + "__id__": 15 + } + ], + "_prefab": { + "__id__": 17 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 0.5, + "y": 0.5, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 12 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 982, + "height": 801 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "830VxCeINAa7bLC2kyd2Db" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 14 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "2a89c2f6-f894-47db-88e9-1017df6fbf0d@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "fdljxQ6hREBoCDN2bRrUnW" + }, + { + "__type__": "cc.UIOpacity", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 16 + }, + "_opacity": 255, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8foH2eGy5DX4TvPYTKru5b" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "8cWbsI+kdMYYPLYQrEFecs", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "fdxpU8hWdAMIljPcrHWSD1" + }, + { + "__type__": "598f2EhUohEebUzsqwXHool", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "logo": { + "__id__": 10 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ffhkucpqlE+aHYz+nafs1t" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 23 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "10GYyo4FNMU6BKnnXpm7FG" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "7aBxAgUy9NRJNTrHNH6/6R", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/assets/app-appinit/view/AppInit.prefab.meta b/assets/app-appinit/view/AppInit.prefab.meta new file mode 100644 index 0000000..b5eaf7e --- /dev/null +++ b/assets/app-appinit/view/AppInit.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "19a93f71-0300-44b3-9bd9-efbc15271e7d", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "AppInit" + } +} diff --git a/assets/app-appinit/view/AppInit.ts b/assets/app-appinit/view/AppInit.ts new file mode 100644 index 0000000..1f3bd5d --- /dev/null +++ b/assets/app-appinit/view/AppInit.ts @@ -0,0 +1,75 @@ +import { Node, UIOpacity, _decorator, tween } from 'cc'; +import BaseAppInit from '../../../extensions/app/assets/base/BaseAppInit'; +import { LOGIN_TOKEN } from '../../res-native/network/HttpRequest'; +import { Tools } from '../../res-native/tools/Tools'; +import { app } from '../../app/app'; +import { USERDATA } from '../../res-native/data/UserData'; +const { ccclass, property } = _decorator; + +@ccclass('AppInit') +export class AppInit extends BaseAppInit { + @property(Node) + private logo: Node; + + /** + * 获得用户资源总量,这里返回几,就需要用户自行调用几次nextInit + */ + protected getUserAssetNum(): number { + return 1; + } + + protected onLoad() { + this.initToken(); + + if (LOGIN_TOKEN.access_token == "" || LOGIN_TOKEN.access_token == undefined) { + return + } + + // 执行初始化操作 + const opacity = this.logo.getComponent(UIOpacity); + opacity.opacity = 0; + + tween(opacity) + .to(0.5, { opacity: 255 }) + .delay(1) + .to(0.5, { opacity: 0 }) + .call(() => { + Tools.httpReq("prize-list", {}, (res:any) => { + USERDATA.setUserData(res); + this.nextInit(); + }) + }) + .start(); + } + + /** 根据参数初始化TOKEN */ + initToken(){ + let str = window.location.search.slice(1) + const pairs = str.split('&'); + const params: { [key: string]: string } = {}; + pairs.forEach(pair => { + const [key, value] = pair.split('='); + params[decodeURIComponent(key)] = decodeURIComponent(value || ''); + }); + + const at = Tools.parseJWT(params.access_token) + const actualKey = 'xyxfz83d'.substring(0, 8); // 取前8个字符 + // 解密appkey + const appkey = Tools.desEcbDecrypt(at.extend.channel, actualKey); + + // 如果解密失败,尝试原始值 + if (!appkey) { + console.log('Failed to decrypt token, using original value'); + } + + LOGIN_TOKEN.setToken(params.access_token, params.refresh_token, at.extend.app_id, appkey) + } + + // BaseAppInit中使用start方法作为初始化入口,如果重写start方法,请注意调用父类方法 + // protected start() { } + + protected onFinish() { + // 执行完成操作 + this.node.destroy(); + } +} \ No newline at end of file diff --git a/assets/app-appinit/view/AppInit.ts.meta b/assets/app-appinit/view/AppInit.ts.meta new file mode 100644 index 0000000..46ad2c3 --- /dev/null +++ b/assets/app-appinit/view/AppInit.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "598f2121-5288-4479-b533-b2ac171e8a25", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-builtin.meta b/assets/app-builtin.meta new file mode 100644 index 0000000..a69e743 --- /dev/null +++ b/assets/app-builtin.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "8564f435-63c9-4e21-bda9-2927d8c7b90d", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app-builtin/.app-builtin.md b/assets/app-builtin/.app-builtin.md new file mode 100644 index 0000000..9217110 --- /dev/null +++ b/assets/app-builtin/.app-builtin.md @@ -0,0 +1,2 @@ +1、存储内置功能的文件夹 +2、不可删除此文件夹 \ No newline at end of file diff --git a/assets/app-builtin/app-admin.meta b/assets/app-builtin/app-admin.meta new file mode 100644 index 0000000..20e4ba3 --- /dev/null +++ b/assets/app-builtin/app-admin.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "95e76f7f-cbcf-4726-87bf-efbf19fb0e33", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_398Ij6Mc1B2Y7sW3e6BgFC" + } +} diff --git a/assets/app-builtin/app-admin/.app-admin.md b/assets/app-builtin/app-admin/.app-admin.md new file mode 100644 index 0000000..3d17431 --- /dev/null +++ b/assets/app-builtin/app-admin/.app-admin.md @@ -0,0 +1,2 @@ +1、一些配置类的资产(框架自动维护) +2、不可删除此文件夹 \ No newline at end of file diff --git a/assets/app-builtin/app-admin/executor.ts b/assets/app-builtin/app-admin/executor.ts new file mode 100644 index 0000000..c8ad23e --- /dev/null +++ b/assets/app-builtin/app-admin/executor.ts @@ -0,0 +1,41 @@ +/* eslint-disable */ +import { Component,director,Director } from 'cc'; +import { app } from '../../app/app'; +import { EDITOR,EDITOR_NOT_IN_PREVIEW } from 'cc/env'; + +export type IReadOnly = { readonly [P in keyof T]: T[P] extends Function ? T[P] : (T[P] extends Object ? IReadOnly : T[P]); }; + +export type IViewName = "PageMain"|"PageRewardhistory"|"PageTips" +export type IViewNames = IViewName[] +export type IMiniViewName = "never" +export type IMiniViewNames = IMiniViewName[] +export type IMusicName = "music/bgm" +export type IMusicNames = IMusicName[] +export type IEffectName = "effect/click"|"effect/jump"|"effect/win" +export type IEffectNames = IEffectName[] + +import EventManager from '../../../extensions/app/assets/manager/event/EventManager' +import LoaderManager from '../../../extensions/app/assets/manager/loader/LoaderManager' +import SoundManager from '../../../extensions/app/assets/manager/sound/SoundManager' +import TimerManager from '../../../extensions/app/assets/manager/timer/TimerManager' +import UIManager from '../../../extensions/app/assets/manager/ui/UIManager' +export type IApp = { + Controller: {}, + controller: {}, + Manager: {Event:Omit,Loader:Omit,Sound:Omit,Timer:Omit,UI:Omit}, + manager: {event:Omit,loader:Omit,sound:Omit,keyof Component>,timer:Omit,ui:Omit,keyof Component>}, + data: {}, + config: {} + store: {} +} + +function init(){ +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) Object.assign(app.config, {}) +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) Object.assign(app.data, {}) +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) Object.assign(app.store, {}) + +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) Object.assign(app.Controller, {}) +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) Object.assign(app.controller, {}) +} +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) director.on(Director.EVENT_RESET,init) +if(!EDITOR||!EDITOR_NOT_IN_PREVIEW) init() diff --git a/assets/app-builtin/app-admin/executor.ts.meta b/assets/app-builtin/app-admin/executor.ts.meta new file mode 100644 index 0000000..e6d7b3b --- /dev/null +++ b/assets/app-builtin/app-admin/executor.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "f187b639-0be1-421c-ac96-f3891a260321", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle.meta b/assets/app-bundle.meta new file mode 100644 index 0000000..78922fa --- /dev/null +++ b/assets/app-bundle.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "77941b47-de7f-4917-8716-2b6c7a2f4c44", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/.app-bundle.md b/assets/app-bundle/.app-bundle.md new file mode 100644 index 0000000..09f58db --- /dev/null +++ b/assets/app-bundle/.app-bundle.md @@ -0,0 +1,2 @@ +1、存储内置的Bundle的文件夹 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-sound.meta b/assets/app-bundle/app-sound.meta new file mode 100644 index 0000000..3088c72 --- /dev/null +++ b/assets/app-bundle/app-sound.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "1641af30-73a6-4372-8a9c-c943ec12e662", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_11aBEBWDxI/6ryvKvFthEo", + "priority": 8 + } +} diff --git a/assets/app-bundle/app-sound/.app-sound.md b/assets/app-bundle/app-sound/.app-sound.md new file mode 100644 index 0000000..0a40169 --- /dev/null +++ b/assets/app-bundle/app-sound/.app-sound.md @@ -0,0 +1,4 @@ +存储音乐/音效资源的文件夹 +1、通过app.manager.sound管理 +2、通过菜单「App/创建/Sound」创建目录 +3、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-sound/effect.meta b/assets/app-bundle/app-sound/effect.meta new file mode 100644 index 0000000..97a3d6c --- /dev/null +++ b/assets/app-bundle/app-sound/effect.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "32c9cd5c-ed73-4e47-be3c-ea1a8f78e77e", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-sound/effect/.effect.md b/assets/app-bundle/app-sound/effect/.effect.md new file mode 100644 index 0000000..81d4b4d --- /dev/null +++ b/assets/app-bundle/app-sound/effect/.effect.md @@ -0,0 +1,3 @@ +存储音效资源的文件夹 +1、通过app.manager.sound.playEffect播放 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-sound/effect/click.mp3 b/assets/app-bundle/app-sound/effect/click.mp3 new file mode 100644 index 0000000..39cb04f Binary files /dev/null and b/assets/app-bundle/app-sound/effect/click.mp3 differ diff --git a/assets/app-bundle/app-sound/effect/click.mp3.meta b/assets/app-bundle/app-sound/effect/click.mp3.meta new file mode 100644 index 0000000..3f85401 --- /dev/null +++ b/assets/app-bundle/app-sound/effect/click.mp3.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.0.0", + "importer": "audio-clip", + "imported": true, + "uuid": "04f32df8-49f5-42a3-821d-55e09e767c24", + "files": [ + ".json", + ".mp3" + ], + "subMetas": {}, + "userData": { + "downloadMode": 0 + } +} diff --git a/assets/app-bundle/app-sound/effect/jump.mp3 b/assets/app-bundle/app-sound/effect/jump.mp3 new file mode 100644 index 0000000..904a138 Binary files /dev/null and b/assets/app-bundle/app-sound/effect/jump.mp3 differ diff --git a/assets/app-bundle/app-sound/effect/jump.mp3.meta b/assets/app-bundle/app-sound/effect/jump.mp3.meta new file mode 100644 index 0000000..e3e6956 --- /dev/null +++ b/assets/app-bundle/app-sound/effect/jump.mp3.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.0.0", + "importer": "audio-clip", + "imported": true, + "uuid": "d3b7bcd2-f720-43d9-a8a9-6671c8036f4e", + "files": [ + ".json", + ".mp3" + ], + "subMetas": {}, + "userData": { + "downloadMode": 0 + } +} diff --git a/assets/app-bundle/app-sound/effect/win.mp3 b/assets/app-bundle/app-sound/effect/win.mp3 new file mode 100644 index 0000000..3de7619 Binary files /dev/null and b/assets/app-bundle/app-sound/effect/win.mp3 differ diff --git a/assets/app-bundle/app-sound/effect/win.mp3.meta b/assets/app-bundle/app-sound/effect/win.mp3.meta new file mode 100644 index 0000000..6d2ffa4 --- /dev/null +++ b/assets/app-bundle/app-sound/effect/win.mp3.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.0.0", + "importer": "audio-clip", + "imported": true, + "uuid": "9559b267-20c1-4c94-b217-187b72211b76", + "files": [ + ".json", + ".mp3" + ], + "subMetas": {}, + "userData": { + "downloadMode": 0 + } +} diff --git a/assets/app-bundle/app-sound/music.meta b/assets/app-bundle/app-sound/music.meta new file mode 100644 index 0000000..703d7b7 --- /dev/null +++ b/assets/app-bundle/app-sound/music.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "5ae9e382-f181-4129-a699-efef7ad9dd41", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-sound/music/.music.md b/assets/app-bundle/app-sound/music/.music.md new file mode 100644 index 0000000..23ad867 --- /dev/null +++ b/assets/app-bundle/app-sound/music/.music.md @@ -0,0 +1,3 @@ +存储音乐资源的文件夹 +1、通过app.manager.sound.playMusic播放 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-sound/music/bgm.mp3 b/assets/app-bundle/app-sound/music/bgm.mp3 new file mode 100644 index 0000000..9ee4c3f Binary files /dev/null and b/assets/app-bundle/app-sound/music/bgm.mp3 differ diff --git a/assets/app-bundle/app-sound/music/bgm.mp3.meta b/assets/app-bundle/app-sound/music/bgm.mp3.meta new file mode 100644 index 0000000..36fa74c --- /dev/null +++ b/assets/app-bundle/app-sound/music/bgm.mp3.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.0.0", + "importer": "audio-clip", + "imported": true, + "uuid": "c86a2589-3d6b-4f8f-84f2-7976c9976512", + "files": [ + ".json", + ".mp3" + ], + "subMetas": {}, + "userData": { + "downloadMode": 0 + } +} diff --git a/assets/app-bundle/app-view.meta b/assets/app-bundle/app-view.meta new file mode 100644 index 0000000..6362102 --- /dev/null +++ b/assets/app-bundle/app-view.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "d4316074-6ccc-4906-90e1-b98c8c421ae1", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/.app-view.md b/assets/app-bundle/app-view/.app-view.md new file mode 100644 index 0000000..333dbde --- /dev/null +++ b/assets/app-bundle/app-view/.app-view.md @@ -0,0 +1,4 @@ +存储UI资源的文件夹 +1、通过app.manager.ui管理 +2、通过菜单「App/创建/View」创建 +3、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page.meta b/assets/app-bundle/app-view/page.meta new file mode 100644 index 0000000..f4ccc66 --- /dev/null +++ b/assets/app-bundle/app-view/page.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "5854d615-edf1-435d-9ec6-1ecb4ee0af2a", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/.page.md b/assets/app-bundle/app-view/page/.page.md new file mode 100644 index 0000000..25dd2b3 --- /dev/null +++ b/assets/app-bundle/app-view/page/.page.md @@ -0,0 +1,2 @@ +1、所有page类型UI的根目录 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main.meta b/assets/app-bundle/app-view/page/main.meta new file mode 100644 index 0000000..00beee5 --- /dev/null +++ b/assets/app-bundle/app-view/page/main.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "06135315-0b97-4b53-97f0-5ee82ea63600", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/main/.main.md b/assets/app-bundle/app-view/page/main/.main.md new file mode 100644 index 0000000..67708fb --- /dev/null +++ b/assets/app-bundle/app-view/page/main/.main.md @@ -0,0 +1,3 @@ +PageMain所在文件夹 +1、通过app.manager.ui.show({ name:'PageMain' })的方式加载 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/native.meta b/assets/app-bundle/app-view/page/main/native.meta new file mode 100644 index 0000000..d5ce7db --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "616115b0-9188-44c6-8a76-26bb2fe12d3c", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_f7NI9WxFVIO6e8LbJGF72k", + "priority": 1, + "bundleName": "page-main" + } +} diff --git a/assets/app-bundle/app-view/page/main/native/.native.md b/assets/app-bundle/app-view/page/main/native/.native.md new file mode 100644 index 0000000..fbfda3c --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/.native.md @@ -0,0 +1,4 @@ +存放UI以及脚本的文件夹 +1、除了UI本身外,不允许存放其它任何预置体或场景资源🔥 +2、UI脚本在根目录下,其它脚本放到expansion目录下 +3、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/native/PageMain.prefab b/assets/app-bundle/app-view/page/main/native/PageMain.prefab new file mode 100644 index 0000000..1eb6937 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/PageMain.prefab @@ -0,0 +1,5753 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "PageMain", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "PageMain", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 102 + }, + { + "__id__": 159 + }, + { + "__id__": 210 + } + ], + "_active": true, + "_components": [ + { + "__id__": 234 + }, + { + "__id__": 236 + }, + { + "__id__": 238 + } + ], + "_prefab": { + "__id__": 240 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "bg", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 3 + }, + { + "__id__": 38 + }, + { + "__id__": 63 + }, + { + "__id__": 69 + }, + { + "__id__": 75 + }, + { + "__id__": 87 + } + ], + "_active": true, + "_components": [ + { + "__id__": 95 + }, + { + "__id__": 97 + }, + { + "__id__": 99 + } + ], + "_prefab": { + "__id__": 101 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "btns", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 4 + }, + { + "__id__": 13 + }, + { + "__id__": 22 + } + ], + "_active": true, + "_components": [ + { + "__id__": 31 + }, + { + "__id__": 33 + }, + { + "__id__": 35 + } + ], + "_prefab": { + "__id__": 37 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 327.5, + "y": 880, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "btn_sounds", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 3 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 5 + }, + { + "__id__": 7 + }, + { + "__id__": 9 + } + ], + "_prefab": { + "__id__": 12 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 139, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 4 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 119, + "height": 117 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e2/A010hdBzqRot0QFZOVA" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 4 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "f76d4098-86bb-4d85-8e5b-beb06b7308f2@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "2cPeWZE15GIJPOJww7DMwl" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 4 + }, + "_enabled": true, + "__prefab": { + "__id__": 10 + }, + "clickEvents": [ + { + "__id__": 11 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "30tMFRufRPS6thCSAPy1CT" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "oncClickMusic", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "8cKb4xJVNHz72xOkrc+uql", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_tips", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 3 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 14 + }, + { + "__id__": 16 + }, + { + "__id__": 18 + } + ], + "_prefab": { + "__id__": 21 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 13 + }, + "_enabled": true, + "__prefab": { + "__id__": 15 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 119, + "height": 117 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "4foCR92opPj6lk+3k4vT7A" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 13 + }, + "_enabled": true, + "__prefab": { + "__id__": 17 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "5b600712-8704-49cd-9f95-5f013387a423@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "97cTpcRLFL3Jy4GrDB0Bb9" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 13 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "clickEvents": [ + { + "__id__": 20 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "84c9SsOvlNuqqwtfx91Ol+" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "onClickTips", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "b0z4M59nZLL4w7oI1eOvGR", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_reward", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 3 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 23 + }, + { + "__id__": 25 + }, + { + "__id__": 27 + } + ], + "_prefab": { + "__id__": 30 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": -139, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 22 + }, + "_enabled": true, + "__prefab": { + "__id__": 24 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 119, + "height": 117 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "96hdW6mp9LyZBwuDutlpHC" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 22 + }, + "_enabled": true, + "__prefab": { + "__id__": 26 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "33qVBjJN5P9ZxSdhWBdn+9" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 22 + }, + "_enabled": true, + "__prefab": { + "__id__": 28 + }, + "clickEvents": [ + { + "__id__": 29 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "23q/qHGVBD+YDTkeVuj0JP" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "onClickRwHis", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "d5EWLydc5Ld4lZGQqHycXf", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 32 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 397, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "896ypyn1dMer+1KrKXbeaZ" + }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 34 + }, + "_resizeMode": 1, + "_layoutType": 1, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 0, + "_paddingRight": 0, + "_paddingTop": 0, + "_paddingBottom": 0, + "_spacingX": 20, + "_spacingY": 0, + "_verticalDirection": 1, + "_horizontalDirection": 1, + "_constraint": 0, + "_constraintNum": 2, + "_affectedByScale": false, + "_isAlign": true, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b1VhtDkqlGupwYHDc2b8bE" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": { + "__id__": 36 + }, + "_alignFlags": 33, + "_target": null, + "_left": 0, + "_right": 14, + "_top": 30, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e7xuazH95FbauhmmDUDOKl" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "ecuU/wqItCrJga8HPiXzNI", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg_box", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 39 + }, + { + "__id__": 54 + } + ], + "_active": true, + "_components": [ + { + "__id__": 58 + }, + { + "__id__": 60 + } + ], + "_prefab": { + "__id__": 62 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -385, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "btn_remain", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 38 + }, + "_children": [ + { + "__id__": 40 + } + ], + "_active": true, + "_components": [ + { + "__id__": 46 + }, + { + "__id__": 48 + }, + { + "__id__": 50 + } + ], + "_prefab": { + "__id__": 53 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "lab", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 39 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 41 + }, + { + "__id__": 43 + } + ], + "_prefab": { + "__id__": 45 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -44.958, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 40 + }, + "_enabled": true, + "__prefab": { + "__id__": 42 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 180, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "54y9NcOoVI4Z/h7orgLi9I" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 40 + }, + "_enabled": true, + "__prefab": { + "__id__": 44 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 67, + "g": 160, + "b": 255, + "a": 255 + }, + "_string": "CHANCE:100", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 29, + "_fontSize": 30, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8bn1FVkyhBB4U8AOZxTszB" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "bcJA1VODNHGLRdyY9wgwuy", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 39 + }, + "_enabled": true, + "__prefab": { + "__id__": 47 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 335, + "height": 345 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7ev6toP6RPWY4BxG9whx/l" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 39 + }, + "_enabled": true, + "__prefab": { + "__id__": 49 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "59e8aac3-ea8a-4bf1-bc34-998f7766b965@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "63SSqDMNxLWps2U76Q7nNP" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 39 + }, + "_enabled": true, + "__prefab": { + "__id__": 51 + }, + "clickEvents": [ + { + "__id__": 52 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "6eALcMfwlPSZ6miixQzlPu" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "onStartGame", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a6qLE0+HFEZKS0YD8L6h/z", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "box_list", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 38 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 55 + } + ], + "_prefab": { + "__id__": 57 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 54 + }, + "_enabled": true, + "__prefab": { + "__id__": 56 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1ffS0jYrlKHZWxigmMnHhv" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "c241mIyERGfoJc6tJpsjp/", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 38 + }, + "_enabled": true, + "__prefab": { + "__id__": 59 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1169 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "44Nzdw4H5A8a387dN0P6s6" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 38 + }, + "_enabled": true, + "__prefab": { + "__id__": 61 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "9e1afa58-b75a-41b2-9340-1134d40ef800@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e7DAGJBfRF/YZP7DrXws9R" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "91wUz56w1BaYXefwID94HR", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "main_icon_dio_1", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 64 + }, + { + "__id__": 66 + } + ], + "_prefab": { + "__id__": 68 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": -420, + "y": 385, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 63 + }, + "_enabled": true, + "__prefab": { + "__id__": 65 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 196, + "height": 150 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a67l87gQtCQbs1eV13jG99" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 63 + }, + "_enabled": true, + "__prefab": { + "__id__": 67 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "8bdde44e-263e-4494-8ecd-07be2039f5f6@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "84U1ZPcvpIBZ67as3GkEbq" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "c6T0xopz9KV45uPuE+xkkj", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "main_icon_dio_2", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 70 + }, + { + "__id__": 72 + } + ], + "_prefab": { + "__id__": 74 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 405, + "y": 530, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 69 + }, + "_enabled": true, + "__prefab": { + "__id__": 71 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 72, + "height": 66 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "feEvpP0wxIx7AT38rflweO" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 69 + }, + "_enabled": true, + "__prefab": { + "__id__": 73 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ee1PbuEFNAZ4cylTwldBYx" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "45Pmecq8pAFKibatlwC1XO", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "logo", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 76 + } + ], + "_active": true, + "_components": [ + { + "__id__": 82 + }, + { + "__id__": 84 + } + ], + "_prefab": { + "__id__": 86 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 485, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "logo", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 75 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 77 + }, + { + "__id__": 79 + } + ], + "_prefab": { + "__id__": 81 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -235, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 76 + }, + "_enabled": true, + "__prefab": { + "__id__": 78 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 357, + "height": 108 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "45fTegy+dLG6OmyKadrPdt" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 76 + }, + "_enabled": true, + "__prefab": { + "__id__": 80 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "afXUqYsgREP47lMQwWdsk+" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "10MNzOb/FDwJkGRjH4wDnW", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 75 + }, + "_enabled": true, + "__prefab": { + "__id__": 83 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 954, + "height": 805 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "9bIpIw2SdJ9J/nZ/+ZCsbh" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 75 + }, + "_enabled": true, + "__prefab": { + "__id__": 85 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "c1864093-fe69-4a27-9c0d-af1dbf554ed6@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "2diusO0xJP0oArPfPsOwRq" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "f9ZVqkmY5HgLfyLq3KWn+i", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "partical_snow", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 88 + }, + { + "__id__": 90 + }, + { + "__id__": 92 + } + ], + "_prefab": { + "__id__": 94 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 1020, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 87 + }, + "_enabled": true, + "__prefab": { + "__id__": 89 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c2iBH04FVFgKHGu7T5P0jo" + }, + { + "__type__": "cc.ParticleSystem2D", + "_name": "Node", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 87 + }, + "_enabled": true, + "__prefab": { + "__id__": 91 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 1, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "duration": -1, + "emissionRate": 200, + "life": 10, + "lifeVar": 10, + "angle": 360, + "angleVar": 360, + "startSize": 3, + "startSizeVar": 50, + "endSize": 30, + "endSizeVar": 10, + "startSpin": -47.369998931884766, + "startSpinVar": 0, + "endSpin": -47.369998931884766, + "endSpinVar": -142.11000061035156, + "sourcePos": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "posVar": { + "__type__": "cc.Vec2", + "x": 600, + "y": 10 + }, + "emitterMode": 0, + "gravity": { + "__type__": "cc.Vec2", + "x": 0, + "y": -500 + }, + "speed": 0, + "speedVar": 0, + "tangentialAccel": 0, + "tangentialAccelVar": 0, + "radialAccel": 0, + "radialAccelVar": 0, + "rotationIsDir": false, + "startRadius": 100, + "startRadiusVar": 0, + "endRadius": 0, + "endRadiusVar": 0, + "rotatePerS": 0, + "rotatePerSVar": 0, + "playOnLoad": true, + "autoRemoveOnFinish": false, + "_preview": true, + "preview": true, + "_custom": true, + "_file": null, + "_spriteFrame": { + "__uuid__": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_totalParticles": 500, + "_startColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 224 + }, + "_startColorVar": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "_endColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 180 + }, + "_endColorVar": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "_positionType": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a495/jvolHAbNemESKcGlb" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 87 + }, + "_enabled": true, + "__prefab": { + "__id__": 93 + }, + "_alignFlags": 1, + "_target": null, + "_left": 0, + "_right": 0, + "_top": -110, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f41tCANuFF8rPOgYd3m1Tc" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "0ftkCDHgxDOolp4Urp+vXl", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 96 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f0wS1MBeVC2qST1WgJNsb+" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 98 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ca1CEiO99ODLqV1afHRaOv" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 100 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 1080, + "_originalHeight": 1920, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f9Dv7o/0ZNNIc5F8GA7XQ0" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "e7vp3L/4RNUJbrPDn69Oi8", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg_rw", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 103 + }, + { + "__id__": 113 + }, + { + "__id__": 137 + }, + { + "__id__": 146 + } + ], + "_active": false, + "_components": [ + { + "__id__": 152 + }, + { + "__id__": 154 + }, + { + "__id__": 156 + } + ], + "_prefab": { + "__id__": 158 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "mask", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 102 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 104 + }, + { + "__id__": 106 + }, + { + "__id__": 108 + }, + { + "__id__": 110 + } + ], + "_prefab": { + "__id__": 112 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 103 + }, + "_enabled": true, + "__prefab": { + "__id__": 105 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "dbGJFlZ7FBB7F1atKRqZ8T" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 103 + }, + "_enabled": true, + "__prefab": { + "__id__": 107 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 163 + }, + "_spriteFrame": { + "__uuid__": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 1, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "80ZlSiSDNBEZtJkCnjKwPl" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 103 + }, + "_enabled": true, + "__prefab": { + "__id__": 109 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 2, + "_originalHeight": 2, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "99/nRhkQVCF7iQ0lPw0kGj" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 103 + }, + "_enabled": true, + "__prefab": { + "__id__": 111 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7emp6hdsRHYa5A92C9vTo5" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "02jElotXNA0JWlW4F9n9ab", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 102 + }, + "_children": [ + { + "__id__": 114 + }, + { + "__id__": 126 + } + ], + "_active": true, + "_components": [ + { + "__id__": 132 + }, + { + "__id__": 134 + } + ], + "_prefab": { + "__id__": 136 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "bg_lab", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 113 + }, + "_children": [ + { + "__id__": 115 + } + ], + "_active": true, + "_components": [ + { + "__id__": 121 + }, + { + "__id__": 123 + } + ], + "_prefab": { + "__id__": 125 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 88, + "y": -247, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "lab", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 114 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 116 + }, + { + "__id__": 118 + } + ], + "_prefab": { + "__id__": 120 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 115 + }, + "_enabled": true, + "__prefab": { + "__id__": 117 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 226.73828125, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c1iEwpF6BIEZBYL/Jemv22" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 115 + }, + "_enabled": true, + "__prefab": { + "__id__": 119 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 236, + "g": 254, + "b": 238, + "a": 255 + }, + "_string": "100 CREDIT", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 40, + "_fontSize": 40, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 0, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": true, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "2crLb0JYxASJj0bFD+iN2b" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "64mtwFschIO40nVGfgDnLj", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 114 + }, + "_enabled": true, + "__prefab": { + "__id__": 122 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 928, + "height": 95 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "dbrHp3+6BKz4q1X8TU6XpP" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 114 + }, + "_enabled": true, + "__prefab": { + "__id__": 124 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": null, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e0UoCILuJJ/pIJkdkfc7lQ" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a0y0AtlDpBHIcRRWZRpod2", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "icon", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 113 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 127 + }, + { + "__id__": 129 + } + ], + "_prefab": { + "__id__": 131 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 107, + "y": -50, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 126 + }, + "_enabled": true, + "__prefab": { + "__id__": 128 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 180, + "height": 180 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "6c3lQAKJ1JuZjWY5jEqinP" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 126 + }, + "_enabled": true, + "__prefab": { + "__id__": 130 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": null, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "90HSae421OQ40btCecUv9q" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "ce4YJzvExDu7lKzkT25O3p", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 113 + }, + "_enabled": true, + "__prefab": { + "__id__": 133 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 934 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "eclZZY5g1H+I1/5qlVy6BP" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 113 + }, + "_enabled": true, + "__prefab": { + "__id__": 135 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "14U/XixTNJgqq4Qksmi9uD" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "14MnHB3hlP3ZPdm1vCncaX", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_sure", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 102 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 138 + }, + { + "__id__": 140 + }, + { + "__id__": 142 + } + ], + "_prefab": { + "__id__": 145 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -620, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 137 + }, + "_enabled": true, + "__prefab": { + "__id__": 139 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 515, + "height": 191 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "40pMS13htJYobTi56eLFrm" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 137 + }, + "_enabled": true, + "__prefab": { + "__id__": 141 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "3c11c55b-7a54-49e4-aa32-d99c3002822e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d3mKDR6gRDmpz4/tYMyoiA" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 137 + }, + "_enabled": true, + "__prefab": { + "__id__": 143 + }, + "clickEvents": [ + { + "__id__": 144 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f6dowBXDlA2LcgFS9DKDh6" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "onClickRewardSure", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "38l1UK181HLaTBYjniMuAe", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 102 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 147 + }, + { + "__id__": 149 + } + ], + "_prefab": { + "__id__": 151 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 330, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 146 + }, + "_enabled": true, + "__prefab": { + "__id__": 148 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 907, + "height": 213 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "4cGf2U9txMHaEZCe71fVEv" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 146 + }, + "_enabled": true, + "__prefab": { + "__id__": 150 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "8b0af801-7117-437d-bd29-f1460c4e4ec4@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b2NlTJRQFN76TZ2Wxe3iYr" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "b8KK3KxxFEgqDYpAtRkIll", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 102 + }, + "_enabled": true, + "__prefab": { + "__id__": 153 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c8JkgZNnRJHpZ6YAWPVxSg" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 102 + }, + "_enabled": true, + "__prefab": { + "__id__": 155 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 2, + "_originalHeight": 2, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "2350NQjz1KI6WQv6hORKDy" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 102 + }, + "_enabled": true, + "__prefab": { + "__id__": 157 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "23wJ2dsRdFN4f5J64Amk7j" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "6dQuVkpRlMYJ7g0tRXoVCR", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg_no_rw", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 160 + }, + { + "__id__": 170 + } + ], + "_active": false, + "_components": [ + { + "__id__": 203 + }, + { + "__id__": 205 + }, + { + "__id__": 207 + } + ], + "_prefab": { + "__id__": 209 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "mask", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 159 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 161 + }, + { + "__id__": 163 + }, + { + "__id__": 165 + }, + { + "__id__": 167 + } + ], + "_prefab": { + "__id__": 169 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 160 + }, + "_enabled": true, + "__prefab": { + "__id__": 162 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "921waqHABOroU8FJqfv+vP" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 160 + }, + "_enabled": true, + "__prefab": { + "__id__": 164 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 162 + }, + "_spriteFrame": { + "__uuid__": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 1, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "13//D1CA1D4rwJrGPV4HEf" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 160 + }, + "_enabled": true, + "__prefab": { + "__id__": 166 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 2, + "_originalHeight": 2, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ecG9q7rkFGa531/lgXYA9X" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 160 + }, + "_enabled": true, + "__prefab": { + "__id__": 168 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "battEflx1FX7/fSRy3Gzut" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "1bmooKGqxOeb9rzJsi2mU4", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 159 + }, + "_children": [ + { + "__id__": 171 + }, + { + "__id__": 183 + }, + { + "__id__": 192 + } + ], + "_active": true, + "_components": [ + { + "__id__": 198 + }, + { + "__id__": 200 + } + ], + "_prefab": { + "__id__": 202 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "lab_bg", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 170 + }, + "_children": [ + { + "__id__": 172 + } + ], + "_active": true, + "_components": [ + { + "__id__": 178 + }, + { + "__id__": 180 + } + ], + "_prefab": { + "__id__": 182 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -362.67, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "Label", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 171 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 173 + }, + { + "__id__": 175 + } + ], + "_prefab": { + "__id__": 177 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 172 + }, + "_enabled": true, + "__prefab": { + "__id__": 174 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 579.736328125, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e1A/Xsy7ROrZoBgZZ7lAP/" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 172 + }, + "_enabled": true, + "__prefab": { + "__id__": 176 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_string": "Sorry, no prize this time.", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 50, + "_fontSize": 50, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 0, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": true, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "33EeRQvD5I/po5DWHi2JDo" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "36TAhrhLdDr7/SX1pCtkGs", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 171 + }, + "_enabled": true, + "__prefab": { + "__id__": 179 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 879, + "height": 86 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bfhEN2KRhGFpNiZqjgtxW8" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 171 + }, + "_enabled": true, + "__prefab": { + "__id__": 181 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "1bacdabd-ef9d-4be3-aee4-6a04882f4878@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d1Z2e0jIlDVKaBVv+wLFor" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "829xnVCG5KP4TSTHDEaVPl", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_sure", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 170 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 184 + }, + { + "__id__": 186 + }, + { + "__id__": 188 + } + ], + "_prefab": { + "__id__": 191 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -620, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 183 + }, + "_enabled": true, + "__prefab": { + "__id__": 185 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 515, + "height": 191 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "6ftXoW4jRIW59BPhE4IxYK" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 183 + }, + "_enabled": true, + "__prefab": { + "__id__": 187 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "88FUvb+PpNjZRtXYpB2j7R" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 183 + }, + "_enabled": true, + "__prefab": { + "__id__": 189 + }, + "clickEvents": [ + { + "__id__": 190 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d191HxvBlAc7HJ+fZU8hn7" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "5c1d6Gm/4FIG5IXQwohh/9Q", + "handler": "onClickRewardSure", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "adDYutSp5KNKttJBBJE6Ge", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 170 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 193 + }, + { + "__id__": 195 + } + ], + "_prefab": { + "__id__": 197 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 330, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 192 + }, + "_enabled": true, + "__prefab": { + "__id__": 194 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 986, + "height": 184 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "09Q5Llze9MtKrUx3WDIpKB" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 192 + }, + "_enabled": true, + "__prefab": { + "__id__": 196 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "4726b5e7-3f98-4702-95d7-9833b36b9c47@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "2ewoC8eytAvofNbgWZtBSf" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "85zYsQ98pLFqGxZtrpTSd9", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 170 + }, + "_enabled": true, + "__prefab": { + "__id__": 199 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1043, + "height": 1587 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "84fhd3Y69KQa7Wch+vdPtw" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 170 + }, + "_enabled": true, + "__prefab": { + "__id__": 201 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "b48a11de-b5fc-495a-9040-89e5d3fd874c@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1aTeVrBzJJ3YunsBdgchk5" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "cbUo4NC8ZLB4LnAQYdtk8I", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 159 + }, + "_enabled": true, + "__prefab": { + "__id__": 204 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8bErge52RJ0a3/uX42aLZq" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 159 + }, + "_enabled": true, + "__prefab": { + "__id__": 206 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 2, + "_originalHeight": 2, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a6yB1CIetDoYPExPGzL5xc" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 159 + }, + "_enabled": true, + "__prefab": { + "__id__": 208 + }, + "clickEvents": [], + "_interactable": true, + "_transition": 0, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 1.2, + "_target": { + "__id__": 159 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "48uZ3Z5EpOmrV5u9RFOpTa" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "87L8rEjHJLYqB7q6OWEwy9", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "box_item", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 211 + }, + { + "__id__": 217 + }, + { + "__id__": 223 + } + ], + "_active": false, + "_components": [ + { + "__id__": 229 + }, + { + "__id__": 231 + } + ], + "_prefab": { + "__id__": 233 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": -310, + "y": -60, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "select", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 210 + }, + "_children": [], + "_active": false, + "_components": [ + { + "__id__": 212 + }, + { + "__id__": 214 + } + ], + "_prefab": { + "__id__": 216 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 211 + }, + "_enabled": true, + "__prefab": { + "__id__": 213 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 281, + "height": 294 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "eczMJav6VJa45eEpekLAxt" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 211 + }, + "_enabled": true, + "__prefab": { + "__id__": 215 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "7818a295-f828-4ba0-b359-612ce7e4e0b8@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "96c2zz4cZAxpPnHzZ39DTW" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "e6t7G+7JlPepmqkxrBC2lB", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "icon", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 210 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 218 + }, + { + "__id__": 220 + } + ], + "_prefab": { + "__id__": 222 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 35, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 217 + }, + "_enabled": true, + "__prefab": { + "__id__": 219 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 180, + "height": 180 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b1jiYcD7JNEZT+rUtX7cMu" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 217 + }, + "_enabled": true, + "__prefab": { + "__id__": 221 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": null, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3adzpcmB5KeYMkIlx3nkNE" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "bdawajh4VE07Dk02aZpEJ9", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "lab", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 210 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 224 + }, + { + "__id__": 226 + } + ], + "_prefab": { + "__id__": 228 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -90, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 223 + }, + "_enabled": true, + "__prefab": { + "__id__": 225 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 200, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "0125iZyrNLTayv2Wf+hhBF" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 223 + }, + "_enabled": true, + "__prefab": { + "__id__": 227 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 238, + "g": 254, + "b": 255, + "a": 255 + }, + "_string": "", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 27, + "_fontSize": 26, + "_fontFamily": "Arial", + "_lineHeight": 26, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": true, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "fez3n3nPpHD7buc/MKTax9" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "86Ug6Xc+1I1YB63g+tyPR0", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 210 + }, + "_enabled": true, + "__prefab": { + "__id__": 230 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 281, + "height": 294 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "57I43KhLJDE40GW8YRpPKu" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 210 + }, + "_enabled": true, + "__prefab": { + "__id__": 232 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bbq65ps+tMqY2Vjl0ktnOz" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "6bXPtU8LlKiZ9g9IOYIexQ", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "5c1d6Gm/4FIG5IXQwohh/9Q", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 235 + }, + "_hideEvent": 1, + "_singleton": true, + "_captureFocus": true, + "_shade": false, + "_blockInput": true, + "_alwaysExist": true, + "btn_music": { + "__id__": 4 + }, + "lab_rw": { + "__id__": 118 + }, + "reward_bg": { + "__id__": 102 + }, + "noreward_bg": { + "__id__": 159 + }, + "box_item": { + "__id__": 210 + }, + "list_box": { + "__id__": 54 + }, + "icon_rw": { + "__id__": 129 + }, + "lab_remain": { + "__id__": 43 + }, + "diomand": [ + { + "__id__": 63 + }, + { + "__id__": 69 + } + ], + "logo": { + "__id__": 75 + }, + "game_logo": { + "__id__": 79 + }, + "game_logo_bg": { + "__id__": 84 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "70ggeL6RdBvb3k6EFfOvBi" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 237 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "93kLNYVP5I3YSkAXyvc+8y" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 239 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "beSbf3LfhHg4Z7OdUM5hMf" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "181hznodBBtYZzEfaJaWeP", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/native/PageMain.prefab.meta b/assets/app-bundle/app-view/page/main/native/PageMain.prefab.meta new file mode 100644 index 0000000..e9e8eb9 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/PageMain.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "4892f711-598c-44a7-888d-fb1ceb7ae920", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "PageMain" + } +} diff --git a/assets/app-bundle/app-view/page/main/native/PageMain.ts b/assets/app-bundle/app-view/page/main/native/PageMain.ts new file mode 100644 index 0000000..300d471 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/PageMain.ts @@ -0,0 +1,303 @@ +import { _decorator, Node, tween, Vec3, Sprite, Asset, ImageAsset, SpriteFrame, Texture2D, Label, EventTouch, UITransform } from 'cc'; +import BaseView from '../../../../../../extensions/app/assets/base/BaseView'; +import { PageTips } from '../../tips/native/PageTips'; +import { app } from 'db://assets/app/app'; +import { PageRewardhistory } from '../../rewardhistory/native/PageRewardhistory'; +import { Tools } from 'db://assets/res-native/tools/Tools'; +import { USERDATA } from 'db://assets/res-native/data/UserData'; +const { ccclass, property } = _decorator; +@ccclass('PageMain') +export class PageMain extends BaseView { + /** 音乐按钮 */ + @property(Node) + btn_music: Node = null!; + /** 奖励文字 */ + @property(Label) + lab_rw: Label = null!; + /** 奖励 */ + @property(Node) + reward_bg: Node = null!; + /** 奖励 */ + @property(Node) + noreward_bg: Node = null!; + /** 宝箱item */ + @property(Node) + box_item: Node = null!; + /** 宝箱列表 */ + @property(Node) + list_box: Node = null!; + /** 奖励icon */ + @property(Sprite) + icon_rw: Sprite = null!; + /** 剩余次数 */ + @property(Label) + lab_remain: Label = null!; + /** 钻石 */ + @property(Node) + diomand: Node[] = []; + /** 钻石 */ + @property(Node) + logo: Node = null!; + /** 奖励icon */ + @property(Sprite) + game_logo: Sprite = null!; + /** 奖励icon */ + @property(Sprite) + game_logo_bg: Sprite = null!; + + /** 宝箱位置 */ + private _position: { [key: number]: Vec3 } = { + 0: new Vec3(-310, 320, 0), + 1: new Vec3(0, 320, 0), + 2: new Vec3(310, 320, 0), + 3: new Vec3(310, 0, 0), + 4: new Vec3(310, -320, 0), + 5: new Vec3(0, -320, 0), + 6: new Vec3(-310, -320, 0), + 7: new Vec3(-310, 0, 0), + }; + + /** 是否可以开始游戏 */ + private _canStart = true; + /** 宝箱管理 */ + private _boxMgr : Node[] = [] + + /** 是否正在播放动画 */ + private _isSpinning: boolean = false; + + + // 初始化的相关逻辑写在这 + onLoad() {} + + // 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对) + onShow(params: any) { + this.lab_remain.string = "CHANCE:" + USERDATA.point.toString() + this.initRw() + this.startAnimation() + + // 加载配置的logo + if (USERDATA.logo && this.game_logo) { + Tools.remoteLoadSprite(USERDATA.logo, this.game_logo) + } + + if (USERDATA.logo_back && this.game_logo_bg) { + Tools.remoteLoadSprite(USERDATA.logo_back, this.game_logo_bg) + } + } + + // 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide) + onHide(result: undefined) { + // app.manager.ui.show({name: 'PageMain', onHide:(result) => { 接收到return的数据,并且有类型提示 }}) + return result; + } + + startAnimation(){ + // 钻石上下移动动画 + this.diomand.forEach((diamond, index) => { + if (diamond) { + tween(diamond) + .repeatForever( + tween() + .by(0.5, { position: new Vec3(0, 10, 0) }) + .by(0.5, { position: new Vec3(0, -10, 0) }) + ) + .start(); + } + }); + + // Logo放大缩小动画 + if (this.logo) { + tween(this.logo) + .repeatForever( + tween() + .to(0.8, { scale: new Vec3(1.1, 1.1, 1) }) + .to(0.8, { scale: new Vec3(1, 1, 1) }) + ) + .start(); + } + } + + initRw(){ + this._boxMgr = [] + for (let i = 0; i < 8; i++) { + this._boxMgr[i] = Tools.AddChild(this.list_box, this.box_item, "item_" + i) + let item = this._boxMgr[i] + item.setPosition(this._position[i]) + item.active = true + if (USERDATA.prize_list[i]){ + Tools.remoteLoadSprite(USERDATA.prize_list[i].pic, Tools.GetChildComp(item, "icon", Sprite)) + Tools.SetChildText(item, "lab", USERDATA.prize_list[i].name) + } + } + this._canStart = true + } + + + /** 点击奖励确定 */ + onClickRewardSure(){ + this.reward_bg.active = false + this.noreward_bg.active = false + this._canStart = true + } + + /** 点击提示 */ + onClickTips(){ + app.manager.ui.show({name: 'PageTips'}) + } + + /** 点击音乐 */ + oncClickMusic(){ + let music = app.manager.sound.isMusicPlaying + music ? app.manager.sound.stopMusic() : app.manager.sound.playDefaultMusic() + this.loadSprite(music ? "main_btn_sounds_off" : "main_btn_sounds_on", this.btn_music) + } + + /** 点击历史 */ + onClickRwHis(){ + app.manager.ui.show({name: 'PageRewardhistory'}) + } + + /** 点击开始 */ + onStartGame() { + if (!this._canStart) return; + if (USERDATA.point <= 0) { + app.manager.ui.showToast(Tools.GetLocalized("no chance")); + return; + } + + this._canStart = false; + + Tools.httpReq("lottery", {}, (res:any)=>{ + let n = this.checkRwId(res.prize_id) + if (n == null){ + app.manager.ui.showToast(Tools.GetLocalized("fail")) + return + } + + USERDATA.point-- + this.lab_remain.string = "CHANCE:" + USERDATA.point.toString() + this.lab_rw.string = Tools.StringLFormat(res.message) + Tools.remoteLoadSprite(USERDATA.prize_list[n].pic, this.icon_rw) + + // 开始转格子动画 + this.startSpinAnimation(n, res.prize_type); + },()=>{ + this._canStart = true; + }) + } + + checkRwId(prize_id: number){ + let n = null + for (let i = 0; i < USERDATA.prize_list.length; i++) { + const element = USERDATA.prize_list[i]; + if (prize_id == element.id){ + n = i + break + } + } + return n + } + + loadSprite(pic: string, node: Node){ + this.loadRes(pic, Asset, (res: ImageAsset)=>{ + let sp = new SpriteFrame() + let tex = new Texture2D(); + tex.image = res; + sp.texture = tex + node.getComponent(Sprite).spriteFrame = sp + }); + } + + + + /** + * 开始转格子动画 + * @param targetIndex 目标格子索引 + */ + private startSpinAnimation(targetIndex: number, prize_type:number) { + if (this._isSpinning) return; + + this._isSpinning = true; + + // 先清除所有高亮 + this.clearAllHighlights(); + + // 开始动画 - 至少转3圈再停到目标位置 + const totalSpins = 3; + const totalSteps = totalSpins * 8 + targetIndex; + + this.spinStep(0, totalSteps, targetIndex, prize_type); + } + + + /** + * 执行旋转步骤 + * @param currentStep 当前步数 + * @param totalSteps 总步数 + * @param targetIndex 目标索引 + * @param prize_type 奖品类型 + */ + private spinStep(currentStep: number, totalSteps: number, targetIndex: number, prize_type:number) { + if (currentStep >= totalSteps) { + // 动画结束 - 确保目标格子高亮 + this.clearAllHighlights(); + this.highlightBox(targetIndex); + + this._isSpinning = false; + + // 延迟显示奖励面板 + this.scheduleOnce(() => { + this.reward_bg.active = prize_type != 3; + this.noreward_bg.active = prize_type == 3; + app.manager.sound.playEffect({name: 'effect/win'}); + }, 0.5); + + return; + } + + // 计算当前应该高亮的格子索引 + const currentIndex = currentStep % 8; + + // 清除之前高亮并设置新的高亮 + this.clearAllHighlights(); + this.highlightBox(currentIndex); + + // 根据进度调整速度(越接近终点越慢) + let delay = 100; // 默认速度 + const remainingSteps = totalSteps - currentStep; + + if (remainingSteps < 8) { + delay = 200 + (8 - remainingSteps) * 50; // 最后几帧逐渐变慢 + } + + // 继续下一步动画 + this.scheduleOnce(() => { + app.manager.sound.playEffect({name: 'effect/jump'}); + + this.spinStep(currentStep + 1, totalSteps, targetIndex, prize_type); + }, delay / 1000); // scheduleOnce 使用秒为单位 + } + + /** + * 高亮指定格子 + * @param index 格子索引 + */ + private highlightBox(index: number) { + if (index < 0 || index >= this._boxMgr.length) return; + + const boxNode = this._boxMgr[index]; + if (boxNode) { + Tools.ActChild(boxNode, "select", true); + } + } + + /** + * 清除所有格子的高亮状态 + */ + private clearAllHighlights() { + for (let i = 0; i < this._boxMgr.length; i++) { + const boxNode = this._boxMgr[i]; + Tools.ActChild(boxNode, "select", false); + } + } +} \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/native/PageMain.ts.meta b/assets/app-bundle/app-view/page/main/native/PageMain.ts.meta new file mode 100644 index 0000000..20d636e --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/PageMain.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "5c1d61a6-ff81-481b-9217-430a2187ff50", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/main/native/expansion.meta b/assets/app-bundle/app-view/page/main/native/expansion.meta new file mode 100644 index 0000000..4ea6788 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/expansion.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "bdb63f02-2584-4780-ab06-23ee67be4568", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/main/native/expansion/.expansion.md b/assets/app-bundle/app-view/page/main/native/expansion/.expansion.md new file mode 100644 index 0000000..90942bb --- /dev/null +++ b/assets/app-bundle/app-view/page/main/native/expansion/.expansion.md @@ -0,0 +1,2 @@ +1、只能存放脚本⚠️ +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/resources.meta b/assets/app-bundle/app-view/page/main/resources.meta new file mode 100644 index 0000000..2625f4f --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "a99733dc-4564-4361-bf0a-458cf9eaf630", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_11aBEBWDxI/6ryvKvFthEo", + "priority": 4, + "bundleName": "page-main-res" + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/.resources.md b/assets/app-bundle/app-view/page/main/resources/.resources.md new file mode 100644 index 0000000..e07958e --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/.resources.md @@ -0,0 +1,6 @@ +UI资源目录 +1、脚本资源一定不要放在此文件夹内🔥 +2、资源会随着UI销毁自动释放 +3、在UI脚本内可通过this.loadRes动态加载 +4、在UI子节点的脚本内可通过app.manager.ui.loadRes(this, ...)动态加载 +5、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png b/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png new file mode 100644 index 0000000..fdf9e6a Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png.meta b/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png.meta new file mode 100644 index 0000000..27ec491 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/mai_btn_remain.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "59e8aac3-ea8a-4bf1-bc34-998f7766b965", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "59e8aac3-ea8a-4bf1-bc34-998f7766b965@6c48a", + "displayName": "mai_btn_remain", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "59e8aac3-ea8a-4bf1-bc34-998f7766b965", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "59e8aac3-ea8a-4bf1-bc34-998f7766b965@f9941", + "displayName": "mai_btn_remain", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": -3.5, + "offsetY": 1, + "trimX": 0, + "trimY": 0, + "width": 335, + "height": 345, + "rawWidth": 342, + "rawHeight": 347, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -167.5, + -172.5, + 0, + 167.5, + -172.5, + 0, + -167.5, + 172.5, + 0, + 167.5, + 172.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 347, + 335, + 347, + 0, + 2, + 335, + 2 + ], + "nuv": [ + 0, + 0.005763688760806916, + 0.97953216374269, + 0.005763688760806916, + 0, + 1, + 0.97953216374269, + 1 + ], + "minPos": [ + -167.5, + -172.5, + 0 + ], + "maxPos": [ + 167.5, + 172.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "59e8aac3-ea8a-4bf1-bc34-998f7766b965@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "59e8aac3-ea8a-4bf1-bc34-998f7766b965@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg.png b/assets/app-bundle/app-view/page/main/resources/main_bg.png new file mode 100644 index 0000000..467289f Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg.png.meta new file mode 100644 index 0000000..b48ac77 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d@6c48a", + "displayName": "main_bg", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d@f9941", + "displayName": "main_bg", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 1080, + "height": 1920, + "rawWidth": 1080, + "rawHeight": 1920, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -540, + -960, + 0, + 540, + -960, + 0, + -540, + 960, + 0, + 540, + 960, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 1920, + 1080, + 1920, + 0, + 0, + 1080, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -540, + -960, + 0 + ], + "maxPos": [ + 540, + 960, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": false, + "fixAlphaTransparencyArtifacts": false, + "redirect": "c6bfc33f-9fd1-43af-9d7c-60d13b21df2d@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_box.png b/assets/app-bundle/app-view/page/main/resources/main_bg_box.png new file mode 100644 index 0000000..65427e3 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg_box.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_box.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg_box.png.meta new file mode 100644 index 0000000..05b7b40 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg_box.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "9e1afa58-b75a-41b2-9340-1134d40ef800", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "9e1afa58-b75a-41b2-9340-1134d40ef800@6c48a", + "displayName": "main_bg_box", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "9e1afa58-b75a-41b2-9340-1134d40ef800", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "9e1afa58-b75a-41b2-9340-1134d40ef800@f9941", + "displayName": "main_bg_box", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": -32, + "trimX": 0, + "trimY": 64, + "width": 1080, + "height": 1169, + "rawWidth": 1080, + "rawHeight": 1233, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -540, + -584.5, + 0, + 540, + -584.5, + 0, + -540, + 584.5, + 0, + 540, + 584.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 1169, + 1080, + 1169, + 0, + 0, + 1080, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 0.9480940794809408, + 1, + 0.9480940794809408 + ], + "minPos": [ + -540, + -584.5, + 0 + ], + "maxPos": [ + 540, + 584.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "9e1afa58-b75a-41b2-9340-1134d40ef800@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "9e1afa58-b75a-41b2-9340-1134d40ef800@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png b/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png new file mode 100644 index 0000000..a77fd64 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png.meta new file mode 100644 index 0000000..68e5a10 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg_box_select.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "7818a295-f828-4ba0-b359-612ce7e4e0b8", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "7818a295-f828-4ba0-b359-612ce7e4e0b8@6c48a", + "displayName": "main_bg_box_select", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "7818a295-f828-4ba0-b359-612ce7e4e0b8", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "7818a295-f828-4ba0-b359-612ce7e4e0b8@f9941", + "displayName": "main_bg_box_select", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": -0.5, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 281, + "height": 294, + "rawWidth": 282, + "rawHeight": 294, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -140.5, + -147, + 0, + 140.5, + -147, + 0, + -140.5, + 147, + 0, + 140.5, + 147, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 294, + 281, + 294, + 0, + 0, + 281, + 0 + ], + "nuv": [ + 0, + 0, + 0.9964539007092199, + 0, + 0, + 1, + 0.9964539007092199, + 1 + ], + "minPos": [ + -140.5, + -147, + 0 + ], + "maxPos": [ + 140.5, + 147, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "7818a295-f828-4ba0-b359-612ce7e4e0b8@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "7818a295-f828-4ba0-b359-612ce7e4e0b8@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_card.png b/assets/app-bundle/app-view/page/main/resources/main_bg_card.png new file mode 100644 index 0000000..1a411ef Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg_card.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_card.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg_card.png.meta new file mode 100644 index 0000000..1b75666 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg_card.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde@6c48a", + "displayName": "main_bg_card", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde@f9941", + "displayName": "main_bg_card", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": -0.5, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 281, + "height": 294, + "rawWidth": 282, + "rawHeight": 294, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -140.5, + -147, + 0, + 140.5, + -147, + 0, + -140.5, + 147, + 0, + 140.5, + 147, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 294, + 281, + 294, + 0, + 0, + 281, + 0 + ], + "nuv": [ + 0, + 0, + 0.9964539007092199, + 0, + 0, + 1, + 0.9964539007092199, + 1 + ], + "minPos": [ + -140.5, + -147, + 0 + ], + "maxPos": [ + 140.5, + 147, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "45225fa4-0af9-4d51-b6bc-8192e9b8bbde@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png b/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png new file mode 100644 index 0000000..857f87c Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png.meta new file mode 100644 index 0000000..1aa46c5 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg_logo.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93@6c48a", + "displayName": "main_bg_logo", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93@f9941", + "displayName": "main_bg_logo", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0.5, + "trimX": 1, + "trimY": 0, + "width": 357, + "height": 108, + "rawWidth": 359, + "rawHeight": 109, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -178.5, + -54, + 0, + 178.5, + -54, + 0, + -178.5, + 54, + 0, + 178.5, + 54, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 1, + 109, + 358, + 109, + 1, + 1, + 358, + 1 + ], + "nuv": [ + 0.002785515320334262, + 0.009174311926605505, + 0.9972144846796658, + 0.009174311926605505, + 0.002785515320334262, + 1, + 0.9972144846796658, + 1 + ], + "minPos": [ + -178.5, + -54, + 0 + ], + "maxPos": [ + 178.5, + 54, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "a407e8b4-a4b9-4ef2-958e-a8ae098b5d93@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png b/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png new file mode 100644 index 0000000..b1b8358 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png.meta b/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png.meta new file mode 100644 index 0000000..76d95fe --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_bg_rw.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861@6c48a", + "displayName": "main_bg_rw", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861@f9941", + "displayName": "main_bg_rw", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 1080, + "height": 934, + "rawWidth": 1080, + "rawHeight": 934, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -540, + -467, + 0, + 540, + -467, + 0, + -540, + 467, + 0, + 540, + 467, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 934, + 1080, + 934, + 0, + 0, + 1080, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -540, + -467, + 0 + ], + "maxPos": [ + 540, + 467, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "fa6f2ba4-2e7c-4186-ae18-fa5c78b58861@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png b/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png new file mode 100644 index 0000000..09151b0 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png.meta b/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png.meta new file mode 100644 index 0000000..685ba4c --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_btn_reward.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0@6c48a", + "displayName": "main_btn_reward", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0@f9941", + "displayName": "main_btn_reward", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": -0.5, + "trimX": 0, + "trimY": 1, + "width": 119, + "height": 117, + "rawWidth": 119, + "rawHeight": 118, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -59.5, + -58.5, + 0, + 59.5, + -58.5, + 0, + -59.5, + 58.5, + 0, + 59.5, + 58.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 117, + 119, + 117, + 0, + 0, + 119, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 0.9915254237288136, + 1, + 0.9915254237288136 + ], + "minPos": [ + -59.5, + -58.5, + 0 + ], + "maxPos": [ + 59.5, + 58.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "658b2f1e-7429-4c65-9a9d-8ba14adf34a0@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png b/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png new file mode 100644 index 0000000..f5b57cb Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png.meta b/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png.meta new file mode 100644 index 0000000..11c376f --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_btn_rw_sure.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "3c11c55b-7a54-49e4-aa32-d99c3002822e", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "3c11c55b-7a54-49e4-aa32-d99c3002822e@6c48a", + "displayName": "main_btn_rw_sure", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "3c11c55b-7a54-49e4-aa32-d99c3002822e", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "3c11c55b-7a54-49e4-aa32-d99c3002822e@f9941", + "displayName": "main_btn_rw_sure", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 458, + "height": 184, + "rawWidth": 458, + "rawHeight": 184, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -229, + -92, + 0, + 229, + -92, + 0, + -229, + 92, + 0, + 229, + 92, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 184, + 458, + 184, + 0, + 0, + 458, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -229, + -92, + 0 + ], + "maxPos": [ + 229, + 92, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "3c11c55b-7a54-49e4-aa32-d99c3002822e@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "3c11c55b-7a54-49e4-aa32-d99c3002822e@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png new file mode 100644 index 0000000..7557923 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png.meta b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png.meta new file mode 100644 index 0000000..49ecefc --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_off.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3@6c48a", + "displayName": "main_btn_sounds_off", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3@f9941", + "displayName": "main_btn_sounds_off", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": -0.5, + "trimX": 0, + "trimY": 1, + "width": 119, + "height": 117, + "rawWidth": 119, + "rawHeight": 118, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -59.5, + -58.5, + 0, + 59.5, + -58.5, + 0, + -59.5, + 58.5, + 0, + 59.5, + 58.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 117, + 119, + 117, + 0, + 0, + 119, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 0.9915254237288136, + 1, + 0.9915254237288136 + ], + "minPos": [ + -59.5, + -58.5, + 0 + ], + "maxPos": [ + 59.5, + 58.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "482daa8e-3325-4cdf-ae00-bebb26f7a9a3@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png new file mode 100644 index 0000000..138aae3 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png.meta b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png.meta new file mode 100644 index 0000000..f2013ce --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_btn_sounds_on.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "f76d4098-86bb-4d85-8e5b-beb06b7308f2", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "f76d4098-86bb-4d85-8e5b-beb06b7308f2@6c48a", + "displayName": "main_btn_sounds_on", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "f76d4098-86bb-4d85-8e5b-beb06b7308f2", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "f76d4098-86bb-4d85-8e5b-beb06b7308f2@f9941", + "displayName": "main_btn_sounds_on", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": -0.5, + "trimX": 0, + "trimY": 1, + "width": 119, + "height": 117, + "rawWidth": 119, + "rawHeight": 118, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -59.5, + -58.5, + 0, + 59.5, + -58.5, + 0, + -59.5, + 58.5, + 0, + 59.5, + 58.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 117, + 119, + 117, + 0, + 0, + 119, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 0.9915254237288136, + 1, + 0.9915254237288136 + ], + "minPos": [ + -59.5, + -58.5, + 0 + ], + "maxPos": [ + 59.5, + 58.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "f76d4098-86bb-4d85-8e5b-beb06b7308f2@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "f76d4098-86bb-4d85-8e5b-beb06b7308f2@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png b/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png new file mode 100644 index 0000000..cc8c71d Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png.meta b/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png.meta new file mode 100644 index 0000000..25dd8a2 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_btn_tips.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "5b600712-8704-49cd-9f95-5f013387a423", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "5b600712-8704-49cd-9f95-5f013387a423@6c48a", + "displayName": "main_btn_tips", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "5b600712-8704-49cd-9f95-5f013387a423", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "5b600712-8704-49cd-9f95-5f013387a423@f9941", + "displayName": "main_btn_tips", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": -0.5, + "trimX": 0, + "trimY": 1, + "width": 119, + "height": 117, + "rawWidth": 119, + "rawHeight": 118, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -59.5, + -58.5, + 0, + 59.5, + -58.5, + 0, + -59.5, + 58.5, + 0, + 59.5, + 58.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 117, + 119, + 117, + 0, + 0, + 119, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 0.9915254237288136, + 1, + 0.9915254237288136 + ], + "minPos": [ + -59.5, + -58.5, + 0 + ], + "maxPos": [ + 59.5, + 58.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "5b600712-8704-49cd-9f95-5f013387a423@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "5b600712-8704-49cd-9f95-5f013387a423@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png new file mode 100644 index 0000000..db3cbe2 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png.meta b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png.meta new file mode 100644 index 0000000..178c281 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_1.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "8bdde44e-263e-4494-8ecd-07be2039f5f6", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "8bdde44e-263e-4494-8ecd-07be2039f5f6@6c48a", + "displayName": "main_icon_dio_1", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "8bdde44e-263e-4494-8ecd-07be2039f5f6", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "8bdde44e-263e-4494-8ecd-07be2039f5f6@f9941", + "displayName": "main_icon_dio_1", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 196, + "height": 150, + "rawWidth": 196, + "rawHeight": 150, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -98, + -75, + 0, + 98, + -75, + 0, + -98, + 75, + 0, + 98, + 75, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 150, + 196, + 150, + 0, + 0, + 196, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -98, + -75, + 0 + ], + "maxPos": [ + 98, + 75, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "8bdde44e-263e-4494-8ecd-07be2039f5f6@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "8bdde44e-263e-4494-8ecd-07be2039f5f6@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png new file mode 100644 index 0000000..b0f6d5b Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png.meta b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png.meta new file mode 100644 index 0000000..42b2623 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_icon_dio_2.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe@6c48a", + "displayName": "main_icon_dio_2", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe@f9941", + "displayName": "main_icon_dio_2", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 72, + "height": 66, + "rawWidth": 72, + "rawHeight": 66, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -36, + -33, + 0, + 36, + -33, + 0, + -36, + 33, + 0, + 36, + 33, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 66, + 72, + 66, + 0, + 0, + 72, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -36, + -33, + 0 + ], + "maxPos": [ + 36, + 33, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "c4fe11ea-e93a-41c1-89ab-0c15b3c99bfe@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png b/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png new file mode 100644 index 0000000..88e4438 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png.meta b/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png.meta new file mode 100644 index 0000000..af94725 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_lab_rw_title.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "8b0af801-7117-437d-bd29-f1460c4e4ec4", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "8b0af801-7117-437d-bd29-f1460c4e4ec4@6c48a", + "displayName": "main_lab_rw_title", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "8b0af801-7117-437d-bd29-f1460c4e4ec4", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "8b0af801-7117-437d-bd29-f1460c4e4ec4@f9941", + "displayName": "main_lab_rw_title", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": -0.5, + "offsetY": 0, + "trimX": 0, + "trimY": 1, + "width": 907, + "height": 213, + "rawWidth": 908, + "rawHeight": 215, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -453.5, + -106.5, + 0, + 453.5, + -106.5, + 0, + -453.5, + 106.5, + 0, + 453.5, + 106.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 214, + 907, + 214, + 0, + 1, + 907, + 1 + ], + "nuv": [ + 0, + 0.004651162790697674, + 0.998898678414097, + 0.004651162790697674, + 0, + 0.9953488372093023, + 0.998898678414097, + 0.9953488372093023 + ], + "minPos": [ + -453.5, + -106.5, + 0 + ], + "maxPos": [ + 453.5, + 106.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "8b0af801-7117-437d-bd29-f1460c4e4ec4@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "8b0af801-7117-437d-bd29-f1460c4e4ec4@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_logo.png b/assets/app-bundle/app-view/page/main/resources/main_logo.png new file mode 100644 index 0000000..8fa440e Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_logo.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_logo.png.meta b/assets/app-bundle/app-view/page/main/resources/main_logo.png.meta new file mode 100644 index 0000000..74439cd --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_logo.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "c1864093-fe69-4a27-9c0d-af1dbf554ed6", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "c1864093-fe69-4a27-9c0d-af1dbf554ed6@6c48a", + "displayName": "main_logo", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "c1864093-fe69-4a27-9c0d-af1dbf554ed6", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "c1864093-fe69-4a27-9c0d-af1dbf554ed6@f9941", + "displayName": "main_logo", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 954, + "height": 805, + "rawWidth": 954, + "rawHeight": 805, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -477, + -402.5, + 0, + 477, + -402.5, + 0, + -477, + 402.5, + 0, + 477, + 402.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 805, + 954, + 805, + 0, + 0, + 954, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -477, + -402.5, + 0 + ], + "maxPos": [ + 477, + 402.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "c1864093-fe69-4a27-9c0d-af1dbf554ed6@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "c1864093-fe69-4a27-9c0d-af1dbf554ed6@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png b/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png new file mode 100644 index 0000000..2157b2e Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png.meta b/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png.meta new file mode 100644 index 0000000..379795d --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_norw_btn.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87@6c48a", + "displayName": "main_norw_btn", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87@f9941", + "displayName": "main_norw_btn", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 458, + "height": 184, + "rawWidth": 458, + "rawHeight": 184, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -229, + -92, + 0, + 229, + -92, + 0, + -229, + 92, + 0, + 229, + 92, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 184, + 458, + 184, + 0, + 0, + 458, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -229, + -92, + 0 + ], + "maxPos": [ + 229, + 92, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "a2189ef6-e9f7-42b7-b49b-f4ffb925ce87@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png b/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png new file mode 100644 index 0000000..a5b8b2b Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png.meta b/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png.meta new file mode 100644 index 0000000..da0188d --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_norw_icon.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "b48a11de-b5fc-495a-9040-89e5d3fd874c", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "b48a11de-b5fc-495a-9040-89e5d3fd874c@6c48a", + "displayName": "main_norw_icon", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "b48a11de-b5fc-495a-9040-89e5d3fd874c", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "b48a11de-b5fc-495a-9040-89e5d3fd874c@f9941", + "displayName": "main_norw_icon", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 8.5, + "offsetY": 137.5, + "trimX": 25, + "trimY": 29, + "width": 1043, + "height": 1587, + "rawWidth": 1076, + "rawHeight": 1920, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -521.5, + -793.5, + 0, + 521.5, + -793.5, + 0, + -521.5, + 793.5, + 0, + 521.5, + 793.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 25, + 1891, + 1068, + 1891, + 25, + 304, + 1068, + 304 + ], + "nuv": [ + 0.023234200743494422, + 0.15833333333333333, + 0.9925650557620818, + 0.15833333333333333, + 0.023234200743494422, + 0.9848958333333333, + 0.9925650557620818, + 0.9848958333333333 + ], + "minPos": [ + -521.5, + -793.5, + 0 + ], + "maxPos": [ + 521.5, + 793.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "b48a11de-b5fc-495a-9040-89e5d3fd874c@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "b48a11de-b5fc-495a-9040-89e5d3fd874c@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png b/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png new file mode 100644 index 0000000..9ea3156 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png.meta b/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png.meta new file mode 100644 index 0000000..94f9581 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_norw_lab.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "4726b5e7-3f98-4702-95d7-9833b36b9c47", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "4726b5e7-3f98-4702-95d7-9833b36b9c47@6c48a", + "displayName": "main_norw_lab", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "4726b5e7-3f98-4702-95d7-9833b36b9c47", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "4726b5e7-3f98-4702-95d7-9833b36b9c47@f9941", + "displayName": "main_norw_lab", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 986, + "height": 184, + "rawWidth": 986, + "rawHeight": 184, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -493, + -92, + 0, + 493, + -92, + 0, + -493, + 92, + 0, + 493, + 92, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 184, + 986, + 184, + 0, + 0, + 986, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -493, + -92, + 0 + ], + "maxPos": [ + 493, + 92, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "4726b5e7-3f98-4702-95d7-9833b36b9c47@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "4726b5e7-3f98-4702-95d7-9833b36b9c47@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png b/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png new file mode 100644 index 0000000..0538057 Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png.meta b/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png.meta new file mode 100644 index 0000000..1223c26 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_norw_lab_bg.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "1bacdabd-ef9d-4be3-aee4-6a04882f4878", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "1bacdabd-ef9d-4be3-aee4-6a04882f4878@6c48a", + "displayName": "main_norw_lab_bg", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "1bacdabd-ef9d-4be3-aee4-6a04882f4878", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "1bacdabd-ef9d-4be3-aee4-6a04882f4878@f9941", + "displayName": "main_norw_lab_bg", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 879, + "height": 86, + "rawWidth": 879, + "rawHeight": 86, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -439.5, + -43, + 0, + 439.5, + -43, + 0, + -439.5, + 43, + 0, + 439.5, + 43, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 86, + 879, + 86, + 0, + 0, + 879, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -439.5, + -43, + 0 + ], + "maxPos": [ + 439.5, + 43, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "1bacdabd-ef9d-4be3-aee4-6a04882f4878@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "1bacdabd-ef9d-4be3-aee4-6a04882f4878@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/main_snow.png b/assets/app-bundle/app-view/page/main/resources/main_snow.png new file mode 100644 index 0000000..075498b Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/main_snow.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/main_snow.png.meta b/assets/app-bundle/app-view/page/main/resources/main_snow.png.meta new file mode 100644 index 0000000..a9ebadd --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/main_snow.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571@6c48a", + "displayName": "main_snow", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571@f9941", + "displayName": "main_snow", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 14.5, + "offsetY": -9, + "trimX": 77, + "trimY": 120, + "width": 275, + "height": 311, + "rawWidth": 400, + "rawHeight": 533, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -137.5, + -155.5, + 0, + 137.5, + -155.5, + 0, + -137.5, + 155.5, + 0, + 137.5, + 155.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 77, + 413, + 352, + 413, + 77, + 102, + 352, + 102 + ], + "nuv": [ + 0.1925, + 0.19136960600375236, + 0.88, + 0.19136960600375236, + 0.1925, + 0.774859287054409, + 0.88, + 0.774859287054409 + ], + "minPos": [ + -137.5, + -155.5, + 0 + ], + "maxPos": [ + 137.5, + 155.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "20b0b7c3-7492-45b9-8d6e-1d1d312e0571@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/main/resources/singleColor.png b/assets/app-bundle/app-view/page/main/resources/singleColor.png new file mode 100644 index 0000000..fa6376e Binary files /dev/null and b/assets/app-bundle/app-view/page/main/resources/singleColor.png differ diff --git a/assets/app-bundle/app-view/page/main/resources/singleColor.png.meta b/assets/app-bundle/app-view/page/main/resources/singleColor.png.meta new file mode 100644 index 0000000..737ea18 --- /dev/null +++ b/assets/app-bundle/app-view/page/main/resources/singleColor.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@6c48a", + "displayName": "singleColor", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@f9941", + "displayName": "singleColor", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 2, + "height": 2, + "rawWidth": 2, + "rawHeight": 2, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -1, + -1, + 0, + 1, + -1, + 0, + -1, + 1, + 0, + 1, + 1, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 2, + 2, + 2, + 0, + 0, + 2, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -1, + -1, + 0 + ], + "maxPos": [ + 1, + 1, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": false, + "fixAlphaTransparencyArtifacts": false, + "redirect": "3b5a4365-09ed-46db-bdb4-c1dc2d3b806b@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory.meta b/assets/app-bundle/app-view/page/rewardhistory.meta new file mode 100644 index 0000000..a526077 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "169756bf-bc5f-471b-8200-c13e4a174b8e", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/.rewardhistory.md b/assets/app-bundle/app-view/page/rewardhistory/.rewardhistory.md new file mode 100644 index 0000000..91f3f8c --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/.rewardhistory.md @@ -0,0 +1,3 @@ +PageRewardhistory所在文件夹 +1、通过app.manager.ui.show({ name:'PageRewardhistory' })的方式加载 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/native.meta b/assets/app-bundle/app-view/page/rewardhistory/native.meta new file mode 100644 index 0000000..b7024e6 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "e76f98d3-131d-48aa-bbd5-a1fc99406971", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_f7NI9WxFVIO6e8LbJGF72k", + "priority": 1, + "bundleName": "page-rewardhistory" + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/.native.md b/assets/app-bundle/app-view/page/rewardhistory/native/.native.md new file mode 100644 index 0000000..fbfda3c --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/.native.md @@ -0,0 +1,4 @@ +存放UI以及脚本的文件夹 +1、除了UI本身外,不允许存放其它任何预置体或场景资源🔥 +2、UI脚本在根目录下,其它脚本放到expansion目录下 +3、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab new file mode 100644 index 0000000..ee2a0a9 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab @@ -0,0 +1,2423 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "PageRewardhistory", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "PageRewardhistory", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 10 + }, + { + "__id__": 63 + } + ], + "_active": true, + "_components": [ + { + "__id__": 99 + }, + { + "__id__": 101 + }, + { + "__id__": 103 + } + ], + "_prefab": { + "__id__": 105 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "mask", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bffYXjGadNB7Q4+PI/QoIF" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7cRCi+2JVIPbbMKk3eVKfp" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 150 + }, + "_spriteFrame": { + "__uuid__": "f02366ec-9682-4417-87b0-bd9723cb4041@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7aZEEniLZLnoT2A6qDMGfE" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "bbqnhfc8RA8aXR1wCSgaxy", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "rehis_bg", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 11 + }, + { + "__id__": 17 + }, + { + "__id__": 23 + }, + { + "__id__": 34 + } + ], + "_active": true, + "_components": [ + { + "__id__": 58 + }, + { + "__id__": 60 + } + ], + "_prefab": { + "__id__": 62 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "rehis_icon", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 12 + }, + { + "__id__": 14 + } + ], + "_prefab": { + "__id__": 16 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 502, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 11 + }, + "_enabled": true, + "__prefab": { + "__id__": 13 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 841, + "height": 362 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "32OvmziOtEvZxKLUiMYsjF" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 11 + }, + "_enabled": true, + "__prefab": { + "__id__": 15 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "4e96f507-f26d-4701-a9a4-912f7547b295@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1fSh9XTYJFEKc1W2xCpgDF" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "30sN1g0INEQ6tJnGr4ctEU", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "rehis_bg_title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 18 + }, + { + "__id__": 20 + } + ], + "_prefab": { + "__id__": 22 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 710, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 17 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 775, + "height": 197 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a1GKjezwlJSJnN7pe9xqLJ" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 17 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "2f12e860-64f6-462e-b3a0-eb4d04dfec81@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "984eQoJG9DX5FV3uH1n2PL" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "36np2mmfVGS4ROL8gu3fv8", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_close", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 24 + }, + { + "__id__": 26 + }, + { + "__id__": 28 + }, + { + "__id__": 30 + } + ], + "_prefab": { + "__id__": 33 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 415, + "y": 608, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 25 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 125, + "height": 125 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3bs6eCETFKzYTMMb53B9n2" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 27 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "381a00f4-28a8-42d0-b9cb-cb658a3bc139@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "69YgQPdGZKpK1htY243dkH" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 29 + }, + "_alignFlags": 33, + "_target": null, + "_left": 0, + "_right": -26, + "_top": 41, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "80ALlTPLBFNrNvhpkQYKPM" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 31 + }, + "clickEvents": [ + { + "__id__": 32 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "02hBBBYaxEPJVtzXIX+TQH" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "a70db4PkldMrqJCkQvJdOTQ", + "handler": "hide", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a2aT9KQWRHAoC5YWwCC8Aw", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "rw_list", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [ + { + "__id__": 35 + } + ], + "_active": true, + "_components": [ + { + "__id__": 51 + }, + { + "__id__": 53 + }, + { + "__id__": 55 + } + ], + "_prefab": { + "__id__": 57 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -165, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "mask", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 34 + }, + "_children": [ + { + "__id__": 36 + } + ], + "_active": true, + "_components": [ + { + "__id__": 42 + }, + { + "__id__": 44 + }, + { + "__id__": 46 + }, + { + "__id__": 48 + } + ], + "_prefab": { + "__id__": 50 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "content", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 35 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 37 + }, + { + "__id__": 39 + } + ], + "_prefab": { + "__id__": 41 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 596, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 36 + }, + "_enabled": true, + "__prefab": { + "__id__": 38 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": -30 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 1 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c5R0L9MrBJZrzT+2sQTjhl" + }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 36 + }, + "_enabled": true, + "__prefab": { + "__id__": 40 + }, + "_resizeMode": 1, + "_layoutType": 2, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 0, + "_paddingRight": 0, + "_paddingTop": 0, + "_paddingBottom": 0, + "_spacingX": 0, + "_spacingY": 30, + "_verticalDirection": 1, + "_horizontalDirection": 0, + "_constraint": 0, + "_constraintNum": 2, + "_affectedByScale": false, + "_isAlign": false, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c20JVpkGFH9ZQrsnjUP7J1" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "adwgBXFMJHP6vbTClSkkcv", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 35 + }, + "_enabled": true, + "__prefab": { + "__id__": 43 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 743, + "height": 920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "dfecdW6XZH4rtvJ4XNsqvn" + }, + { + "__type__": "cc.Mask", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 35 + }, + "_enabled": true, + "__prefab": { + "__id__": 45 + }, + "_type": 0, + "_inverted": false, + "_segments": 64, + "_alphaThreshold": 0.1, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "9cXLtOWxFAi7aY7KonSggx" + }, + { + "__type__": "cc.Graphics", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 35 + }, + "_enabled": true, + "__prefab": { + "__id__": 47 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_lineWidth": 1, + "_strokeColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_lineJoin": 2, + "_lineCap": 0, + "_fillColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 0 + }, + "_miterLimit": 10, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "13TM5Y/e1IiLSO90FdQfVR" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 35 + }, + "_enabled": true, + "__prefab": { + "__id__": 49 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "eaipPus09CE47pOj0qhOJ3" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "626PlbjDVN/5DyH4A13Hbo", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 52 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 743, + "height": 920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "87EV8TcYxOU4q32+Rca4yo" + }, + { + "__type__": "cc.ScrollView", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 54 + }, + "bounceDuration": 1, + "brake": 0.5, + "elastic": true, + "inertia": true, + "horizontal": false, + "vertical": true, + "cancelInnerEvents": true, + "scrollEvents": [], + "_content": { + "__id__": 36 + }, + "_horizontalScrollBar": null, + "_verticalScrollBar": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "77Yv3wlQpK1KCIl+GZVf+P" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 56 + }, + "_alignFlags": 45, + "_target": null, + "_left": 80, + "_right": 80, + "_top": 416.5, + "_bottom": 86.50000000000006, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bfLCQyoshOuJK46743VnVw" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "7chrvFK39HT7lXWyIdpNHV", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 59 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 903, + "height": 1423 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8bBpxEqYlOBbTY+5sAe0wj" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 61 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8cJTs+KZNODIWRuB6R4Qcc" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "aeI23Z1VFFHbej1+bcDfxJ", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "rw_item", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 64 + }, + { + "__id__": 76 + }, + { + "__id__": 82 + }, + { + "__id__": 88 + } + ], + "_active": false, + "_components": [ + { + "__id__": 94 + }, + { + "__id__": 96 + } + ], + "_prefab": { + "__id__": 98 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "rehis_bg_rw", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 63 + }, + "_children": [ + { + "__id__": 65 + } + ], + "_active": true, + "_components": [ + { + "__id__": 71 + }, + { + "__id__": 73 + } + ], + "_prefab": { + "__id__": 75 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": -228.041, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "icon", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 64 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 66 + }, + { + "__id__": 68 + } + ], + "_prefab": { + "__id__": 70 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 65 + }, + "_enabled": true, + "__prefab": { + "__id__": 67 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 136, + "height": 135 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "9eJIwEfKVN7ZjkTTxdPEhW" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 65 + }, + "_enabled": true, + "__prefab": { + "__id__": 69 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": null, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "daSNSwwHFBo51DBDnYrYVf" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "ebADOrCZhMm4etSoWUvB7w", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 64 + }, + "_enabled": true, + "__prefab": { + "__id__": 72 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 259, + "height": 225 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "81G7eldpxJ3ppKZ8P9hkPf" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 64 + }, + "_enabled": true, + "__prefab": { + "__id__": 74 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "2305111f-e56f-4991-8aac-e10282bc8b86@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 1, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f4tK6bBplAMbGC2GPdKezH" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "6fBetE+YhHaIsM9ozM2HLs", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "lab_num", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 63 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 77 + }, + { + "__id__": 79 + } + ], + "_prefab": { + "__id__": 81 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 60, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 76 + }, + "_enabled": true, + "__prefab": { + "__id__": 78 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 400, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b70p2VMCZPm7AEeTP27on1" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 76 + }, + "_enabled": true, + "__prefab": { + "__id__": 80 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 254, + "b": 228, + "a": 255 + }, + "_string": "50 Credits", + "_horizontalAlign": 0, + "_verticalAlign": 1, + "_actualFontSize": 47, + "_fontSize": 46, + "_fontFamily": "Arial", + "_lineHeight": 46, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": true, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": true, + "_shadowColor": { + "__type__": "cc.Color", + "r": 7, + "g": 43, + "b": 83, + "a": 134 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "54F83KoqVCtI0BFr62hprZ" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a9isNGzsZLMr75cXd8J/j+", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "lab_time_title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 63 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 83 + }, + { + "__id__": 85 + } + ], + "_prefab": { + "__id__": 87 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -20, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 82 + }, + "_enabled": true, + "__prefab": { + "__id__": 84 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 300, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "68yXRYR6tKjLomSWMi/Ltl" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 82 + }, + "_enabled": true, + "__prefab": { + "__id__": 86 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 64, + "g": 229, + "b": 254, + "a": 255 + }, + "_string": "Obtain Time:", + "_horizontalAlign": 0, + "_verticalAlign": 1, + "_actualFontSize": 29, + "_fontSize": 28, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3eTBI9VzVCn7bERganRT8e" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "60wH7WTQdKXp6CoZ1OUbk+", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "lab_time", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 63 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 89 + }, + { + "__id__": 91 + } + ], + "_prefab": { + "__id__": 93 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -60, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 88 + }, + "_enabled": true, + "__prefab": { + "__id__": 90 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 300, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "5bxHv7aA1BL7dB0hqsxwod" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 88 + }, + "_enabled": true, + "__prefab": { + "__id__": 92 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_string": "2025-06-06 12:33:33", + "_horizontalAlign": 0, + "_verticalAlign": 1, + "_actualFontSize": 29, + "_fontSize": 28, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "ebNOJUgtBO6q1/3SWWWyHu" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "7aBrKuUghLXaJlAwDPvCrB", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 63 + }, + "_enabled": true, + "__prefab": { + "__id__": 95 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 805, + "height": 294 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "91RRU2DW9IZouOvD6QIqhT" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 63 + }, + "_enabled": true, + "__prefab": { + "__id__": 97 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "9f6qaYWzRMxKruomyp/IkF" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "0e35HmFcBAvqnvHR0uCSOh", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "a70db4PkldMrqJCkQvJdOTQ", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 100 + }, + "_hideEvent": 2, + "_singleton": true, + "_captureFocus": true, + "_shade": false, + "_blockInput": true, + "_alwaysExist": false, + "rw_item": { + "__id__": 63 + }, + "rw_list": { + "__id__": 53 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "689lCMjJZJI4uUV6znpRKN" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 102 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7ba1ZyY9tHo4Hrq2Ww9Oa6" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 104 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "744gmrD/dAUoVkMgrOfyML" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "68C1xdSS5HCqj8JNp7fqdk", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab.meta b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab.meta new file mode 100644 index 0000000..2543b3b --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "5231a223-7efb-466d-849b-e506ffbf58bf", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "PageRewardhistory" + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts new file mode 100644 index 0000000..83d1357 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts @@ -0,0 +1,39 @@ +import { _decorator, Node, ScrollView, Sprite } from 'cc'; +import BaseView from '../../../../../../extensions/app/assets/base/BaseView'; +import { Tools } from 'db://assets/res-native/tools/Tools'; +const { ccclass, property } = _decorator; +@ccclass('PageRewardhistory') +export class PageRewardhistory extends BaseView { + @property(Node) + rw_item: Node = null!; + @property(ScrollView) + rw_list: ScrollView = null!; + + // 初始化的相关逻辑写在这 + onLoad() {} + + // 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对) + onShow(params: any) { + this.initRw() + } + + initRw() { + this.rw_list.content.removeAllChildren() + Tools.httpReq("draw-records", {}, (res:any)=>{ + for (let i = 0; i < res.length; i++) { + let d = res[i] + let item = Tools.AddChild(this.rw_list.content, this.rw_item, "item" + i); + Tools.SetChildText(item, "lab_num", d.prize_name) + Tools.SetChildText(item, "lab_time", d.draw_time) + Tools.remoteLoadSprite(d.prize_pic, Tools.GetChildComp(item, "rehis_bg_rw/icon", Sprite)) + item.active = true; + } + }) + } + + // 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide) + onHide(result: undefined) { + // app.manager.ui.show({name: 'PageRewardhistory', onHide:(result) => { 接收到return的数据,并且有类型提示 }}) + return result; + } +} \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts.meta b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts.meta new file mode 100644 index 0000000..ba32fcd --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/PageRewardhistory.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "a70dbe0f-9257-4cae-a242-910bc974e4d0", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/expansion.meta b/assets/app-bundle/app-view/page/rewardhistory/native/expansion.meta new file mode 100644 index 0000000..24b516d --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/expansion.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "cb733b05-a6d4-4c8c-a674-9e1dd4ad3084", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/native/expansion/.expansion.md b/assets/app-bundle/app-view/page/rewardhistory/native/expansion/.expansion.md new file mode 100644 index 0000000..90942bb --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/native/expansion/.expansion.md @@ -0,0 +1,2 @@ +1、只能存放脚本⚠️ +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources.meta b/assets/app-bundle/app-view/page/rewardhistory/resources.meta new file mode 100644 index 0000000..e837f76 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "ede1d7ef-2b9f-48e9-b21a-107727dba4e0", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_11aBEBWDxI/6ryvKvFthEo", + "priority": 4, + "bundleName": "page-rewardhistory-res" + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/.resources.md b/assets/app-bundle/app-view/page/rewardhistory/resources/.resources.md new file mode 100644 index 0000000..e07958e --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/.resources.md @@ -0,0 +1,6 @@ +UI资源目录 +1、脚本资源一定不要放在此文件夹内🔥 +2、资源会随着UI销毁自动释放 +3、在UI脚本内可通过this.loadRes动态加载 +4、在UI子节点的脚本内可通过app.manager.ui.loadRes(this, ...)动态加载 +5、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png new file mode 100644 index 0000000..ce2f8ea Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png.meta new file mode 100644 index 0000000..6bafe11 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f@6c48a", + "displayName": "rehis_bg", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f@f9941", + "displayName": "rehis_bg", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 903, + "height": 1423, + "rawWidth": 903, + "rawHeight": 1423, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -451.5, + -711.5, + 0, + 451.5, + -711.5, + 0, + -451.5, + 711.5, + 0, + 451.5, + 711.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 1423, + 903, + 1423, + 0, + 0, + 903, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -451.5, + -711.5, + 0 + ], + "maxPos": [ + 451.5, + 711.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "5198c377-3de0-4ac4-ab9e-81a5c3b85c9f@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png new file mode 100644 index 0000000..7aaeaf3 Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png.meta new file mode 100644 index 0000000..d7d2126 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_bg_rw.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "2305111f-e56f-4991-8aac-e10282bc8b86", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "2305111f-e56f-4991-8aac-e10282bc8b86@6c48a", + "displayName": "rehis_bg_rw", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "2305111f-e56f-4991-8aac-e10282bc8b86", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "2305111f-e56f-4991-8aac-e10282bc8b86@f9941", + "displayName": "rehis_bg_rw", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 1, + "trimY": 1, + "width": 259, + "height": 225, + "rawWidth": 261, + "rawHeight": 227, + "borderTop": 132, + "borderBottom": 93, + "borderLeft": 132, + "borderRight": 127, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -129.5, + -112.5, + 0, + 129.5, + -112.5, + 0, + -129.5, + 112.5, + 0, + 129.5, + 112.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 1, + 226, + 260, + 226, + 1, + 1, + 260, + 1 + ], + "nuv": [ + 0.0038314176245210726, + 0.004405286343612335, + 0.9961685823754789, + 0.004405286343612335, + 0.0038314176245210726, + 0.9955947136563876, + 0.9961685823754789, + 0.9955947136563876 + ], + "minPos": [ + -129.5, + -112.5, + 0 + ], + "maxPos": [ + 129.5, + 112.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "2305111f-e56f-4991-8aac-e10282bc8b86@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "2305111f-e56f-4991-8aac-e10282bc8b86@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png new file mode 100644 index 0000000..e96494e Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png.meta new file mode 100644 index 0000000..7e647eb --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_btn_close.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "381a00f4-28a8-42d0-b9cb-cb658a3bc139", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "381a00f4-28a8-42d0-b9cb-cb658a3bc139@6c48a", + "displayName": "rehis_btn_close", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "381a00f4-28a8-42d0-b9cb-cb658a3bc139", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "381a00f4-28a8-42d0-b9cb-cb658a3bc139@f9941", + "displayName": "rehis_btn_close", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 125, + "height": 125, + "rawWidth": 125, + "rawHeight": 125, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -62.5, + -62.5, + 0, + 62.5, + -62.5, + 0, + -62.5, + 62.5, + 0, + 62.5, + 62.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 125, + 125, + 125, + 0, + 0, + 125, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -62.5, + -62.5, + 0 + ], + "maxPos": [ + 62.5, + 62.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "381a00f4-28a8-42d0-b9cb-cb658a3bc139@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "381a00f4-28a8-42d0-b9cb-cb658a3bc139@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png new file mode 100644 index 0000000..8653a64 Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png.meta new file mode 100644 index 0000000..cedad1f --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_icon.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "4e96f507-f26d-4701-a9a4-912f7547b295", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "4e96f507-f26d-4701-a9a4-912f7547b295@6c48a", + "displayName": "rehis_icon", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "4e96f507-f26d-4701-a9a4-912f7547b295", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "4e96f507-f26d-4701-a9a4-912f7547b295@f9941", + "displayName": "rehis_icon", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 841, + "height": 362, + "rawWidth": 841, + "rawHeight": 362, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -420.5, + -181, + 0, + 420.5, + -181, + 0, + -420.5, + 181, + 0, + 420.5, + 181, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 362, + 841, + 362, + 0, + 0, + 841, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -420.5, + -181, + 0 + ], + "maxPos": [ + 420.5, + 181, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "4e96f507-f26d-4701-a9a4-912f7547b295@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "4e96f507-f26d-4701-a9a4-912f7547b295@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png new file mode 100644 index 0000000..4c6b8cc Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png.meta new file mode 100644 index 0000000..42fbf23 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_rw_bg.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8@6c48a", + "displayName": "rehis_rw_bg", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8@f9941", + "displayName": "rehis_rw_bg", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 805, + "height": 294, + "rawWidth": 805, + "rawHeight": 294, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -402.5, + -147, + 0, + 402.5, + -147, + 0, + -402.5, + 147, + 0, + 402.5, + 147, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 294, + 805, + 294, + 0, + 0, + 805, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -402.5, + -147, + 0 + ], + "maxPos": [ + 402.5, + 147, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "2f833d48-cce6-4b5e-bcc3-de30bfa9ebc8@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png new file mode 100644 index 0000000..4f46592 Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png.meta new file mode 100644 index 0000000..e3c44df --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/rehis_title.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "2f12e860-64f6-462e-b3a0-eb4d04dfec81", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "2f12e860-64f6-462e-b3a0-eb4d04dfec81@6c48a", + "displayName": "rehis_title", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "2f12e860-64f6-462e-b3a0-eb4d04dfec81", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "2f12e860-64f6-462e-b3a0-eb4d04dfec81@f9941", + "displayName": "rehis_title", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 769, + "height": 212, + "rawWidth": 769, + "rawHeight": 212, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -384.5, + -106, + 0, + 384.5, + -106, + 0, + -384.5, + 106, + 0, + 384.5, + 106, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 212, + 769, + 212, + 0, + 0, + 769, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -384.5, + -106, + 0 + ], + "maxPos": [ + 384.5, + 106, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "2f12e860-64f6-462e-b3a0-eb4d04dfec81@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "2f12e860-64f6-462e-b3a0-eb4d04dfec81@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png b/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png new file mode 100644 index 0000000..fa6376e Binary files /dev/null and b/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png differ diff --git a/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png.meta b/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png.meta new file mode 100644 index 0000000..a77eb52 --- /dev/null +++ b/assets/app-bundle/app-view/page/rewardhistory/resources/singleColor.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "f02366ec-9682-4417-87b0-bd9723cb4041", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "f02366ec-9682-4417-87b0-bd9723cb4041@6c48a", + "displayName": "singleColor", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "f02366ec-9682-4417-87b0-bd9723cb4041", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "f02366ec-9682-4417-87b0-bd9723cb4041@f9941", + "displayName": "singleColor", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 2, + "height": 2, + "rawWidth": 2, + "rawHeight": 2, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -1, + -1, + 0, + 1, + -1, + 0, + -1, + 1, + 0, + 1, + 1, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 2, + 2, + 2, + 0, + 0, + 2, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -1, + -1, + 0 + ], + "maxPos": [ + 1, + 1, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "f02366ec-9682-4417-87b0-bd9723cb4041@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": false, + "fixAlphaTransparencyArtifacts": false, + "redirect": "f02366ec-9682-4417-87b0-bd9723cb4041@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/tips.meta b/assets/app-bundle/app-view/page/tips.meta new file mode 100644 index 0000000..1559f16 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "09e2d82a-3d4f-4102-b780-de9ea86f192b", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/tips/.tips.md b/assets/app-bundle/app-view/page/tips/.tips.md new file mode 100644 index 0000000..fd7600b --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/.tips.md @@ -0,0 +1,3 @@ +PageTips所在文件夹 +1、通过app.manager.ui.show({ name:'PageTips' })的方式加载 +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/native.meta b/assets/app-bundle/app-view/page/tips/native.meta new file mode 100644 index 0000000..a64c4b4 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "4ed45723-cb84-4213-9fde-d70ce968b9b0", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_f7NI9WxFVIO6e8LbJGF72k", + "priority": 1, + "bundleName": "page-tips" + } +} diff --git a/assets/app-bundle/app-view/page/tips/native/.native.md b/assets/app-bundle/app-view/page/tips/native/.native.md new file mode 100644 index 0000000..fbfda3c --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/.native.md @@ -0,0 +1,4 @@ +存放UI以及脚本的文件夹 +1、除了UI本身外,不允许存放其它任何预置体或场景资源🔥 +2、UI脚本在根目录下,其它脚本放到expansion目录下 +3、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/native/PageTips.prefab b/assets/app-bundle/app-view/page/tips/native/PageTips.prefab new file mode 100644 index 0000000..ccf4e42 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/PageTips.prefab @@ -0,0 +1,1218 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "PageTips", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "PageTips", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 10 + } + ], + "_active": true, + "_components": [ + { + "__id__": 47 + }, + { + "__id__": 49 + }, + { + "__id__": 51 + } + ], + "_prefab": { + "__id__": 53 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "mask", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "855hhnaT9AHLxt7GxEQCL8" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 150 + }, + "_spriteFrame": { + "__uuid__": "06c69eac-72f1-4cf9-938e-ece19602cc55@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d0VapTGlhL44GLDGmoMHIi" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1aLpquux9Dob4Ar9pF7GYh" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "d0CzyElo5AOI+9uKiojWR3", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "bg", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 11 + }, + { + "__id__": 23 + }, + { + "__id__": 34 + } + ], + "_active": true, + "_components": [ + { + "__id__": 42 + }, + { + "__id__": 44 + } + ], + "_prefab": { + "__id__": 46 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "tips_bg_title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [ + { + "__id__": 12 + } + ], + "_active": true, + "_components": [ + { + "__id__": 18 + }, + { + "__id__": 20 + } + ], + "_prefab": { + "__id__": 22 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 760, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 11 + }, + "_children": [], + "_active": false, + "_components": [ + { + "__id__": 13 + }, + { + "__id__": 15 + } + ], + "_prefab": { + "__id__": 17 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 15, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 12 + }, + "_enabled": true, + "__prefab": { + "__id__": 14 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 882, + "height": 214 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e6bFRknSRAV6SOBlTbQbE5" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 12 + }, + "_enabled": true, + "__prefab": { + "__id__": 16 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "f28663c8-a56e-4250-bc32-12e6ec054846@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "34QGt3dJ1De4Ky5PX7dhEc" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "ccSv3OFI5JMI2YR4/vJJH0", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 11 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 772, + "height": 193 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "10k+HQ+dhEOpv+h1gNkMpj" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 11 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "f28663c8-a56e-4250-bc32-12e6ec054846@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "64wrR76RpGh66GmfFhXwGs" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "8cdTt93QFJQ47qdk9zWm47", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "btn_close", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 24 + }, + { + "__id__": 26 + }, + { + "__id__": 28 + }, + { + "__id__": 30 + } + ], + "_prefab": { + "__id__": 33 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 415, + "y": 608, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 25 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 125, + "height": 125 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c81oaqd/hFMJbTtvIOpb7a" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 27 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "e4c4a51f-4906-4750-92fa-eda8ea787e68@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e32xl/XVNMw4Mux/FhoJHg" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 29 + }, + "_alignFlags": 33, + "_target": null, + "_left": 0, + "_right": -26, + "_top": 41, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a77EROo3VIyIVVyfiCA3gh" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 23 + }, + "_enabled": true, + "__prefab": { + "__id__": 31 + }, + "clickEvents": [ + { + "__id__": 32 + } + ], + "_interactable": true, + "_transition": 3, + "_normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_hoverColor": { + "__type__": "cc.Color", + "r": 211, + "g": 211, + "b": 211, + "a": 255 + }, + "_pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_disabledColor": { + "__type__": "cc.Color", + "r": 124, + "g": 124, + "b": 124, + "a": 255 + }, + "_normalSprite": null, + "_hoverSprite": null, + "_pressedSprite": null, + "_disabledSprite": null, + "_duration": 0.1, + "_zoomScale": 0.96, + "_target": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "41MXh67GBHSaRHn+G95VLq" + }, + { + "__type__": "cc.ClickEvent", + "target": { + "__id__": 1 + }, + "component": "", + "_componentId": "79948hibTlEY5RVGpx/edvj", + "handler": "hide", + "customEventData": "" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "a7p8qYyWlARb/S9yiHW8xE", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "lab_tips", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 35 + }, + { + "__id__": 37 + }, + { + "__id__": 39 + } + ], + "_prefab": { + "__id__": 41 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -25, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 36 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 663, + "height": 1073 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "4buQ/O/8VKfqYQlwSjTu2D" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 38 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 201, + "g": 235, + "b": 255, + "a": 255 + }, + "_string": "", + "_horizontalAlign": 0, + "_verticalAlign": 0, + "_actualFontSize": 33, + "_fontSize": 32, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 2, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "abLDZbR01A+Z/f720dYtxZ" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 34 + }, + "_enabled": true, + "__prefab": { + "__id__": 40 + }, + "_alignFlags": 45, + "_target": null, + "_left": 120, + "_right": 120, + "_top": 200, + "_bottom": 150, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 700, + "_originalHeight": 400, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "95NfXeQS1GaqBmpbIGFS9v" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "99FUHm8JhMHK4TbR9+XfqB", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 43 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 903, + "height": 1423 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "73lVCMbLRPRJ7jqVFJXNn+" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 45 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 1, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bfPwi6E+VBTKSgAzV1+snk" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "b31L8f7wxDCZX14TH8RZ2P", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "79948hibTlEY5RVGpx/edvj", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 48 + }, + "_hideEvent": 2, + "_singleton": true, + "_captureFocus": true, + "_shade": false, + "_blockInput": true, + "_alwaysExist": false, + "lab_tips": { + "__id__": 37 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "61DG2Hhm9Lf7Z9V9XAwcZD" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 50 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e1RBJlY5BO27PDlfslJaia" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 52 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f09VrsjTNCgKly1ztpB1Gx" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "13R0oe3xFAmrvlQLMv2EeI", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/native/PageTips.prefab.meta b/assets/app-bundle/app-view/page/tips/native/PageTips.prefab.meta new file mode 100644 index 0000000..be91713 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/PageTips.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "f8f8b7ef-6d55-4b2e-997d-fb96104ac47d", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "PageTips" + } +} diff --git a/assets/app-bundle/app-view/page/tips/native/PageTips.ts b/assets/app-bundle/app-view/page/tips/native/PageTips.ts new file mode 100644 index 0000000..b6b11a3 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/PageTips.ts @@ -0,0 +1,24 @@ +import { _decorator, Label, Node } from 'cc'; +import BaseView from '../../../../../../extensions/app/assets/base/BaseView'; +import { USERDATA } from 'db://assets/res-native/data/UserData'; +const { ccclass, property } = _decorator; +@ccclass('PageTips') +export class PageTips extends BaseView { + /** tips */ + @property(Label) + lab_tips: Label = null!; + + // 初始化的相关逻辑写在这 + onLoad() {} + + // 界面打开时的相关逻辑写在这(onShow可被多次调用-它与onHide不成对) + onShow(params: any) { + this.lab_tips.string = USERDATA.description + } + + // 界面关闭时的相关逻辑写在这(已经关闭的界面不会触发onHide) + onHide(result: undefined) { + // app.manager.ui.show({name: 'PageTips', onHide:(result) => { 接收到return的数据,并且有类型提示 }}) + return result; + } +} \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/native/PageTips.ts.meta b/assets/app-bundle/app-view/page/tips/native/PageTips.ts.meta new file mode 100644 index 0000000..c28ad68 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/PageTips.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "79948862-6d39-4463-9455-1a9c7f79dbe3", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/tips/native/expansion.meta b/assets/app-bundle/app-view/page/tips/native/expansion.meta new file mode 100644 index 0000000..8cd4830 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/expansion.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "d5c2c247-b89a-42bc-a389-290ca94b79d9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app-bundle/app-view/page/tips/native/expansion/.expansion.md b/assets/app-bundle/app-view/page/tips/native/expansion/.expansion.md new file mode 100644 index 0000000..90942bb --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/native/expansion/.expansion.md @@ -0,0 +1,2 @@ +1、只能存放脚本⚠️ +2、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/resources.meta b/assets/app-bundle/app-view/page/tips/resources.meta new file mode 100644 index 0000000..e3821c6 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources.meta @@ -0,0 +1,14 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "bc281800-ee8d-4ec9-bd7d-1373ede53490", + "files": [], + "subMetas": {}, + "userData": { + "isBundle": true, + "bundleConfigID": "auto_11aBEBWDxI/6ryvKvFthEo", + "priority": 4, + "bundleName": "page-tips-res" + } +} diff --git a/assets/app-bundle/app-view/page/tips/resources/.resources.md b/assets/app-bundle/app-view/page/tips/resources/.resources.md new file mode 100644 index 0000000..e07958e --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources/.resources.md @@ -0,0 +1,6 @@ +UI资源目录 +1、脚本资源一定不要放在此文件夹内🔥 +2、资源会随着UI销毁自动释放 +3、在UI脚本内可通过this.loadRes动态加载 +4、在UI子节点的脚本内可通过app.manager.ui.loadRes(this, ...)动态加载 +5、不可单独删除此文件夹 \ No newline at end of file diff --git a/assets/app-bundle/app-view/page/tips/resources/singleColor.png b/assets/app-bundle/app-view/page/tips/resources/singleColor.png new file mode 100644 index 0000000..fa6376e Binary files /dev/null and b/assets/app-bundle/app-view/page/tips/resources/singleColor.png differ diff --git a/assets/app-bundle/app-view/page/tips/resources/singleColor.png.meta b/assets/app-bundle/app-view/page/tips/resources/singleColor.png.meta new file mode 100644 index 0000000..458e322 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources/singleColor.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "06c69eac-72f1-4cf9-938e-ece19602cc55", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "06c69eac-72f1-4cf9-938e-ece19602cc55@6c48a", + "displayName": "singleColor", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "06c69eac-72f1-4cf9-938e-ece19602cc55", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "06c69eac-72f1-4cf9-938e-ece19602cc55@f9941", + "displayName": "singleColor", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 2, + "height": 2, + "rawWidth": 2, + "rawHeight": 2, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -1, + -1, + 0, + 1, + -1, + 0, + -1, + 1, + 0, + 1, + 1, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 2, + 2, + 2, + 0, + 0, + 2, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -1, + -1, + 0 + ], + "maxPos": [ + 1, + 1, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "06c69eac-72f1-4cf9-938e-ece19602cc55@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": false, + "fixAlphaTransparencyArtifacts": false, + "redirect": "06c69eac-72f1-4cf9-938e-ece19602cc55@6c48a" + } +} diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_bg.png b/assets/app-bundle/app-view/page/tips/resources/tips_bg.png new file mode 100644 index 0000000..ce2f8ea Binary files /dev/null and b/assets/app-bundle/app-view/page/tips/resources/tips_bg.png differ diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_bg.png.meta b/assets/app-bundle/app-view/page/tips/resources/tips_bg.png.meta new file mode 100644 index 0000000..430c7b4 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources/tips_bg.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174@6c48a", + "displayName": "tips_bg", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174@f9941", + "displayName": "tips_bg", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 903, + "height": 1423, + "rawWidth": 903, + "rawHeight": 1423, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -451.5, + -711.5, + 0, + 451.5, + -711.5, + 0, + -451.5, + 711.5, + 0, + 451.5, + 711.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 1423, + 903, + 1423, + 0, + 0, + 903, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -451.5, + -711.5, + 0 + ], + "maxPos": [ + 451.5, + 711.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "d4a6fcf4-f444-4ba7-83be-b2bfae37b174@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png b/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png new file mode 100644 index 0000000..e96494e Binary files /dev/null and b/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png differ diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png.meta b/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png.meta new file mode 100644 index 0000000..cd6f968 --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources/tips_btn_close.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "e4c4a51f-4906-4750-92fa-eda8ea787e68", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "e4c4a51f-4906-4750-92fa-eda8ea787e68@6c48a", + "displayName": "tips_btn_close", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "e4c4a51f-4906-4750-92fa-eda8ea787e68", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "e4c4a51f-4906-4750-92fa-eda8ea787e68@f9941", + "displayName": "tips_btn_close", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 125, + "height": 125, + "rawWidth": 125, + "rawHeight": 125, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -62.5, + -62.5, + 0, + 62.5, + -62.5, + 0, + -62.5, + 62.5, + 0, + 62.5, + 62.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 125, + 125, + 125, + 0, + 0, + 125, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -62.5, + -62.5, + 0 + ], + "maxPos": [ + 62.5, + 62.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "e4c4a51f-4906-4750-92fa-eda8ea787e68@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "e4c4a51f-4906-4750-92fa-eda8ea787e68@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_title.png b/assets/app-bundle/app-view/page/tips/resources/tips_title.png new file mode 100644 index 0000000..a6d7408 Binary files /dev/null and b/assets/app-bundle/app-view/page/tips/resources/tips_title.png differ diff --git a/assets/app-bundle/app-view/page/tips/resources/tips_title.png.meta b/assets/app-bundle/app-view/page/tips/resources/tips_title.png.meta new file mode 100644 index 0000000..b70b31c --- /dev/null +++ b/assets/app-bundle/app-view/page/tips/resources/tips_title.png.meta @@ -0,0 +1,138 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "f28663c8-a56e-4250-bc32-12e6ec054846", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "f28663c8-a56e-4250-bc32-12e6ec054846@6c48a", + "displayName": "tips_title", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "f28663c8-a56e-4250-bc32-12e6ec054846", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "f28663c8-a56e-4250-bc32-12e6ec054846@f9941", + "displayName": "tips_title", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0.5, + "trimX": 2, + "trimY": 1, + "width": 882, + "height": 214, + "rawWidth": 886, + "rawHeight": 217, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -441, + -107, + 0, + 441, + -107, + 0, + -441, + 107, + 0, + 441, + 107, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 2, + 216, + 884, + 216, + 2, + 2, + 884, + 2 + ], + "nuv": [ + 0.002257336343115124, + 0.009216589861751152, + 0.9977426636568849, + 0.009216589861751152, + 0.002257336343115124, + 0.9953917050691244, + 0.9977426636568849, + 0.9953917050691244 + ], + "minPos": [ + -441, + -107, + 0 + ], + "maxPos": [ + 441, + 107, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "f28663c8-a56e-4250-bc32-12e6ec054846@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "f28663c8-a56e-4250-bc32-12e6ec054846@6c48a", + "compressSettings": { + "useCompressTexture": true, + "presetId": "b1rRMHaV9Gz5HhQd3Z8obg" + } + } +} diff --git a/assets/app-scene.meta b/assets/app-scene.meta new file mode 100644 index 0000000..2311883 --- /dev/null +++ b/assets/app-scene.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "104c58a7-687b-47fb-b7b0-dac627418567", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app-scene/.app-scene.md b/assets/app-scene/.app-scene.md new file mode 100644 index 0000000..9e82b98 --- /dev/null +++ b/assets/app-scene/.app-scene.md @@ -0,0 +1,2 @@ +1、存储主场景的文件夹 +2、不可删除此文件夹 \ No newline at end of file diff --git a/assets/app-scene/main.scene b/assets/app-scene/main.scene new file mode 100644 index 0000000..d9e110a --- /dev/null +++ b/assets/app-scene/main.scene @@ -0,0 +1,1415 @@ +[ + { + "__type__": "cc.SceneAsset", + "_name": "main", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "scene": { + "__id__": 1 + } + }, + { + "__type__": "cc.Scene", + "_name": "main", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + } + ], + "_active": true, + "_components": [], + "_prefab": { + "__id__": 59 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "autoReleaseAssets": false, + "_globals": { + "__id__": 63 + }, + "_id": "5298bb0b-166e-4978-af98-0047d43757de" + }, + { + "__type__": "cc.Node", + "_name": "Canvas", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 3 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + }, + { + "__id__": 38 + }, + { + "__id__": 41 + }, + { + "__id__": 53 + } + ], + "_active": true, + "_components": [ + { + "__id__": 56 + }, + { + "__id__": 57 + }, + { + "__id__": 58 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 540, + "y": 960, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "beI88Z2HpFELqR4T5EMHpg" + }, + { + "__type__": "cc.Node", + "_name": "CameraCleaner", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 4 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "44sn5JnYZMDacIjGeLTb9L" + }, + { + "__type__": "cc.Camera", + "_name": "Camera", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 3 + }, + "_enabled": true, + "__prefab": null, + "_projection": 0, + "_priority": 0, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 667, + "_near": 0, + "_far": 1, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 7, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 0, + "_targetTexture": null, + "_postProcess": null, + "_usePostProcess": false, + "_cameraType": -1, + "_trackingType": 0, + "_id": "90ePEmbuZG5pOTEw/PvfiP" + }, + { + "__type__": "cc.Node", + "_name": "CameraDefault", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 6 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 1000 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "ebFwiq8gBFaYpqYbdoDODe" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 5 + }, + "_enabled": true, + "__prefab": null, + "_projection": 0, + "_priority": 1000, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 960, + "_near": 0, + "_far": 2000, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 6, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 33554432, + "_targetTexture": null, + "_postProcess": null, + "_usePostProcess": false, + "_cameraType": -1, + "_trackingType": 0, + "_id": "63WIch3o5BEYRlXzTT0oWc" + }, + { + "__type__": "cc.Node", + "_name": "AppInitLayer", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 8 + } + ], + "_active": true, + "_components": [ + { + "__id__": 36 + }, + { + "__id__": 37 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "c1MYxrXkRChJfRVULozYQ1" + }, + { + "__type__": "cc.Node", + "_objFlags": 512, + "_parent": { + "__id__": 7 + }, + "_prefab": { + "__id__": 9 + }, + "__editorExtras__": {} + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 8 + }, + "asset": { + "__uuid__": "19a93f71-0300-44b3-9bd9-efbc15271e7d", + "__expectedType__": "cc.Prefab" + }, + "fileId": "7aBxAgUy9NRJNTrHNH6/6R", + "instance": { + "__id__": 10 + }, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.PrefabInstance", + "fileId": "59H08KPE9KIrsVoKNgJyQL", + "prefabRootNode": null, + "mountedChildren": [], + "mountedComponents": [], + "propertyOverrides": [ + { + "__id__": 11 + }, + { + "__id__": 13 + }, + { + "__id__": 14 + }, + { + "__id__": 15 + }, + { + "__id__": 16 + }, + { + "__id__": 18 + }, + { + "__id__": 20 + }, + { + "__id__": 21 + }, + { + "__id__": 23 + }, + { + "__id__": 25 + }, + { + "__id__": 27 + }, + { + "__id__": 29 + }, + { + "__id__": 31 + }, + { + "__id__": 32 + }, + { + "__id__": 34 + }, + { + "__id__": 35 + } + ], + "removedComponents": [] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 12 + }, + "propertyPath": [ + "_name" + ], + "value": "AppInit" + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "7aBxAgUy9NRJNTrHNH6/6R" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 12 + }, + "propertyPath": [ + "_lpos" + ], + "value": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 12 + }, + "propertyPath": [ + "_lrot" + ], + "value": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 12 + }, + "propertyPath": [ + "_euler" + ], + "value": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 17 + }, + "propertyPath": [ + "_contentSize" + ], + "value": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "fdxpU8hWdAMIljPcrHWSD1" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 19 + }, + "propertyPath": [ + "_contentSize" + ], + "value": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "1bUhFF79dG46Ne46ZRxKpC" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 12 + }, + "propertyPath": [ + "_layer" + ], + "value": 33554432 + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 22 + }, + "propertyPath": [ + "_layer" + ], + "value": 33554432 + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "0fJ7SovSVCVawCNYpB3WTW" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 24 + }, + "propertyPath": [ + "_contentSize" + ], + "value": { + "__type__": "cc.Size", + "width": 982, + "height": 801 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "830VxCeINAa7bLC2kyd2Db" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 26 + }, + "propertyPath": [ + "_sizeMode" + ], + "value": 1 + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "fdljxQ6hREBoCDN2bRrUnW" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 28 + }, + "propertyPath": [ + "_color" + ], + "value": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "f0x+xHB+BD77gwz9qesmbl" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 30 + }, + "propertyPath": [ + "sp_flash" + ], + "value": null + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "ffhkucpqlE+aHYz+nafs1t" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 26 + }, + "propertyPath": [ + "_color" + ], + "value": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 33 + }, + "propertyPath": [ + "_lscale" + ], + "value": { + "__type__": "cc.Vec3", + "x": 0.4, + "y": 0.4, + "z": 1 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "8cWbsI+kdMYYPLYQrEFecs" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 33 + }, + "propertyPath": [ + "_active" + ], + "value": false + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 28 + }, + "propertyPath": [ + "_spriteFrame" + ], + "value": { + "__uuid__": "1fc6b57d-ae88-4565-be7a-545305c50cbb@f9941", + "__expectedType__": "cc.SpriteFrame" + } + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 7 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "3fCzoQamRD6YqJ5xAJrIrF" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 7 + }, + "_enabled": true, + "__prefab": null, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "39b7+TQHZNjLetoDp6d0KT" + }, + { + "__type__": "cc.Node", + "_name": "UserInterface", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 39 + }, + { + "__id__": 40 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "22nXmnonVOVLZIZLp3/gsy" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 38 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "49vj7BWZpFRron6sjoM8FB" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 38 + }, + "_enabled": true, + "__prefab": null, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "7bO/h4uK5NkKHZJR3g+kQE" + }, + { + "__type__": "cc.Node", + "_objFlags": 512, + "_parent": { + "__id__": 2 + }, + "_prefab": { + "__id__": 42 + }, + "__editorExtras__": {} + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 41 + }, + "asset": { + "__uuid__": "5e43bb09-848f-434a-b3a5-a6b6602e00af", + "__expectedType__": "cc.Prefab" + }, + "fileId": "09f6AV8NhG8amoujtBeGc3", + "instance": { + "__id__": 43 + }, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.PrefabInstance", + "fileId": "6bff0rS6pG9K1dncpRrgk3", + "prefabRootNode": null, + "mountedChildren": [], + "mountedComponents": [], + "propertyOverrides": [ + { + "__id__": 44 + }, + { + "__id__": 46 + }, + { + "__id__": 47 + }, + { + "__id__": 48 + }, + { + "__id__": 49 + }, + { + "__id__": 51 + } + ], + "removedComponents": [] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 45 + }, + "propertyPath": [ + "_name" + ], + "value": "MainManager" + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "09f6AV8NhG8amoujtBeGc3" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 45 + }, + "propertyPath": [ + "_lpos" + ], + "value": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 45 + }, + "propertyPath": [ + "_lrot" + ], + "value": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 45 + }, + "propertyPath": [ + "_euler" + ], + "value": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 50 + }, + "propertyPath": [ + "_contentSize" + ], + "value": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "bab8wNsgZHRICm9NXgLsKC" + ] + }, + { + "__type__": "CCPropertyOverrideInfo", + "targetInfo": { + "__id__": 52 + }, + "propertyPath": [ + "_contentSize" + ], + "value": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "c3fJug795H8Zpvt/9PivC1" + ] + }, + { + "__type__": "cc.Node", + "_name": "UserManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 54 + }, + { + "__id__": 55 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "85DtqjhStE35D/yB7DOLJP" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 53 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "75nDyZNw1Ba5VJGHfNgh1y" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 53 + }, + "_enabled": true, + "__prefab": null, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "bbmV5F90ZFTpPH7eVrcMtt" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "d6rUX5yfhMlKoWX2bSbawx" + }, + { + "__type__": "cc.Canvas", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_cameraComponent": { + "__id__": 6 + }, + "_alignCanvasWithScreen": true, + "_id": "12O/ljcVlEqLmVm3U2gEOQ" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334.0000000000002, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "eaKwWyCaFLR50mqc10Dr1B" + }, + { + "__type__": "cc.PrefabInfo", + "root": null, + "asset": null, + "fileId": "5298bb0b-166e-4978-af98-0047d43757de", + "instance": null, + "targetOverrides": [ + { + "__id__": 60 + } + ], + "nestedPrefabInstanceRoots": [ + { + "__id__": 8 + }, + { + "__id__": 41 + } + ] + }, + { + "__type__": "cc.TargetOverrideInfo", + "source": { + "__id__": 8 + }, + "sourceInfo": { + "__id__": 61 + }, + "propertyPath": [ + "logo" + ], + "target": { + "__id__": 8 + }, + "targetInfo": { + "__id__": 62 + } + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "ffhkucpqlE+aHYz+nafs1t" + ] + }, + { + "__type__": "cc.TargetInfo", + "localID": [ + "8cWbsI+kdMYYPLYQrEFecs" + ] + }, + { + "__type__": "cc.SceneGlobals", + "ambient": { + "__id__": 64 + }, + "shadows": { + "__id__": 65 + }, + "_skybox": { + "__id__": 66 + }, + "fog": { + "__id__": 67 + }, + "octree": { + "__id__": 68 + }, + "skin": { + "__id__": 69 + }, + "lightProbeInfo": { + "__id__": 70 + }, + "postSettings": { + "__id__": 71 + }, + "bakedWithStationaryMainLight": false, + "bakedWithHighpLightmap": false + }, + { + "__type__": "cc.AmbientInfo", + "_skyColorHDR": { + "__type__": "cc.Vec4", + "x": 0.242612, + "y": 0.362617, + "z": 0.798746, + "w": 0.520833125 + }, + "_skyColor": { + "__type__": "cc.Vec4", + "x": 0.242612, + "y": 0.362617, + "z": 0.798746, + "w": 0.520833125 + }, + "_skyIllumHDR": 20000, + "_skyIllum": 20000, + "_groundAlbedoHDR": { + "__type__": "cc.Vec4", + "x": 0.241836, + "y": 0.361964, + "z": 0.798801, + "w": 0 + }, + "_groundAlbedo": { + "__type__": "cc.Vec4", + "x": 0.241836, + "y": 0.361964, + "z": 0.798801, + "w": 0 + }, + "_skyColorLDR": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.5, + "z": 0.8, + "w": 1 + }, + "_skyIllumLDR": 20000, + "_groundAlbedoLDR": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.2, + "z": 0.2, + "w": 1 + } + }, + { + "__type__": "cc.ShadowsInfo", + "_enabled": false, + "_type": 0, + "_normal": { + "__type__": "cc.Vec3", + "x": 0, + "y": 1, + "z": 0 + }, + "_distance": 0, + "_planeBias": 1, + "_shadowColor": { + "__type__": "cc.Color", + "r": 76, + "g": 76, + "b": 76, + "a": 255 + }, + "_maxReceived": 4, + "_size": { + "__type__": "cc.Vec2", + "x": 512, + "y": 512 + } + }, + { + "__type__": "cc.SkyboxInfo", + "_envLightingType": 0, + "_envmapHDR": null, + "_envmap": null, + "_envmapLDR": null, + "_diffuseMapHDR": null, + "_diffuseMapLDR": null, + "_enabled": false, + "_useHDR": true, + "_editableMaterial": null, + "_reflectionHDR": null, + "_reflectionLDR": null, + "_rotationAngle": 0 + }, + { + "__type__": "cc.FogInfo", + "_type": 0, + "_fogColor": { + "__type__": "cc.Color", + "r": 200, + "g": 200, + "b": 200, + "a": 255 + }, + "_enabled": false, + "_fogDensity": 0.3, + "_fogStart": 0.5, + "_fogEnd": 300, + "_fogAtten": 5, + "_fogTop": 1.5, + "_fogRange": 1.2, + "_accurate": false + }, + { + "__type__": "cc.OctreeInfo", + "_enabled": false, + "_minPos": { + "__type__": "cc.Vec3", + "x": -1024, + "y": -1024, + "z": -1024 + }, + "_maxPos": { + "__type__": "cc.Vec3", + "x": 1024, + "y": 1024, + "z": 1024 + }, + "_depth": 8 + }, + { + "__type__": "cc.SkinInfo", + "_enabled": true, + "_blurRadius": 0.01, + "_sssIntensity": 3 + }, + { + "__type__": "cc.LightProbeInfo", + "_giScale": 1, + "_giSamples": 1024, + "_bounces": 2, + "_reduceRinging": 0, + "_showProbe": true, + "_showWireframe": true, + "_showConvex": false, + "_data": null, + "_lightProbeSphereVolume": 1 + }, + { + "__type__": "cc.PostSettingsInfo", + "_toneMappingType": 0 + } +] \ No newline at end of file diff --git a/assets/app-scene/main.scene.meta b/assets/app-scene/main.scene.meta new file mode 100644 index 0000000..e02e30d --- /dev/null +++ b/assets/app-scene/main.scene.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.1.50", + "importer": "scene", + "imported": true, + "uuid": "5298bb0b-166e-4978-af98-0047d43757de", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app.meta b/assets/app.meta new file mode 100644 index 0000000..98c4ff0 --- /dev/null +++ b/assets/app.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "a7084ee0-ab27-4f9f-a846-6d4b38db50ba", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/app/.app.md b/assets/app/.app.md new file mode 100644 index 0000000..a2d605a --- /dev/null +++ b/assets/app/.app.md @@ -0,0 +1,2 @@ +1、框架配置、生命周期及全局导出 +2、不可删除此文件夹 \ No newline at end of file diff --git a/assets/app/app.ts b/assets/app/app.ts new file mode 100644 index 0000000..0406b3c --- /dev/null +++ b/assets/app/app.ts @@ -0,0 +1,33 @@ +import { Game, game } from 'cc'; +import { DEBUG, DEV, EDITOR } from 'cc/env'; +import Core from '../../extensions/app/assets/Core'; +import { IApp } from '../app-builtin/app-admin/executor'; +import { appInited, appReady, cccInited, cccReady } from './handle'; + +export class App extends Core { + protected static _inst: App | undefined; + static get inst() { + if (!this._inst) this._inst = new App(); + return this._inst; + } + + private constructor() { + super(); + } +} + +export const app = App.inst; + +if (DEBUG) { + //@ts-ignore + window['app'] = app; + //@ts-ignore + window['App'] = App; +} + +if (!EDITOR || DEV) { + cccReady && cccReady(app); + appReady && appReady(app); + cccInited && game.once(Game.EVENT_ENGINE_INITED, function () { cccInited(app); }); + appInited && app.once(App.EventType.EVENT_APPINIT_FINISHED, function () { appInited(app); }); +} \ No newline at end of file diff --git a/assets/app/app.ts.meta b/assets/app/app.ts.meta new file mode 100644 index 0000000..3d3d0a0 --- /dev/null +++ b/assets/app/app.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "121df84f-631d-4557-831a-19641e7deea8", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app/handle.ts b/assets/app/handle.ts new file mode 100644 index 0000000..67152f8 --- /dev/null +++ b/assets/app/handle.ts @@ -0,0 +1,34 @@ +import { game, sys } from 'cc'; +import { App } from './app'; + +/** + * ccc除物理引擎等外的基础功能已经准备好了 + */ +export function cccReady(app: App) { + // 为了防止web环境中异常掉帧问题(关键代码在cc.game._pacer._handleRAF中) + if (sys.isBrowser) { + // game.frameRate = 100; // 在60、90帧率手机上满帧率运行,120帧率手机上以60帧率运行(可能不够流畅但省电) + game.frameRate = 200; // 满帧率运行 + } +} + +/** + * ccc全部功能都初始化完毕了 + */ +export function cccInited(app: App) { + +} + +/** + * app除了用户自定义Manager未加载外,其它都已准备好了 + */ +export function appReady(app: App) { + +} + +/** + * app全部功能都初始化完毕了 + */ +export function appInited(app: App) { + +} \ No newline at end of file diff --git a/assets/app/handle.ts.meta b/assets/app/handle.ts.meta new file mode 100644 index 0000000..fdff36a --- /dev/null +++ b/assets/app/handle.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "8afaf85a-fbcd-4213-aacb-2e9337926fee", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/app/setting.ts b/assets/app/setting.ts new file mode 100644 index 0000000..6bd6ccf --- /dev/null +++ b/assets/app/setting.ts @@ -0,0 +1,32 @@ +import { DEBUG } from 'cc/env'; +import { Logger } from 'db://app/lib/logger/logger'; +import { Storage } from 'db://app/lib/storage/storage'; +import SoundManager from 'db://app/manager/sound/SoundManager'; +import UIManager from 'db://app/manager/ui/UIManager'; + +// 如果需要加密内容,请设置密钥的值 +Storage.setting.secretKey = ''; +// 设置日志过滤 +Logger.setting.filter = DEBUG ? ['error', 'log', 'warn'] : ['error']; + +// 预加载的UI列表 +UIManager.setting.preload = ['PageMain', 'PageRewardhistory', 'PageTips']; +// 默认UI, 会在首屏流程后自动show +UIManager.setting.defaultUI = 'PageMain'; // 通过App菜单创建Page类型的UI后,填入该UI的名称(会有自动提示与类型检查) +// 是否自动适配分辨率策略 +UIManager.setting.autoFit = true; // 开启后,会弃用项目设置中的适配策略,并自动根据设备分辨率与设计分辨率计算出新的适配策略 +// 弹窗默认遮罩展现动画配置 +UIManager.setting.shade = { + delay: 0, + begin: 100, + end: 200, + speed: 400, + blur: false +}; + +// 预加载的音频(按数组顺序依次预加载) +SoundManager.setting.preload = ['music/bgm']; +// 默认音乐, 会在首屏流程后自动播放 +SoundManager.setting.defaultMusicName = 'music/bgm'; +// 默认音效, 会在Button被点击后播放 +SoundManager.setting.defaultEffectName = 'effect/click'; \ No newline at end of file diff --git a/assets/app/setting.ts.meta b/assets/app/setting.ts.meta new file mode 100644 index 0000000..ce6357e --- /dev/null +++ b/assets/app/setting.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "9a8d2a40-9eb2-4058-8883-a7de0fedbd33", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native.meta b/assets/res-native.meta new file mode 100644 index 0000000..3d7413e --- /dev/null +++ b/assets/res-native.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "1a0d9ccf-f49e-434f-9e73-241ccac52e5b", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/.res-native.md b/assets/res-native/.res-native.md new file mode 100644 index 0000000..33a7695 --- /dev/null +++ b/assets/res-native/.res-native.md @@ -0,0 +1,5 @@ +存储静态资源的文件夹 +1、非公共脚本资源,尽量不放到主包内 +3、图片、字体等非脚本类公共资源,尽量不放到主包内(因为构建后这些资源会被拷贝到其它Bundle中) +2、如果公共脚本资源体积较大,可以考虑放到Bundle内,保证首屏体积尽量小 +4、如不再需要,可以直接删除此文件夹 \ No newline at end of file diff --git a/assets/res-native/animation.meta b/assets/res-native/animation.meta new file mode 100644 index 0000000..006e349 --- /dev/null +++ b/assets/res-native/animation.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "769a05ac-21c9-496a-8982-371919a27245", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/com.meta b/assets/res-native/com.meta new file mode 100644 index 0000000..29fd412 --- /dev/null +++ b/assets/res-native/com.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "f5e99d2a-0445-4298-85ea-fbe37da68ad2", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/com/com_loading.jpg b/assets/res-native/com/com_loading.jpg new file mode 100644 index 0000000..7fa9388 Binary files /dev/null and b/assets/res-native/com/com_loading.jpg differ diff --git a/assets/res-native/com/com_loading.jpg.meta b/assets/res-native/com/com_loading.jpg.meta new file mode 100644 index 0000000..17d8b73 --- /dev/null +++ b/assets/res-native/com/com_loading.jpg.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "1fc6b57d-ae88-4565-be7a-545305c50cbb", + "files": [ + ".jpg", + ".json" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "1fc6b57d-ae88-4565-be7a-545305c50cbb@6c48a", + "displayName": "com_loading", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "1fc6b57d-ae88-4565-be7a-545305c50cbb", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "1fc6b57d-ae88-4565-be7a-545305c50cbb@f9941", + "displayName": "com_loading", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 1081, + "height": 1920, + "rawWidth": 1081, + "rawHeight": 1920, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -540.5, + -960, + 0, + 540.5, + -960, + 0, + -540.5, + 960, + 0, + 540.5, + 960, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 1920, + 1081, + 1920, + 0, + 0, + 1081, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -540.5, + -960, + 0 + ], + "maxPos": [ + 540.5, + 960, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "1fc6b57d-ae88-4565-be7a-545305c50cbb@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": false, + "fixAlphaTransparencyArtifacts": false, + "redirect": "1fc6b57d-ae88-4565-be7a-545305c50cbb@6c48a" + } +} diff --git a/assets/res-native/data.meta b/assets/res-native/data.meta new file mode 100644 index 0000000..c0ca199 --- /dev/null +++ b/assets/res-native/data.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "da6dc13a-ba14-40ce-a8ee-791a814c21d7", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/data/ChannelData.ts b/assets/res-native/data/ChannelData.ts new file mode 100644 index 0000000..0724b9c --- /dev/null +++ b/assets/res-native/data/ChannelData.ts @@ -0,0 +1,81 @@ +import { _decorator } from 'cc'; +const { ccclass } = _decorator; + +/** 玩家数据类 */ +@ccclass('ChannelData') +class ChannelData { + public static instance: ChannelData | null = null; + + /** 获取渠道数据状态 */ + public get_success: boolean = false; + + /** 活动开关(0:关闭,1:开启) */ + public activity_open : number = 0; + /** 币商功能(0:禁用,1:启用) */ + public coin_status : boolean = true; + /** 币别代码 */ + public currency : string = ""; + /** 讨论组功能(0:禁用,1:启用) */ + public discussion_group_status : boolean = true; + /** 渠道域名 */ + public domain : string = ""; + /** 下载地址 */ + public download_url : string = ""; + /** 渠道ID */ + public id : number = 0; + /** 语言 */ + public lang : string = ""; + /** line client id */ + public line_client_id : string = ""; + /** line 登录功能(0:禁用,1:启用) */ + public line_login_status : boolean = true; + /** 机台线路 */ + public machine_media_line : number = 0; + /** 渠道名称 */ + public name : string = ""; + /** 全民代理功能(0:禁用,1:启用) */ + public national_promoter_status : boolean = true; + /** 代理开启状态 */ + public promotion_status : boolean = true; + /** Q币转入(0:禁用,1:启用) */ + public q_talk_point_status : boolean = true; + /** Q币充值(0:禁用,1:启用) */ + public q_talk_recharge_status : boolean = true; + /** Q币转出(0:禁用,1:启用) */ + public q_talk_withdraw_status : boolean = true; + /** 排行榜功能(0:禁用,1:启用) */ + public ranking_status : boolean = true; + /** 充值开启状态 */ + public recharge_status : boolean = true; + /** 反水开启状态 */ + public reverse_water_status : boolean = true; + /** 实体机台开关 0关闭1-开启 */ + public status_machine : boolean = true; + /** web登录状态(0:禁用,1:启用) */ + public web_login_status : boolean = true; + /** 人工提现(0:禁用,1:启用) */ + public withdraw_status : boolean = true; + + private constructor(){} + static get Instance(){ + if(ChannelData.instance == null){ + ChannelData.instance = new ChannelData(); + } + return ChannelData.instance; + } + + public setChannelData(data:any){ + for (let key in data){ + if (this.hasOwnProperty(key)){ + (this as any)[key] = data[key]; + } + } + + this.get_success = true; + } +} + +/** + * 游戏配置数据 + */ +export const CHANNELDATA = ChannelData.Instance; \ No newline at end of file diff --git a/assets/res-native/data/ChannelData.ts.meta b/assets/res-native/data/ChannelData.ts.meta new file mode 100644 index 0000000..11381d0 --- /dev/null +++ b/assets/res-native/data/ChannelData.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "c2e6b946-cc1f-4b8a-b626-42968399e30d", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/data/UserData.ts b/assets/res-native/data/UserData.ts new file mode 100644 index 0000000..9512720 --- /dev/null +++ b/assets/res-native/data/UserData.ts @@ -0,0 +1,40 @@ +import { _decorator } from 'cc'; +const { ccclass } = _decorator; + +/** 玩家数据类 */ +@ccclass('UserData') +class UserData { + public static instance: UserData | null = null; + + /** 剩余抽奖次数 */ + public point : number = 0; + /** 奖品列表 */ + public prize_list : any[] = []; + /** 游戏描述 */ + public description : string = ""; + + /* 游戏logo */ + public logo : string = ""; + public logo_back : string = ""; + + private constructor(){} + static get Instance(){ + if(UserData.instance == null){ + UserData.instance = new UserData(); + } + return UserData.instance; + } + + public setUserData(data:any){ + for (let key in data){ + if (this.hasOwnProperty(key)){ + (this as any)[key] = data[key]; + } + } + } +} + +/** + * 玩家数据 + */ +export const USERDATA = UserData.Instance; \ No newline at end of file diff --git a/assets/res-native/data/UserData.ts.meta b/assets/res-native/data/UserData.ts.meta new file mode 100644 index 0000000..d0782eb --- /dev/null +++ b/assets/res-native/data/UserData.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "29d17a77-7796-4df7-a0ed-7e0ececeae54", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/network.meta b/assets/res-native/network.meta new file mode 100644 index 0000000..caa8c90 --- /dev/null +++ b/assets/res-native/network.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "baf2ef12-30f7-46ec-af55-620c096bef72", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/network/HttpRequest.ts b/assets/res-native/network/HttpRequest.ts new file mode 100644 index 0000000..93349bf --- /dev/null +++ b/assets/res-native/network/HttpRequest.ts @@ -0,0 +1,294 @@ +import { game } from "cc"; +import { HTTP_SITE_ID, SERVER_LIST, GAME_VER } from "../setting/ServerConfig"; +import { Tools } from "../tools/Tools"; +import { app } from "../../app/app"; +import { CHANNELDATA } from "../data/ChannelData"; + +var urls: any = {}; // 当前请求地址集合 +var reqparams: any = {}; // 请求参数 + +/** + * 登录token类,全局唯一 + */ +export class LoginToken{ + private static instance: LoginToken | null = null; + public access_token: string = ""; + public refresh_token: string = ""; + public appId: string = ""; + public appKey: string = ""; + private constructor(){} + + static get Instance(){ + if(LoginToken.instance == null){ + LoginToken.instance = new LoginToken(); + } + return LoginToken.instance; + } + + public setToken(access_token: string, refresh_token: string, appID: string, appKey: string){ + this.access_token = access_token; + this.refresh_token = refresh_token; + this.appId = appID + this.appKey = appKey + } +} + +/** 当前保存的token */ +export const LOGIN_TOKEN : LoginToken = LoginToken.Instance; + +export enum HttpEvent { + NO_NETWORK = "http_request_no_network", // 断网 + UNKNOWN_ERROR = "http_request_unknown_error", // 未知错误 + TIMEOUT = "http_request_timout" // 请求超时 +} + + +export class HttpRequest { + /** 服务器地址 */ + public server: string = SERVER_LIST + /** 请求超时时间 */ + public timeout: number = 10000; + + public lobbyUrl = "" + + public setUrl (url:string) { + this.server = "http://" + url + "/" + } + + /** + * HTTP GET请求 + * 例: + * + * Get + var complete = function(response){ + LogWrap.log(response); + } + var error = function(response){ + LogWrap.log(response); + } + this.get(name, complete, error); + */ + public get(name: string, completeCallback: Function, errorCallback?: Function) { + this.sendRequest(name, null, false, completeCallback, errorCallback) + } + public getWithParams(name: string, params: any, completeCallback: Function, errorCallback?: Function) { + this.sendRequest(name, params, false, completeCallback, errorCallback) + } + + public getByArraybuffer(name: string, completeCallback: Function, errorCallback?: Function) { + this.sendRequest(name, null, false, completeCallback, errorCallback, 'arraybuffer', false); + } + public getWithParamsByArraybuffer(name: string, params: any, completeCallback: Function, errorCallback?: Function) { + this.sendRequest(name, params, false, completeCallback, errorCallback, 'arraybuffer', false); + } + + /** + * HTTP POST请求 + * 例: + * + * Post + var param = '{"LoginCode":"donggang_dev","Password":"e10adc3949ba59abbe56e057f20f883e"}' + var complete = function(response){ + var jsonData = JSON.parse(response); + var data = JSON.parse(jsonData.Data); + LogWrap.log(data.Id); + } + var error = function(response){ + LogWrap.log(response); + } + this.post(name, param, complete, error); + */ + public post(name: string, params: any, completeCallback?: Function, errorCallback?: Function) { + this.sendRequest(name, params, true, completeCallback, errorCallback); + } + + /** 取消请求中的请求 */ + public abort(name: string) { + var xhr = urls[this.server + name]; + if (xhr) { + xhr.abort(); + } + } + + /** + * 获得字符串形式的参数 + */ + private getParamString(params: any) { + var result = ""; + for (var name in params) { + let data = params[name]; + if (data instanceof Object) { + for (var key in data) + result += `${key}=${data[key]}&`; + } + else { + result += `${name}=${data}&`; + } + } + + return result.substring(0, result.length - 1); + } + + /** + * Http请求 + * @param name(string) 请求地址 + * @param params(JSON) 请求参数 + * @param isPost(boolen) 是否为POST方式 + * @param callback(function) 请求成功回调 + * @param errorCallback(function) 请求失败回调 + * @param responseType(string) 响应类型 + */ + private async sendRequest( + name: string, + params: any, + isPost: boolean, + completeCallback?: Function, + errorCallback?: Function, + responseType?: string, + isOpenTimeout = true, + timeout: number = this.timeout + ) { + if (!name) { + console.log("请求地址不能为空"); + return; + } + + let url: string, newUrl: string, paramsStr: string; + if (name.toLocaleLowerCase().indexOf("http") === 0) { + url = name; + } else { + url = this.server + name; + } + + if (params) { + paramsStr = this.getParamString(params); + if (url.indexOf("?") > -1) + newUrl = url + "&" + encodeURIComponent(paramsStr); + else + newUrl = url + "?" + paramsStr; + } else { + newUrl = url; + } + + if (urls[newUrl] != null && reqparams[newUrl] === paramsStr!) { + console.log(`地址【${url}】已正在请求中,不能重复请求`); + return; + } + + const xhr = new XMLHttpRequest(); + urls[newUrl] = xhr; + reqparams[newUrl] = paramsStr!; + + if (isPost) { + xhr.open("POST", url); + } else { + xhr.open("GET", newUrl); + } + + if (LOGIN_TOKEN.access_token !== "") { + xhr.setRequestHeader("Authorization", "Bearer " + LOGIN_TOKEN.access_token); + } + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); + + // 加密设置 + const time = Math.floor(Date.now() / 1000); + xhr.setRequestHeader("Lang", CHANNELDATA.lang); + + if (!params) params = {}; + let _params = params; + _params.appId = LOGIN_TOKEN.appId; + _params.nonceStr = Tools.getRandomStr(6); + _params.timestamp = time; + + let sha256DDD: string; + try { + sha256DDD = await Tools.generateSignNative(_params, LOGIN_TOKEN.appKey); + } catch (err) { + console.error("生成签名失败:", err); + this.deleteCache(newUrl); + const data: any = { url, params, event: HttpEvent.UNKNOWN_ERROR }; + if (errorCallback) errorCallback(data); + return; // 出错直接返回,避免继续执行 + } + + xhr.setRequestHeader("appId", LOGIN_TOKEN.appId); + xhr.setRequestHeader("timestamp", _params.timestamp.toString()); + xhr.setRequestHeader("signature", sha256DDD); + xhr.setRequestHeader("nonceStr", _params.nonceStr); + xhr.setRequestHeader("Site-Id", HTTP_SITE_ID); + const v = app.lib.storage.get("CURR_VERSION") || "100"; + xhr.setRequestHeader("app-version-key", v.toString()); + xhr.setRequestHeader("system-key", "android"); + xhr.setRequestHeader("Client-Version", GAME_VER); + + const data: any = { url, params }; + + // 请求超时 + if (isOpenTimeout) { + xhr.timeout = timeout; + xhr.ontimeout = () => { + this.deleteCache(newUrl); + data.event = HttpEvent.TIMEOUT; + if (errorCallback) errorCallback(data); + }; + } + + xhr.onloadend = () => { + if (xhr.status === 500) { + this.deleteCache(newUrl); + data.event = HttpEvent.NO_NETWORK; + if (errorCallback) errorCallback(data); + } + }; + + xhr.onerror = () => { + this.deleteCache(newUrl); + if (!errorCallback) return; + if (xhr.readyState === 0 || xhr.readyState === 1 || xhr.status === 0) { + data.event = HttpEvent.NO_NETWORK; + } else { + data.event = HttpEvent.UNKNOWN_ERROR; + } + errorCallback(data); + }; + + xhr.onreadystatechange = () => { + if (xhr.readyState !== 4) return; + this.deleteCache(newUrl); + if (xhr.status === 200) { + if (completeCallback) { + if (responseType === "arraybuffer") { + xhr.responseType = responseType; + completeCallback(xhr.response); + } else { + try { + const resp: any = JSON.parse(xhr.response); + if (Number(resp.code) === 200 || Number(resp.code) === 406) { + completeCallback(resp.data); + } else { + app.manager.ui.showToast(Tools.GetLocalized(resp.msg)); + if (errorCallback) errorCallback(resp.data); + } + } catch (error) { + console.log("解析响应失败:", error); + if (errorCallback) errorCallback({ event: HttpEvent.UNKNOWN_ERROR }); + } + } + } + } + }; + + if (!paramsStr) { + xhr.send(); + } else { + xhr.send(paramsStr!); + } + } + + private deleteCache(url: string) { + delete urls[url]; + delete reqparams[url]; + } +} + +export let httpRequest = new HttpRequest() \ No newline at end of file diff --git a/assets/res-native/network/HttpRequest.ts.meta b/assets/res-native/network/HttpRequest.ts.meta new file mode 100644 index 0000000..17e3ae9 --- /dev/null +++ b/assets/res-native/network/HttpRequest.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "58832863-cdb2-4696-85ed-027e9449985d", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/setting.meta b/assets/res-native/setting.meta new file mode 100644 index 0000000..4d8f112 --- /dev/null +++ b/assets/res-native/setting.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "c3f3b179-7966-4963-a10d-f690739ee781", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/setting/ServerConfig.ts b/assets/res-native/setting/ServerConfig.ts new file mode 100644 index 0000000..0a27209 --- /dev/null +++ b/assets/res-native/setting/ServerConfig.ts @@ -0,0 +1,34 @@ +/** 服务区域 */ +export const enum SERVER_EREA { + // 一级棒横版 + ZP = 0, +} +/** 当前服务区域配置(根据打包修改) */ +export const NOW_SERVER_EREA : SERVER_EREA = SERVER_EREA.ZP; + +// 默认地址 +const DEFAULT_URL = "https://xyxapi.yuliao666.top" +/** 通用版本 */ +const DEFAULT_VERSION = "1.0.5" +/** 测试服版本号 */ +const DEFAULT_TEST_VERSION = "1.0.0" + +/** 区域打包配置文件 */ +const SERVER_CONFIG = { + // 横版一级棒 + [0] : { + "server" : DEFAULT_URL, + "site_id" : "ba5ea4dc-75bb-438d-8a3a-b8031ef89426", + "ver" : DEFAULT_TEST_VERSION, + "area" : "86", + } +} + +/** 服务器地址 */ +export const SERVER_LIST = SERVER_CONFIG[NOW_SERVER_EREA]["server"]; +/** Site ID */ +export const HTTP_SITE_ID = SERVER_CONFIG[NOW_SERVER_EREA]["site_id"]; +/** 当前版本号 */ +export const GAME_VER = SERVER_CONFIG[NOW_SERVER_EREA]["ver"]; +/** 国家电话区号 */ +export const COUNTRY_CODE = SERVER_CONFIG[NOW_SERVER_EREA]["area"]; \ No newline at end of file diff --git a/assets/res-native/setting/ServerConfig.ts.meta b/assets/res-native/setting/ServerConfig.ts.meta new file mode 100644 index 0000000..4801ace --- /dev/null +++ b/assets/res-native/setting/ServerConfig.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "29ef329c-fd90-4d8a-a91a-95ab0b17eace", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/tools.meta b/assets/res-native/tools.meta new file mode 100644 index 0000000..55a88e0 --- /dev/null +++ b/assets/res-native/tools.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "c1e551ce-e4da-42b1-b6e7-60cf4cf1f45c", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res-native/tools/Tools.ts b/assets/res-native/tools/Tools.ts new file mode 100644 index 0000000..c53fefb --- /dev/null +++ b/assets/res-native/tools/Tools.ts @@ -0,0 +1,627 @@ +import { _decorator, SpriteFrame, Node, Sprite, instantiate, Label, Prefab, Color, Size, UITransform, RichText, Component, Texture2D, ImageAsset } from 'cc'; +import { httpRequest } from '../network/HttpRequest'; +import { app } from '../../app/app'; +const { ccclass } = _decorator; + +//@ts-ignore +import CryptoJS from "crypto-js"; + +type ConstructorOf = new (...args: any[]) => T; + +// 定义数据接口 +interface DataObject { + [key: string]: string | number | boolean; +} + +/** 事件名称 */ +export enum EventType { + /** 刷新玩家数据 */ + RefreshUserInfo = "RefreshUserInfo", + /** 刷新玩家数据成功 */ + RefreshUserInfoSuccess = "RefreshUserInfoSuccess", +} + + +// 定义阈值和对应的num值 +const sizeThresholds = [ + { size: 20000000, num: 100 }, + { size: 19000000, num: 95 }, + { size: 18000000, num: 90 }, + { size: 17000000, num: 85 }, + { size: 16000000, num: 80 }, + { size: 15000000, num: 75 }, + { size: 14000000, num: 70 }, + { size: 13000000, num: 65 }, + { size: 12000000, num: 60 }, + { size: 11000000, num: 55 }, + { size: 10000000, num: 50 }, + { size: 9000000, num: 45 }, + { size: 8000000, num: 40 }, + { size: 7000000, num: 35 }, + { size: 6000000, num: 30 }, + { size: 5000000, num: 25 }, + { size: 4000000, num: 20 }, + { size: 3000000, num: 15 }, + { size: 2000000, num: 10 }, + { size: 1000000, num: 5 }, + { size: 500000, num: 2.5 }, + { size: 250000, num: 1.5 } +]; + +/** 用户代理等级和图片对照表 */ +const AGENT_LV_TO_PIC = { + ["等级青铜"] : "a", + ["等级白银"] : "b", + ["等级黄金"] : "c", + ["等级VIP"] : "d", + ["等级超级VIP"] : "e" +} + +/** 通用工具类 */ +@ccclass('Tools') +export class Tools +{ + //#region Sprite相关操作 + /** 设置节点的SpriteFrame, 默认从resource/ui下面找 */ + static SetSpriteFrame(node:Node, uiname:string, uipath:string, fuc:Function = null) { + app.manager.loader.load({ + bundle: "", // 不传入bundle,默认为resources + path: 'xxx/xxxx', + type: SpriteFrame, + onComplete(asset){ + if (node){ + let c = node.getComponent(Sprite) + if (c) c.spriteFrame = asset + if (fuc) fuc() + } + } + }) + } + + /** 加载远程图片 */ + static remoteLoadSprite(url: string, node: Sprite, fuc?: Function) { + app.manager.loader.loadRemote( { + url: url, + ext: null, + onComplete: (result: ImageAsset | null) => { + if (result) { + if(node) { + let sp = new SpriteFrame() + let tex = new Texture2D(); + tex.image = result; + sp.texture = tex + node.spriteFrame = sp + if (fuc) fuc() + } + } + } + }) + } + + /** 设置子节点uisprite */ + static SetChildSprite(node:Node, path:string, uiname:string, uipath:string, fuc:Function = null) { + let n = node.getChildByPath(path) + if (n) this.SetSpriteFrame(n, uiname, uipath, fuc) + } + + /** + * 设置艺术字 + * itemPath:字体预制件位置, numPath:字体图片位置, pre:图片名前缀 + */ + // static SetArtNums(str:any, item:Node, itemPath:string = "ui/numbers/num_Item", numPath:string = "ui/numbers", pre:string = "numbers_0") { + // str = String(str) + // item.destroyAllChildren() + // let m_resLoader = new ResLoader(); + // m_resLoader.loadPrefabNode(itemPath, (prefab:Node) => { + // console.log(itemPath, prefab) + // // 根据字符串长度,显示对应数量的数字图片 + // for (let i = 0; i < str.length; i++) { + // let n = Tools.AddChild(item, prefab, "num_" + i) + // n.active = true + // this.SetSpriteFrame(n, pre + (str[i] == "." ? "dot" : str[i]), numPath) + // } + // }) + // } + //#endregion + + + //#region http相关 + /** 发送http请求 */ + static httpReq(str:string, param:any, callback:Function, failCallBack:Function = null) { + httpRequest.post("/agent/api/" + str, param, callback, failCallBack) + } + //#endregion + + + //#region Node 相关 + /** 添加子节点 */ + static AddChild(node:Node, prefab:Node|Prefab, name:string = null):Node { + var n = instantiate(prefab as Node) + node.addChild(n) + if (name) n.name = name + return n + } + + /** 设置子节点显示 */ + static ActChild(node:Node, path:string, act:boolean) + { + let n = node.getChildByPath(path) + if (n) n.active = act + } + + /** 获取子节点组件 */ + static GetChildComp(node: Node, path: string, compClass: ConstructorOf): T { + return node.getChildByPath(path)?.getComponent(compClass); + } + + //#endregion + + + //#region Text 相关 + /** 设置子节点文字 */ + static SetText(node:Node, str:string) { + str = String(str) + node.getComponent(Label).string = str + } + /** 设置子节点文字 */ + static SetChildText(node:Node, path:string, str:string) { + str = String(str) + let n = node.getChildByPath(path) + n.getComponent(Label).string = str + } + /** 设置子节点文字 */ + static SetChildRichText(node:Node, path:string, str:string) { + str = String(str) + let n = node.getChildByPath(path) + n.getComponent(RichText).string = str + } + /** 设置节点文字颜色 */ + static SetLabColor(node:Node, str:string) { + node.getComponent(Label).color = Color.fromHEX(new Color(), str) + } + /** 设置子节点字体颜色 */ + static SetChildLabColor(node:Node, path:string, str:string) { + let n = node.getChildByPath(path) + n.getComponent(Label).color = Color.fromHEX(new Color(), str) + } + + /** 设置节点大小 */ + static SetSize(node:Node, size:Size) { + node.getComponent(UITransform).setContentSize(size); + } + + /** 设置节点触摸事件 */ + static SetTouchEndEvt(node:Node, func:Function) { + node.off(Node.EventType.TOUCH_END) + node.on(Node.EventType.TOUCH_END, func) + } + + /** 设置子节点触摸事件 */ + static SetChildTouchEndEvt(node:Node, path:string, func:Function) { + let n = node.getChildByPath(path) + if (n) this.SetTouchEndEvt(n, func) + } + //#endregion + + + //#region 字符串操作 + /** + ** 替换占位符{0},{1}.... + ** 例子: const message = Tools.stringFormat("My name is {0} and I am {1} years old.", name, age); + */ + static StringFormat(format: string, ...args: any[]): string { + return format.replace(/{(\d+)}/g, (match, index) => { + return typeof args[index] !== "undefined" ? args[index] : match; + }); + } + + static StringLFormat(format: string, ...args: any[]): string { + format = this.GetLocalized(format) + return this.StringFormat(format, ...args) + } + //#endregion + + + //#region 其他 + /** 本地化 */ + static GetLocalized(str : string) { + return str + //return LabelConfig[str] ? LabelConfig[str][LocalizadManager.getInstance().getLanauge()-1] : str + } + /** 压缩上传图片成base64 */ + static CompressImageToBase64(param:any, callback:Function = null){ + var fileList = param.files[0]; + var reader = new FileReader(); + reader.readAsDataURL(fileList); + reader.onload = (event) => { + let image = new Image() //新建一个img标签(还没嵌入DOM节点) + var dataImg = event.target.result; + var num = 1; + //@ts-ignore + image.src = event.target.result + image.onload = () => { + //由于不能将太多Base64字符给服务端发过于,咱们压缩一下 + //如果想支持更大图片,请继续加判断,增加除数 + // 检查文件大小是否超过20M + if (fileList.size > 20000000) { + console.log("文件大小不能大于20M!"); + param.value = ''; + return; + } + // 根据文件大小设置num值 + for (const threshold of sizeThresholds) { + if (fileList.size > threshold.size) { + num = threshold.num; + break; + } + } + let canvas = document.createElement('canvas'); + let context = canvas.getContext('2d'); + let imageWidth = image.width / num; //压缩后图片的大小 + let imageHeight = image.height / num; + const minSize = 640; // 设置最小尺寸 + if (imageWidth < minSize || imageHeight < minSize) { + const scaleFactor = Math.max(minSize / imageWidth, minSize / imageHeight); + imageWidth *= scaleFactor; + imageHeight *= scaleFactor; + } + canvas.width = imageWidth; + canvas.height = imageHeight; + context.drawImage(image, 0, 0, imageWidth, imageHeight); + dataImg = canvas.toDataURL('image/png'); + //此时的dataImg就是你要上传给服务器的字符 + param.value = ''; + if (callback) callback(dataImg) + return dataImg; + } + }; + } + + /** 生成二维码 */ + // static SetQRCode(text: string, item : Node){ + // const qr = QRCode(0, 'M'); + // qr.addData(text); + // qr.make(); + // const dataUrl = qr.createDataURL(4, 4); + // const img = new Image(); + // img.src = dataUrl; + + // assetManager.loadRemote(dataUrl, {ext : '.png'}, (err, imgAsset: ImageAsset) => { + // if (err) { + // console.error(err.message || err); + // return; + // } + // const sp = new SpriteFrame() + // const tx = new Texture2D() + // tx.image = imgAsset + // sp.texture = tx + // item.getComponent(Sprite).spriteFrame = sp + // }) + // } + + /** 通过base64字符串设置图片 */ + static SetBase64Pic(src: string, node: Node): void { + let image = new Image() + image.src = src // base 64是string,看后端返回是二进制,是否带头data:image/png;base64, 不带要手动添加 + image.onload = () => { + let texture = new Texture2D() + texture.image = new ImageAsset(image) + let _frame = new SpriteFrame() + _frame.texture = texture + // 获取节点的容器 + let c = node.getComponent(Sprite) + if (c) c.spriteFrame = _frame + } + } + + /** 复制到剪切板 */ + static CopyToClipboard(str:string) { + var input = str + ''; + const el = document.createElement('textarea'); + el.value = input; + el.setAttribute('readonly', ''); + el.style.contain = 'strict'; + el.style.position = 'absolute'; + el.style.left = '-9999px'; + el.style.fontSize = '12pt'; // Prevent zooming on iOS + + const selection = getSelection(); + var originalRange = null; + if (selection.rangeCount > 0) { + originalRange = selection.getRangeAt(0); + } + document.body.appendChild(el); + el.select(); + el.selectionStart = 0; + el.selectionEnd = input.length; + + var success = false; + try { + success = document.execCommand('copy'); + } catch (err) {} + + document.body.removeChild(el); + + if (originalRange) { + selection.removeAllRanges(); + selection.addRange(originalRange); + } + app.manager.ui.showToast("复制成功") + return success; + } + + /** 获取代理等级本地化 */ + static GetAgentLvLocalized(agentLv:string, lv :number) { + return this.StringFormat(this.GetLocalized(agentLv), lv) + } + + /** 设置代理等级图标 */ + // static SetAgentLvIcon(item:Node, agentLv:string, lv :number) { + // if (!AGENT_LV_TO_PIC[agentLv]) return + // var icon = "icon" + AGENT_LV_TO_PIC[agentLv] + this.Return2LengthNumber(lv) + // this.SetSpriteFrame(item, icon, "Lobby/ui/allagent/icon") + // } + + /** 设置子节点代理等级图标 */ + // static SetChildAgentLvIcon(item:Node, path :string, agentLv:string, lv :number) { + // let n = item.getChildByPath(path) + // this.SetAgentLvIcon(n, agentLv, lv) + // } + + /** 返回两位数 */ + static Return2LengthNumber(n : number) { + return n < 10 ? "0" + n : n.toString() + } + + //#endregion + + + //#region 数学算法 + static MathClampZeroToOne(value: number): number { + return Math.max(0, Math.min(1, value)); + } + + static MathClamp(value: number, min: number, max: number): number { + return Math.max(min, Math.min(max, value)); + } + //#endregion + + + static OpenWeb(url:string) { + const link = document.createElement('a'); + link.href = url; + link.target = '_blank'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + + /** + * 获取指定长度随机字符串 + */ + public static getRandomStr (len:number) { + let chars = + 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz' + let maxPos = chars.length + let pwd = '' + for (let i = 0; i < len; i++) { + pwd += chars.charAt(Math.floor(Math.random() * maxPos)) + } + return pwd + } + + /** + * 使用 crypto-js 生成签名 + * @param data - 要签名的数据 + * @param key - 签名密钥 + * @param encrypt - 加密算法 (sha1, sha256) + * @returns Promise 签名结果 + */ + public static generateSignNative( + data: Record, + key: string, + encrypt: string = 'sha256' + ): Promise { + // 1. 对数据进行排序 + const sortedData = Tools.sortData(data); + + // 2. 构建查询字符串(自定义实现) + const queryString = Object.keys(sortedData) + .map(k => encodeURIComponent(k) + "=" + encodeURIComponent(sortedData[k])) + .join("&"); + + // 3. URL解码并拼接密钥 + const decodedString = decodeURIComponent(queryString); + const str = decodedString + key; + + // 4. 根据算法生成签名 + let hash; + switch (encrypt.toLowerCase()) { + case 'sha1': + hash = CryptoJS.SHA1(str); + break; + case 'sha256': + default: + hash = CryptoJS.SHA256(str); + break; + } + + // 5. 返回十六进制字符串 + return Promise.resolve(hash.toString(CryptoJS.enc.Hex)); + } + + // 示例排序函数(你已有的话可以直接用) + public static sortData(data: Record): Record { + return Object.keys(data) + .sort() + .reduce((acc, key) => { + acc[key] = data[key]; + return acc; + }, {} as Record); + } + + + + //#region 加密解密 + /** 解析JWT令牌 */ + public static parseJWT(token: string) { + try { + const parts = token.split('.'); + if (parts.length !== 3) { + throw new Error('Invalid JWT token'); + } + + // 解码 payload 部分(第二部分) + const payload = JSON.parse(atob(parts[1])); + return payload; + } catch (error) { + console.error('Failed to parse JWT token:', error); + return null; + } + } + + + /** + * 解密 DES-ECB 模式加密的数据 + * @param encryptedData base64编码的加密数据 + * @param secretKey 8位密钥 + * @returns 解密后的字符串 + */ + static desEcbDecrypt(encryptedData: string, secretKey: string): string { + try { + // 确保密钥为8位 (PHP的openssl_encrypt会自动截取前8位) + const key = secretKey.length > 8 ? secretKey.substring(0, 8) : this.padKey(secretKey, 8); + + // 创建CryptoJS格式的密钥 + const keyWordArray = CryptoJS.enc.Utf8.parse(key); + + // 解密 + const decrypted = CryptoJS.DES.decrypt( + encryptedData, + keyWordArray, + { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + } + ); + + return decrypted.toString(CryptoJS.enc.Utf8); + } catch (error) { + console.error('DES-ECB decryption failed:', error); + return ''; + } + } + + /** + * 加密 DES-ECB 模式数据 + * @param data 待加密的数据 + * @param secretKey 8位密钥 + * @returns base64编码的加密数据 + */ + static desEcbEncrypt(data: string, secretKey: string): string { + try { + // 确保密钥为8位 + const key = secretKey.length > 8 ? secretKey.substring(0, 8) : this.padKey(secretKey, 8); + + // 创建CryptoJS格式的密钥 + const keyWordArray = CryptoJS.enc.Utf8.parse(key); + + // 加密 + const encrypted = CryptoJS.DES.encrypt( + data, + keyWordArray, + { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + } + ); + + return encrypted.toString(); + } catch (error) { + console.error('DES-ECB encryption failed:', error); + return ''; + } + } + + /** + * 补齐或截断密钥到指定长度 + * @param key 原始密钥 + * @param length 目标长度 + */ + private static padKey(key: string, length: number): string { + if (key.length > length) { + return key.substring(0, length); + } else if (key.length < length) { + while (key.length < length) { + key += '\0'; // 用null字符补齐 + } + return key; + } + return key; + } + + /** + * 3DES-ECB 解密 (Triple DES) + * @param encryptedData base64编码的加密数据 + * @param secretKey 24位密钥 (3DES需要24字节密钥) + * @returns 解密后的字符串 + */ + static tripleDesEcbDecrypt(encryptedData: string, secretKey: string): string { + try { + // 确保密钥为24位 + const key = this.padKey(secretKey, 24); + + // 创建CryptoJS格式的密钥 + const keyWordArray = CryptoJS.enc.Utf8.parse(key); + + // 解密 + const decrypted = CryptoJS.TripleDES.decrypt( + encryptedData, + keyWordArray, + { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + } + ); + + return decrypted.toString(CryptoJS.enc.Utf8); + } catch (error) { + console.error('3DES-ECB decryption failed:', error); + return ''; + } + } + + /** + * 3DES-ECB 加密 (Triple DES) + * @param data 待加密的数据 + * @param secretKey 24位密钥 + * @returns base64编码的加密数据 + */ + static tripleDesEcbEncrypt(data: string, secretKey: string): string { + try { + // 确保密钥为24位 + const key = this.padKey(secretKey, 24); + + // 创建CryptoJS格式的密钥 + const keyWordArray = CryptoJS.enc.Utf8.parse(key); + + // 加密 + const encrypted = CryptoJS.TripleDES.encrypt( + data, + keyWordArray, + { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + } + ); + + return encrypted.toString(); + } catch (error) { + console.error('3DES-ECB encryption failed:', error); + return ''; + } + } + + //#endregion +} diff --git a/assets/res-native/tools/Tools.ts.meta b/assets/res-native/tools/Tools.ts.meta new file mode 100644 index 0000000..31a3d09 --- /dev/null +++ b/assets/res-native/tools/Tools.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "20f5e370-8629-444b-85bb-ebe2ee037cff", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/build-templates/templates-version.json b/build-templates/templates-version.json new file mode 100644 index 0000000..2acab2b --- /dev/null +++ b/build-templates/templates-version.json @@ -0,0 +1,4 @@ +{ + "web-desktop": "1.0.0", + "web-mobile": "1.0.0" +} diff --git a/build-templates/web-desktop/index.ejs b/build-templates/web-desktop/index.ejs new file mode 100755 index 0000000..f96cfca --- /dev/null +++ b/build-templates/web-desktop/index.ejs @@ -0,0 +1,36 @@ + + + + + + <%= projectName %> + + + + + + + + + + + + + + + + + +

+ +
+
+ +
+
+ + <%- include(cocosTemplate, {}) %> + + diff --git a/build-templates/web-mobile/index.ejs b/build-templates/web-mobile/index.ejs new file mode 100755 index 0000000..37ecd37 --- /dev/null +++ b/build-templates/web-mobile/index.ejs @@ -0,0 +1,47 @@ + + + + + + <%= projectName %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ <%- include(cocosTemplate, {}) %> + + diff --git a/cliconfig.json b/cliconfig.json new file mode 100644 index 0000000..6de44dc --- /dev/null +++ b/cliconfig.json @@ -0,0 +1,4 @@ +{ + "type": "Creator3D", + "version": "3.5.13" +} \ No newline at end of file diff --git a/extensions/app/README-CN.md b/extensions/app/README-CN.md new file mode 100755 index 0000000..0d238da --- /dev/null +++ b/extensions/app/README-CN.md @@ -0,0 +1,16 @@ +# 项目简介 + +框架核心。 + +## 开发环境 + +Node.js + +## 安装 + +```bash +# 安装依赖模块 +npm install +# 构建 +npm run build +``` diff --git a/extensions/app/README-EN.md b/extensions/app/README-EN.md new file mode 100755 index 0000000..b487848 --- /dev/null +++ b/extensions/app/README-EN.md @@ -0,0 +1,16 @@ +# Project Title + +The core of the framework + +## Development Environment + +Node.js + +## Install + +```bash +# Install dependent modules +npm install +# build +npm run build +``` diff --git a/extensions/app/assets/Core.ts b/extensions/app/assets/Core.ts new file mode 100644 index 0000000..f314424 --- /dev/null +++ b/extensions/app/assets/Core.ts @@ -0,0 +1,142 @@ +import { Component, Director, director, EventTarget, js } from 'cc'; +import { DEV, EDITOR } from 'cc/env'; +import * as debug from './lib/debug/debug'; +import logger from './lib/logger/logger'; +import storage from './lib/storage/storage'; +import task from './lib/task/task'; +import EventManager from './manager/event/EventManager'; +import LoaderManager from './manager/loader/LoaderManager'; +import SoundManager from './manager/sound/SoundManager'; +import TimerManager from './manager/timer/TimerManager'; +import UIManager from './manager/ui/UIManager'; + +enum EventType { + /**AppInit准备完毕 */ + EVENT_APPINIT_FINISHED = 'EVENT_APPINIT_FINISHED', + /**系统Manager初始化完毕 */ + EVENT_SYS_MANAGER_INITED = 'EVENT_SYS_MANAGER_INITED', + /**用户Manager初始化完毕 */ + EVENT_USER_MANAGER_INITED = 'EVENT_USER_MANAGER_INITED', + /**所有Manager初始化完毕 */ + EVENT_MANAGER_INITED = 'EVENT_MANAGER_INITED', + /**所有Manager准备完毕 */ + EVENT_MANAGER_FINISHED = 'EVENT_MANAGER_FINISHED' +} + +type IData = { [key in string]: any }; +type IConfig = { [key in string]: any }; +type IStore = { [key in string]: any }; +type ICtrl = { [key in string]: any }; + +interface ITypeofManager { + Loader: Omit, + Event: Omit, + Sound: Omit, + Timer: Omit, + UI: Omit +} + +interface IManager { + loader: Omit, + event: Omit, + sound: Omit, keyof Component>, + timer: Omit, + ui: Omit, keyof Component> +} + +interface ICore { + data: IData, + config: IConfig, + store: IStore, + controller: ICtrl, + Controller: ICtrl, + manager: IManager, + Manager: ITypeofManager +} + +const Lib = { task, storage, debug, logger }; +const Config = {}; +const Data = {}; +const Store = {}; +const controller = {}; +const Controller = {}; +const Manager = {}; +const manager = {}; + +const eventTarget = new EventTarget(); +let EventMap = {}; + +director.on(Director.EVENT_RESET, () => { + js.clear(Config); + js.clear(Data); + js.clear(Store); + js.clear(controller); + js.clear(Controller); + js.clear(Manager); + js.clear(manager); + + EventMap = {}; +}); + +export default class Core { + static EventType = EventType; + + protected static _inst: Core | undefined; + static get inst() { + if (!this._inst) this._inst = new Core(); + return this._inst; + } + + lib = Lib; + config: T['config'] = null; + data: T['data'] = null; + store: T['store'] = null; + Controller: T['Controller'] = null; + controller: T['controller'] = null; + Manager: T['Manager'] = null; + manager: T['manager'] = null; + + constructor() { + this.config = Config; + this.data = Data; + this.store = Store; + this.Controller = Controller; + this.controller = controller; + this.Manager = Manager as any; + this.manager = manager as any; + if (!EDITOR || DEV) { + if (this.constructor !== Core && !js.getClassById('App')) { + js.setClassAlias(this.constructor as any, 'App'); + } + } + } + + on(event: keyof typeof EventType, callback: (...any: any[]) => void, target?: any): any { + if (EventMap[event]) callback.call(target); + eventTarget.on(event, callback, target); + } + + once(event: keyof typeof EventType, callback: Function, target?: any): any { + if (EventMap[event]) { + callback.call(target); + } else { + eventTarget.once(event, callback as any, target); + } + } + + off(event: keyof typeof EventType, callback: (...any: any[]) => void, target?: any): any { + eventTarget.off(event, callback, target); + } + + targetOff(target: any) { + eventTarget.targetOff(target); + } + + /** + * 请不要手动调用 + */ + static emit(event: keyof typeof EventType, ...args: any[]): any { + EventMap[event] = true; + eventTarget.emit(event, ...args); + } +} \ No newline at end of file diff --git a/extensions/app/assets/Core.ts.meta b/extensions/app/assets/Core.ts.meta new file mode 100644 index 0000000..4b7439e --- /dev/null +++ b/extensions/app/assets/Core.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "b4a49372-fa9e-4448-b91b-29bc9701d9ff", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/app.ts.meta b/extensions/app/assets/app.ts.meta new file mode 100644 index 0000000..0efe5c2 --- /dev/null +++ b/extensions/app/assets/app.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "0ceacfb9-e86a-4e83-bd5d-15a4a27185c8", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base.meta b/extensions/app/assets/base.meta new file mode 100644 index 0000000..2570a4b --- /dev/null +++ b/extensions/app/assets/base.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "2fb050e0-159f-4a3b-b24c-3d76e43ac54d", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/base/BaseAppInit.ts b/extensions/app/assets/base/BaseAppInit.ts new file mode 100644 index 0000000..ed6793c --- /dev/null +++ b/extensions/app/assets/base/BaseAppInit.ts @@ -0,0 +1,275 @@ +import { Button, Component, EventTouch, Node, Settings, _decorator, assetManager, isValid, settings, warn } from 'cc'; +import { EDITOR } from 'cc/env'; +import Core from '../Core'; +import BaseManager from './BaseManager'; +const { ccclass } = _decorator; + +const AdminBundleName = 'app-admin'; +const ModelBundleName = 'app-model'; +const ControlBundleName = 'app-control'; +const ControllerBundleName = 'app-controller'; +const ManagerBundleName = 'app-manager'; +const DontRewriteFuns = ['startInit', 'nextInit']; + +@ccclass('BaseAppInit') +export default abstract class BaseAppInit extends Component { + private get _base_mgr_total() { + return Math.max(0, BaseManager.getTotalAssetNum(assetManager.getBundle(ManagerBundleName))); + } + private get _base_user_total() { + return Math.max(0, this.getUserAssetNum()); + } + private get _base_total() { + return this._base_mgr_total + this._base_user_total; + } + + private _base_mgr_completed = 0; + private _base_user_completed = 0; + private get _base_completed() { + return this._base_mgr_completed + Math.min(this._base_user_total, this._base_user_completed); + } + + private _base_inited = false; + private _base_finished = false; + + constructor() { + super(); + if (EDITOR) { + DontRewriteFuns.forEach((funName) => { + if (BaseAppInit.prototype[funName] !== this[funName]) { + warn(`[AppInit] 不应该重写父类方法{${funName}}`); + } + }); + } + } + + /** + * [避免重写] 开始初始化 + */ + protected startInit() { + const projectBundles = settings.querySettings(Settings.Category.ASSETS, 'projectBundles') as string[]; + Core.inst.lib.task.createAny() + // 预加载control、model、admin、manager + .add([ + (next, retry) => { + // 预加载control(废弃) + if (projectBundles.indexOf(ControlBundleName) === -1) return next(); + assetManager.preloadAny({ url: ControlBundleName }, { ext: 'bundle' }, null, (err) => { + if (err) return retry(0.1); + next(); + }); + }, + (next, retry) => { + // 预加载controller + if (projectBundles.indexOf(ControllerBundleName) === -1) return next(); + assetManager.preloadAny({ url: ControllerBundleName }, { ext: 'bundle' }, null, (err) => { + if (err) return retry(0.1); + next(); + }); + }, + (next, retry) => { + // 预加载model + if (projectBundles.indexOf(ModelBundleName) === -1) return next(); + assetManager.preloadAny({ url: ModelBundleName }, { ext: 'bundle' }, null, (err) => { + if (err) return retry(0.1); + next(); + }); + }, + (next, retry) => { + // 预加载admin + if (projectBundles.indexOf(AdminBundleName) === -1) return next(); + assetManager.preloadAny({ url: AdminBundleName }, { ext: 'bundle' }, null, (err) => { + if (err) return retry(0.1); + next(); + }); + }, + (next, retry) => { + // 预加载manage + if (projectBundles.indexOf(ManagerBundleName) === -1) return next(); + assetManager.preloadAny({ url: ManagerBundleName }, { ext: 'bundle' }, null, (err) => { + if (err) return retry(0.1); + next(); + }); + } + ]) + // 加载control(废弃) + .add((next, retry) => { + if (projectBundles.indexOf(ControlBundleName) === -1) return next(); + assetManager.loadBundle(ControlBundleName, (err) => { + if (err) return retry(0.1); + next(); + }); + }) + // 加载controller + .add((next, retry) => { + if (projectBundles.indexOf(ControllerBundleName) === -1) return next(); + assetManager.loadBundle(ControllerBundleName, (err) => { + if (err) return retry(0.1); + next(); + }); + }) + // 加载model + .add((next, retry) => { + if (projectBundles.indexOf(ModelBundleName) === -1) return next(); + assetManager.loadBundle(ModelBundleName, (err) => { + if (err) return retry(0.1); + next(); + }); + }) + // 加载admin + .add((next, retry) => { + if (projectBundles.indexOf(AdminBundleName) === -1) return next(); + assetManager.loadBundle(AdminBundleName, (err) => { + if (err) return retry(0.1); + next(); + }); + }) + // 加载manager + .add((next, retry) => { + if (projectBundles.indexOf(ManagerBundleName) === -1) return next(); + assetManager.loadBundle(ManagerBundleName, (err) => { + if (err) return retry(0.1); + next(); + }); + }) + .start(() => { + this._base_inited = true; + this.onProgress(0, this._base_total); + + // 初始化app, 使用complete来实现onUserInit的切换以确保manager已完全加载 + BaseManager.init( + assetManager.getBundle(ManagerBundleName), + () => { + this.innerNextInit(); + }, + () => { + this.onUserInit(); + if (this._base_completed < this._base_total) return; + // 全部加载完成 + this.innerFinished(); + } + ); + }); + } + + /** + * [不可重写] 用于内部初始化完成 + */ + private innerFinished() { + if (this._base_finished) return; + this._base_finished = true; + Core.emit(Core.EventType.EVENT_APPINIT_FINISHED); + // 默认音效(Button点击触发, 这个方案可以正常触发input事件) + if (Core.inst.Manager.Sound.setting.defaultEffectName) { + const playDefaultEffect = function (e: EventTouch) { + // SoundManager.setButtonEffect会将Button所在节点的useDefaultEffect设为false + if (e.target['useDefaultEffect'] === false) return; + Core.inst.manager.ui.onceUserInterface(Node.EventType.TOUCH_END, function (event: EventTouch) { + if (!event.target.getComponent(Button)) return; + setTimeout(() => { + if (!isValid(Core.inst.manager.sound)) return; + // 如果是scrollView中的button,在滑动后不播放点击音效 + if (event.eventPhase === EventTouch.CAPTURING_PHASE) return; + Core.inst.manager.sound.playDefaultEffect(); + }); + }, null, true); + }; + const onEnable = Button.prototype.onEnable; + Button.prototype.onEnable = function () { + onEnable.call(this); + this.node.on(Node.EventType.TOUCH_START, playDefaultEffect); + }; + const onDisable = Button.prototype.onDisable; + Button.prototype.onDisable = function () { + this.node.off(Node.EventType.TOUCH_START, playDefaultEffect); + onDisable.call(this); + }; + } + return Core.inst.manager.ui.showDefault(() => { + // 初始化完成 + this.onFinish(); + // 默认音乐(默认播放) + if (Core.inst.Manager.Sound.setting.defaultMusicName) { + const onTouch = function () { + if (!isValid(Core.inst.manager.sound)) return; + if (Core.inst.manager.sound.isMusicPlaying && !Core.inst.manager.sound.isMusicPaused) { + Core.inst.manager.sound.replayMusic(() => { + Core.inst.manager.ui.offUserInterface(Node.EventType.TOUCH_START, onTouch, this, true); + }); + } else { + Core.inst.manager.ui.offUserInterface(Node.EventType.TOUCH_START, onTouch, this, true); + } + }; + Core.inst.manager.ui.onUserInterface(Node.EventType.TOUCH_START, onTouch, this, true); + Core.inst.manager.sound.playDefaultMusic(() => { + Core.inst.manager.ui.offUserInterface(Node.EventType.TOUCH_START, onTouch, this, true); + }); + } + }); + } + + /** + * [不可重写] 用于内部初始化 + */ + private innerNextInit() { + // 完成+1 + this._base_mgr_completed += 1; + // 进度回调 + this.onProgress(this._base_completed, this._base_total); + } + + /** + * [避免重写] 初始化下一步,用户部分每完成一步需要调用一次 + */ + protected nextInit(): any { + if (this._base_finished) return; + + if (!this._base_inited) { + // 完成+1 + this._base_user_completed += 1; + // 进度回调 + this.onProgress(this._base_completed, this._base_total); + return; + } + + // 完成+1 + this._base_user_completed += 1; + // 进度回调 + this.onProgress(this._base_completed, this._base_total); + + // 全部加载完成 + if (this._base_completed >= this._base_total) { + this.innerFinished(); + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////// 以下可重写 //////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * [可以重写] 默认start调用startInit,可以重写后自定义时机 + */ + protected start(): any { this.startInit(); } + + /** + * [可以重写] 获得用户资源总量,这里返回几,就需要用户自行调用几次nextInit + */ + protected getUserAssetNum(): number { return 0; } + + /** + * [可以重写] 用户初始化函数,会在框架初始化完成后调用 + */ + protected onUserInit(): any { return 0; } + + /** + * [可以重写] 监听进度 + * @param {Number} completed + * @param {Number} total + */ + protected onProgress(completed: number, total: number): any { return completed / total; } + + /** + * [可以重写] 初始化完成 + */ + protected onFinish() { } +} \ No newline at end of file diff --git a/extensions/app/assets/base/BaseAppInit.ts.meta b/extensions/app/assets/base/BaseAppInit.ts.meta new file mode 100644 index 0000000..8678d4a --- /dev/null +++ b/extensions/app/assets/base/BaseAppInit.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "2110b07a-1c6c-430e-b9d9-926db06c8b30", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base/BaseControl.ts b/extensions/app/assets/base/BaseControl.ts new file mode 100644 index 0000000..98feaa8 --- /dev/null +++ b/extensions/app/assets/base/BaseControl.ts @@ -0,0 +1,179 @@ +class CallbackInfo { + public callback: Function = null; + public target: unknown = null; + public once = false; + + public constructor(callback: Function, target: unknown = null, once: boolean = false) { + this.callback = callback; + this.target = target; + this.once = once; + } +} + +type Parameters any> = T extends (...args: infer P) => any ? P : any; +type AnyFunc = (...args: any[]) => any; + +class CallbackList { + private callbacks: CallbackInfo[] = []; + + public size() { + return this.callbacks.length; + } + + public add(callback: Function, target: unknown = null, once: boolean = false) { + this.callbacks.push(new CallbackInfo(callback, target, once)); + } + + public emit(args: any[]) { + for (let index = 0; index < this.callbacks.length; index++) { + const info = this.callbacks[index]; + // 先移除 + if (info.once) { + this.callbacks.splice(index, 1); + --index; + } + if (info.callback) { + info.callback.apply(info.target, args); + } + } + } + + public call(args: any[]) { + if (this.callbacks.length === 0) return; + const info = this.callbacks[0]; + + // 先移除 + if (info.once) this.callbacks.splice(0, 1); + if (!info.callback) return; + + return info.callback.apply(info.target, args); + } + + public remove(callback: Function, target: unknown = null) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.callback !== callback || info.target !== target) continue; + this.callbacks.splice(index, 1); + } + } + + public removeByCallback(callback: Function) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.callback !== callback) continue; + this.callbacks.splice(index, 1); + } + } + + public removeByTarget(target: unknown) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.target !== target) continue; + this.callbacks.splice(index, 1); + } + } +} + +class EventEmitter { + private listeners: { [key in string]: CallbackList } = {}; + + public on(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) this.listeners[event] = new CallbackList(); + this.listeners[event].add(cb, target); + } + + public once(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) this.listeners[event] = new CallbackList(); + this.listeners[event].add(cb, target, true); + } + + public off(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) return; + + this.listeners[event].remove(cb, target); + } + + public targetOff(target?: unknown) { + if (!target) return; + + for (const key in this.listeners) { + if (Object.prototype.hasOwnProperty.call(this.listeners, key)) { + const element = this.listeners[key]; + element.removeByTarget(target); + } + } + } + + public emit(event: string | number, args: any[]) { + if (!event.toString()) return; + if (!this.listeners[event]) return; + this.listeners[event].emit(args); + } + + public call(event: string | number, args: any[]) { + if (!event.toString()) return; + if (!this.listeners[event]) return; + return this.listeners[event].call(args); + } +} + +export interface IBaseControl { + readonly inst: Readonly + + //用于类型提示推导//////////////// + new(): SuperBaseControl// + /////////////////////////////// +} + +class SuperBaseControl { + //用于类型提示推导// + private e: E;//// + private t: T;//// + ///////////////// + + private event = new EventEmitter(); + + protected call(key: E[K], ...args: Parameters): ReturnType { + return this.event.call.call(this.event, key, args); + } + + protected emit(key: E[K], ...args: Parameters): void { + return this.event.emit.call(this.event, key, args); + } + + private on(...args: any[]): void { + return this.event.on.apply(this.event, args); + } + + private once(...args: any[]): void { + return this.event.once.apply(this.event, args); + } + + private off(...args: any[]): void { + return this.event.off.apply(this.event, args); + } + + private targetOff(target: any): void { + return this.event.targetOff.call(this.event, target); + } +} + +/** + * @deprecated 废弃,请使用Controller代替Control + */ +export default function BaseControl(Event?: E) { + return class BaseControl extends SuperBaseControl { + public static Event = Event; + + private static _base_inst: Readonly = null; + public static get inst() { + if (this._base_inst === null) { + this._base_inst = new this() as C; + } + return this._base_inst; + } + }; +} \ No newline at end of file diff --git a/extensions/app/assets/base/BaseControl.ts.meta b/extensions/app/assets/base/BaseControl.ts.meta new file mode 100644 index 0000000..303d8a2 --- /dev/null +++ b/extensions/app/assets/base/BaseControl.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "fb1039b9-17f2-43b5-ad26-8d74e691b4f5", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base/BaseController.ts b/extensions/app/assets/base/BaseController.ts new file mode 100644 index 0000000..9eccc4b --- /dev/null +++ b/extensions/app/assets/base/BaseController.ts @@ -0,0 +1,211 @@ +import { DEV } from 'cc/env'; +import { IReadOnly } from '../../../../assets/app-builtin/app-admin/executor'; +import { Logger } from '../lib/logger/logger'; + +class CallbackInfo { + public callback: Function = null; + public target: unknown = null; + public once = false; + + public constructor(callback: Function, target: unknown = null, once: boolean = false) { + this.callback = callback; + this.target = target; + this.once = once; + } +} + +type Parameters any> = T extends (...args: infer P) => any ? P : any; +type AnyFunc = (...args: any[]) => any; + +class CallbackList { + private callbacks: CallbackInfo[] = []; + + public size() { + return this.callbacks.length; + } + + public add(callback: Function, target: unknown = null, once: boolean = false) { + this.callbacks.push(new CallbackInfo(callback, target, once)); + } + + public emit(args: any[]) { + for (let index = 0; index < this.callbacks.length; index++) { + const info = this.callbacks[index]; + // 先移除 + if (info.once) { + this.callbacks.splice(index, 1); + --index; + } + if (info.callback) { + info.callback.apply(info.target, args); + } + } + } + + public call(args: any[]) { + if (this.callbacks.length === 0) return; + const info = this.callbacks[0]; + + // 先移除 + if (info.once) this.callbacks.splice(0, 1); + if (!info.callback) return; + + return info.callback.apply(info.target, args); + } + + public remove(callback: Function, target: unknown = null) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.callback !== callback || info.target !== target) continue; + this.callbacks.splice(index, 1); + } + } + + public removeByCallback(callback: Function) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.callback !== callback) continue; + this.callbacks.splice(index, 1); + } + } + + public removeByTarget(target: unknown) { + for (let index = this.callbacks.length - 1; index >= 0; index--) { + const info = this.callbacks[index]; + if (info.target !== target) continue; + this.callbacks.splice(index, 1); + } + } +} + +class EventEmitter { + private listeners: { [key in string]: CallbackList } = {}; + + public on(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) this.listeners[event] = new CallbackList(); + this.listeners[event].add(cb, target); + } + + public once(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) this.listeners[event] = new CallbackList(); + this.listeners[event].add(cb, target, true); + } + + public off(event: string | number, cb: (...data: any[]) => void, target?: unknown) { + if (!event.toString() || !cb) return; + if (!this.listeners[event]) return; + + this.listeners[event].remove(cb, target); + } + + public targetOff(target?: unknown) { + if (!target) return; + + for (const key in this.listeners) { + if (Object.prototype.hasOwnProperty.call(this.listeners, key)) { + const element = this.listeners[key]; + element.removeByTarget(target); + } + } + } + + public emit(event: string | number, args: any[]) { + if (!event.toString()) return; + if (!this.listeners[event]) return; + this.listeners[event].emit(args); + } + + public call(event: string | number, args: any[]) { + if (!event.toString()) return; + if (!this.listeners[event]) return; + return this.listeners[event].call(args); + } +} + +export interface IBaseController { + readonly inst: Readonly + + //用于类型提示推导//////////////// + new(): SuperBaseController// + /////////////////////////////// +} + +class SuperBaseController { + //用于类型提示推导// + private t: T;//// + ///////////////// + + private event = new EventEmitter(); + + /**获取第一个事件回调的返回值 */ + protected call(key: K, ...args: Parameters): ReturnType { + return this.event.call.call(this.event, key, args); + } + + /**发射事件 */ + protected emit(key: K, ...args: Parameters): void { + return this.event.emit.call(this.event, key, args); + } + + private on(...args: any[]): void { + return this.event.on.apply(this.event, args); + } + + private once(...args: any[]): void { + return this.event.once.apply(this.event, args); + } + + private off(...args: any[]): void { + return this.event.off.apply(this.event, args); + } + + private targetOff(target: any): void { + return this.event.targetOff.call(this.event, target); + } + + /**打印日志 */ + protected get log(): Function { + return Logger.create('log', '#4682b4', DEV ? `[${this['constructor'].name}] LOG` : `[${this['constructor'].name}] [LOG]`); + } + + /**打印警告 */ + protected get warn(): Function { + return Logger.create('warn', '#ff7f50', DEV ? `[${this['constructor'].name}] WARN` : `[${this['constructor'].name}] [WARN]`); + } + + /**打印错误 */ + protected get error(): Function { + return Logger.create('error', '#ff4757', DEV ? `[${this['constructor'].name}] ERROR` : `[${this['constructor'].name}] [ERROR]`); + } +} + +export default function BaseController() { + return class BaseController extends SuperBaseController { + /** + * 控制器事件 + */ + public static Event: { [key in keyof T]: key } = new Proxy({} as any, { + get: function (target, key) { + if (target[key]) return target[key]; + target[key] = key; + return key; + } + }); + + private static _base_inst: IReadOnly = null; + /** + * 控制器单例 + * - 尽量使用app.controller,可以避免因跨Bundle引用导致的问题,也可以避免Controller之间循环引用的问题 + */ + public static get inst() { + return this._base_inst; + } + + constructor() { + super(); + BaseController._base_inst = this as any; + } + }; +} \ No newline at end of file diff --git a/extensions/app/assets/base/BaseController.ts.meta b/extensions/app/assets/base/BaseController.ts.meta new file mode 100644 index 0000000..3d4f957 --- /dev/null +++ b/extensions/app/assets/base/BaseController.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "a7da7081-e604-487e-8e0c-7d458fdbb356", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base/BaseManager.ts b/extensions/app/assets/base/BaseManager.ts new file mode 100644 index 0000000..8b8ab0c --- /dev/null +++ b/extensions/app/assets/base/BaseManager.ts @@ -0,0 +1,359 @@ +import { AssetManager, Component, EventTarget, Prefab, Widget, _decorator, error, instantiate, js, path, warn } from 'cc'; +import { DEBUG, DEV, EDITOR } from 'cc/env'; +import Core from '../Core'; +import { Logger } from '../lib/logger/logger'; + +const { ccclass } = _decorator; + +const UserManagerPath = 'UserManager'; +const DontRewriteFuns = ['emit', 'on', 'once', 'off', 'targetOff']; + +const uuid = new class UUID { + private index = 0; + + public create(): string { + if (this.index++ > 10000000) { + this.index = 0; + } + return `${Date.now()}-${this.index}`; + } +}; + +const loadBegin = Logger.create('log', '#32cd32', DEV ? '[BaseManager] 下载开始' : '[BaseManager] [下载开始]'); + +const loadFinish = Logger.create('log', '#00ae9d', DEV ? '[BaseManager] 下载完成' : '[BaseManager] [下载完成]'); + +const loadError = Logger.create('log', '#ff4757', DEV ? '[BaseManager] 下载失败' : '[BaseManager] [下载失败]'); + +const initBegin = Logger.create('log', '#3e4145', DEV ? '[BaseManager] 初始化开始' : '[BaseManager] [初始化开始]'); + +const initFinish = Logger.create('log', '#008080', DEV ? '[BaseManager] 初始化完成' : '[BaseManager] [初始化完成]'); + +@ccclass('BaseManager') +export default class BaseManager extends Component { + // 事件管理器 + private _base_event: EventTarget = new EventTarget(); + + // manager名字 + private _base_manager_name: string = js.getClassName(this); + public get managerName() { + return this._base_manager_name; + } + + constructor() { + super(); + + if (EDITOR) { + DontRewriteFuns.forEach((funName) => { + if (BaseManager.prototype[funName] !== this[funName]) { + warn(`[${this._base_manager_name}] 不应该重写父类方法{${funName}}`); + } + }); + } + + if (this._base_manager_name !== 'Manager' && this._base_manager_name.slice(-7) === 'Manager') { + const managerName = this._base_manager_name.slice(0, - 7); + Core.inst.Manager[managerName] = this.constructor; + Core.inst.manager[managerName.toLowerCase()] = this; + } else if (EDITOR) { + error(`[${this._base_manager_name}] manager命名错误(应为 xxxxManager 以Manager结尾)`); + } else if (DEBUG) { + error(`[${this._base_manager_name}] manager命名错误(应为 xxxxManager 以Manager结尾)`); + } + } + + // 用来初始化组件或节点的一些属性,当该组件被第一次添加到节点上或用户点击了它的 Reset 菜单时调用。这个回调只会在编辑器下调用。 + resetInEditor() { + const widget = this.node.getComponent(Widget) || this.node.addComponent(Widget); + widget.isAlignBottom = true; + widget.isAlignLeft = true; + widget.isAlignRight = true; + widget.isAlignTop = true; + widget.top = 0; + widget.left = 0; + widget.right = 0; + widget.bottom = 0; + widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE; + } + + /** + * [无序] 自身初始化完成, init执行完毕后被调用 + */ + protected onInited() { + } + + /** + * [无序] 所有manager初始化完成 + */ + protected onFinished() { + } + + /** + * [无序] 初始化manager,在初始化完成后,调用finish方法 + * @param {Function} finish + */ + protected init(finish?: Function) { + finish && finish(); + } + + protected createUUID() { + return uuid.create(); + } + + /**打印日志 */ + protected get log() { + if (DEV) { + return window.console.log.bind(window.console, + '%c %s %c %s ', + 'background:#4169e1; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #4169e1; color: #fff; font-weight: normal;', + `[${this._base_manager_name}] LOG ${new Date().toLocaleString()}`, + 'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #4169e1; color: #4169e1; font-weight: normal;' + ); + } + return window.console.log.bind(window.console, + `[${this._base_manager_name}] [LOG] [${new Date().toLocaleString()}]`, + ); + } + + /**打印警告 */ + protected get warn() { + if (DEV) { + return window.console.warn.bind(window.console, + '%c %s %c %s ', + 'background:#ff7f50; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #ff7f50; color: #fff; font-weight: normal;', + `[${this._base_manager_name}] WARN ${new Date().toLocaleString()}`, + 'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #ff7f50; color: #ff7f50; font-weight: normal;' + ); + } + return window.console.warn.bind(window.console, + `[${this._base_manager_name}] [WARN] [${new Date().toLocaleString()}]`, + ); + } + + /**打印错误 */ + protected get error() { + if (DEV) { + return window.console.error.bind(window.console, + '%c %s %c %s ', + 'background:#ff4757; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #ff4757; color: #fff; font-weight: normal;', + `[${this._base_manager_name}] ERROR ${new Date().toLocaleString()}`, + 'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #ff4757; color: #ff4757; font-weight: normal;' + ); + } + return window.console.error.bind(window.console, + `[${this._base_manager_name}] [ERROR] [${new Date().toLocaleString()}]`, + ); + } + + /** + * [系统内置] 事件分发 + */ + public emit(event: string | number, ...data: any[]) { + this._base_event.emit(event as any, ...data); + } + + /** + * [系统内置] 事件监听 + */ + public on(event: string | number, cb: (...any: any[]) => void, target?: any) { + this._base_event.on(event as any, cb, target); + } + + /** + * [系统内置] 事件监听 + */ + public once(event: string | number, cb: (...any: any[]) => void, target?: any) { + this._base_event.once(event as any, cb, target); + } + + /** + * [系统内置] 事件移除监听 + */ + public off(event: string | number, cb?: (...any: any[]) => void, target?: any) { + this._base_event.off(event as any, cb, target); + } + + /** + * [系统内置] 事件移除监听 + */ + public targetOff(target: any) { + this._base_event.targetOff(target); + } + + /***********************************静态***********************************/ + /** + * 框架内置Manager的数量 + * @private + */ + public static get sysMgrCount() { + return 5; + } + + /** + * 获得初始化资源的数量(包括sysMgrCount) + * @private + */ + public static getTotalAssetNum(bundle: AssetManager.Bundle) { + let count = this.sysMgrCount; + + if (!bundle) return count; + + const array = bundle.getDirWithPath('/', Prefab) as { uuid: string, path: string, ctor: Function }[]; + + array.forEach(function (item) { + if (item.path.endsWith('Manager')) { + count++; + } + }); + + return count; + } + + /** + * 获得初始化资源的数量 + * @private + */ + public static getUserAssetUrls(bundle: AssetManager.Bundle) { + const pathArr: string[] = []; + + if (!bundle) return pathArr; + + const array = bundle.getDirWithPath('/', Prefab) as { uuid: string, path: string, ctor: Function }[]; + + array.forEach(function (item) { + if (item.path.endsWith('Manager')) { + pathArr.push(item.path); + } + }); + + return pathArr; + } + + /** + * 静态方法,初始化manager,该方法必须在场景初始化完毕之后调用 + * @private + */ + public static init( + bundle: AssetManager.Bundle, + progress: (completeAsset: Number, totalAsset: Number) => any, + complete: (totalAsset: Number) => any) { + const urls = this.getUserAssetUrls(bundle); + + const totalAsset = urls.length + this.sysMgrCount; + let completeAsset = 0; + + const onProgress = function (next: Function, manager: BaseManager) { + if (DEBUG) { + const startTime = window?.performance?.now ? performance.now() : Date.now(); + initBegin(manager.managerName); + return function () { + manager.onInited(); + if (DEBUG) { + const endTime = window?.performance?.now ? performance.now() : Date.now(); + initFinish(`${manager.managerName} 耗时:${(endTime - startTime).toFixed(6)} ms`); + } + progress && progress(++completeAsset, totalAsset); + next(); + }; + } + return function () { + manager.onInited(); + progress && progress(++completeAsset, totalAsset); + next(); + }; + }; + + // 用户manager(动态添加) + const userMgrList: BaseManager[] = []; + // 系统manager(静态内置) + const sysMgrList: BaseManager[] = [Core.inst.manager.event, Core.inst.manager.timer, Core.inst.manager.loader, Core.inst.manager.ui, Core.inst.manager.sound] as any as BaseManager[]; + + // 初始化系统manager + const initSysMgrTask = Core.inst.lib.task.createASync(); + sysMgrList.forEach(function (manager: BaseManager) { + initSysMgrTask.add(function (next) { + manager.init(onProgress(next, manager)); + }); + }); + + // 加载用户manager + const loadUserMgrTask = Core.inst.lib.task.createASync(); + const UserManagerRoot = Core.inst.manager.ui.root.getChildByPath(UserManagerPath); + urls.forEach(function (url) { + loadUserMgrTask.add(function (next, retry) { + if (DEBUG) { + const managerName = path.basename(url); + const startTime = window?.performance?.now ? performance.now() : Date.now(); + loadBegin(managerName); + bundle.load(url, Prefab, function (err, prefab: Prefab) { + if (err || !prefab) { + loadError(managerName, '重试...'); + retry(1); + } else { + const endTime = window?.performance?.now ? performance.now() : Date.now(); + loadFinish(`${managerName} 耗时:${(endTime - startTime).toFixed(6)} ms`); + const node = instantiate(prefab); + node.parent = UserManagerRoot; + node.active = true; + userMgrList.push(node.getComponent(BaseManager)); + next(); + } + }); + return; + } + bundle.load(url, Prefab, function (err, prefab: Prefab) { + if (err || !prefab) { + loadError(path.basename(url), '重试...'); + retry(1); + } else { + const node = instantiate(prefab); + node.parent = UserManagerRoot; + node.active = true; + userMgrList.push(node.getComponent(BaseManager)); + next(); + } + }); + }); + }); + + Core.inst.lib.task.createAny() + .add([ + next => initSysMgrTask.start(next), + next => loadUserMgrTask.start(next), + ]) + .add(function (next) { + Core.emit(Core.EventType.EVENT_SYS_MANAGER_INITED); + next(); + }) + .add(function (next) { + // 初始化用户manager + const initUserMgrTask = Core.inst.lib.task.createASync(); + userMgrList.forEach(manager => { + initUserMgrTask.add(function (next) { + manager.init(onProgress(next, manager)); + }); + }); + initUserMgrTask.start(next); + }) + .add(function (next) { + Core.emit(Core.EventType.EVENT_USER_MANAGER_INITED); + Core.emit(Core.EventType.EVENT_MANAGER_INITED); + next(); + }) + .add(function (next) { + // 所有manager初始化完成后,触发回调 + sysMgrList.forEach(function (manager) { + manager.onFinished(); + }); + userMgrList.forEach(function (manager) { + manager.onFinished(); + }); + next(); + }) + .start(function () { + Core.emit(Core.EventType.EVENT_MANAGER_FINISHED); + complete && complete(totalAsset); + }); + } + +} \ No newline at end of file diff --git a/extensions/app/assets/base/BaseManager.ts.meta b/extensions/app/assets/base/BaseManager.ts.meta new file mode 100644 index 0000000..7e2a3f0 --- /dev/null +++ b/extensions/app/assets/base/BaseManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "30205eac-9b1e-4f44-8081-7b70ff8d6c52", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base/BaseModel.ts b/extensions/app/assets/base/BaseModel.ts new file mode 100644 index 0000000..0ecd1ff --- /dev/null +++ b/extensions/app/assets/base/BaseModel.ts @@ -0,0 +1,43 @@ +// export type IModel = { +// [P in keyof T]: T[P] extends Function +// ? '❌此处不能定义任何方法' +// : ( +// T[P] extends Array +// ? ( +// R extends Function +// ? '❌此处不能定义任何方法' +// : T[P] +// ) +// : T[P] // IModel 性能消耗大 +// ); +// }; + +// export type IStore = { +// [P in keyof T]: T[P] extends Function +// ? T[P] +// : ( +// T[P] extends Array +// ? ( +// R extends Function +// ? '❌此处不能定义任何方法' +// : IModel +// ) +// : IModel +// ); +// }; + +export type IModel = { + [P in keyof T]: T[P] extends Function + ? '❌此处不能定义任何方法' + : T[P]; +}; + +// export type IStore = { +// [P in keyof T]: T[P] extends Function +// ? T[P] +// : IModel; +// }; + +export type IStore = { + [P in keyof T]: T[P]; +}; \ No newline at end of file diff --git a/extensions/app/assets/base/BaseModel.ts.meta b/extensions/app/assets/base/BaseModel.ts.meta new file mode 100644 index 0000000..ecdd708 --- /dev/null +++ b/extensions/app/assets/base/BaseModel.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "7a377ceb-e086-4e71-99bd-f44dab40d24f", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/base/BaseView.ts b/extensions/app/assets/base/BaseView.ts new file mode 100644 index 0000000..d1bba3f --- /dev/null +++ b/extensions/app/assets/base/BaseView.ts @@ -0,0 +1,1035 @@ +import { Asset, Component, Enum, EventTouch, Font, Label, Node, Scene, Sprite, SpriteFrame, UITransform, Widget, _decorator, director, isValid, js, sp } from 'cc'; +import { DEV, EDITOR } from 'cc/env'; +import { IMiniViewName, IMiniViewNames, IViewName } from '../../../../assets/app-builtin/app-admin/executor'; +import Core from '../Core'; +import { Logger } from '../lib/logger/logger'; +import { IBaseControl } from './BaseControl'; +import { IBaseController } from './BaseController'; + +const { ccclass, property, disallowMultiple } = _decorator; + +const BlockEvents = [ + Node.EventType.TOUCH_START, Node.EventType.TOUCH_MOVE, Node.EventType.TOUCH_END, Node.EventType.TOUCH_CANCEL, + Node.EventType.MOUSE_DOWN, Node.EventType.MOUSE_MOVE, Node.EventType.MOUSE_UP, + Node.EventType.MOUSE_ENTER, Node.EventType.MOUSE_LEAVE, Node.EventType.MOUSE_WHEEL +]; + +const HideEvent = Enum({ + destroy: 1, + active: 2 +}); + +export type IShade = { + /**等待 默认0秒 */ + delay?: number, + /**开始透明度 默认60 */ + begin?: number, + /**结束透明度 默认180 */ + end?: number, + /**透明变化速度 默认100 */ + speed?: number, + /** + * 毛玻璃效果 默认false + * - 开启后其它参数将无效 + */ + blur?: boolean, +}; + +export interface IShowParamAttr { + zIndex?: number, + siblingIndex?: number, +} + +export interface IShowParamOnShow { + (result: T): any +} + +export interface IShowParamOnHide { + (result: T): any +} + +export interface IShowParamBeforeShow { + (error: string): any +} + +export interface IShowParamInnerLoad { + (name: string, path: string, type: { prototype: Asset }, callback: (result: Asset) => any): void +} + +export interface IHideParamOnHide { + (result: T): any +} + +export type IViewType = 'Page' | 'Paper' | 'Pop' | 'Top'; + +export enum ViewType { + Page = 'Page', + Paper = 'Paper', + PaperAll = 'PaperAll', + Pop = 'Pop', + Top = 'Top' +} + +interface IMiniOnShow { + (name: IMiniViewName, data?: any): any +} +interface IMiniOnHide { + (name: IMiniViewName, data?: any): any +} +interface IMiniOnFinish { + (): any +} +type IPick = { + -readonly [P in keyof T]: T[P] extends Function + ? T[P] + : (T[P] extends Object + ? IPick + : T[P]); +}; +interface IBaseViewController { + new(): BaseView & { + readonly controller: IPick & Readonly<{ + /**获取第一个事件回调的返回值 */ + emit(key: K, ...args: Parameters): void; + /**发射事件 */ + call(key: K, ...args: Parameters): ReturnType; + /**注册事件回调 */ + on(key: K, callback: (...args: Parameters) => ReturnType, target?: any): void; + /**注册一次性事件回调 */ + once(key: K, callback: (...args: Parameters) => ReturnType, target?: any): void; + /**取消事件回调 */ + off(key: keyof T, callback: Function, target?: any): void; + /**取消事件回调 */ + targetOff(target: any): void; + }> + } +} + +enum ViewState { + BeforeShow, + Showing, + Showed, + BeforeHide, + Hiding, + Hid, +} + +const Group = { id: 'BaseView', name: 'Settings', displayOrder: -Infinity, style: 'section' }; + +// 记录PaperAll的owner +const PaperAllToOwner: Map = new Map(); + +@ccclass('BaseView') +@disallowMultiple() +export default class BaseView extends Component { + /** + * @deprecated 废弃,请使用BindController代替BindControl + */ + static BindControl(Control: IBaseControl) { + return class BindControl extends BaseView { + protected get control(): Pick & Readonly<{ + call(key: E[K], ...args: Parameters): ReturnType; + emit(key: E[K], ...args: Parameters): void; + on(key: E[K], callback: (...args: Parameters) => ReturnType, target?: any): void; + once(key: E[K], callback: (...args: Parameters) => ReturnType, target?: any): void; + off(key: E[keyof E], callback: Function, target?: any): void; + targetOff(target: any): void; + }> { + return Control ? Control.inst as any : null; + } + }; + } + + /** + * 给UI绑定一个控制器,绑定后可以通过this.controller访问,并能访问一些内部方法(emit、on、once、off、targetOff) + */ + static BindController(Controller: IBaseController) { + @disallowMultiple() + class BindController extends BaseView { + protected get controller() { + return Controller ? Controller.inst as any : null; + } + } + return BindController as any as IBaseViewController; + } + + /** + * 是否有效,如果返回false的话,app.manager.ui.show会触发onError回调 + */ + public static isViewValid(next: (valid: boolean) => void, data: any) { + data; + next && next(true); + } + + public static isPage(name: string) { + return name.indexOf(ViewType.Page) === 0; + } + + public static isPaper(name: string) { + return name.indexOf(ViewType.Paper) === 0; + } + + public static isPaperAll(name: string) { + return name.indexOf(ViewType.PaperAll) === 0; + } + + public static isPop(name: string) { + return name.indexOf(ViewType.Pop) === 0; + } + + public static isTop(name: string) { + return name.indexOf(ViewType.Top) === 0; + } + + // 是否被调用过 + private _base_view_created = false; + // view状态 + private _base_view_state = ViewState.Hid; + // 当前view的名字 + private _base_view_name: IViewName | IMiniViewName = js.getClassName(this) as any; + // 触摸是否有效 + private _base_touch_enable = true; + // show/hide等待列表 + private _base_show_hide_delays: Function[] = []; + // 子界面融合相关 + private _base_mini_show: Set = new Set(); + + protected isPage() { + return BaseView.isPage(this._base_view_name); + } + + protected isPaper() { + return BaseView.isPaper(this._base_view_name); + } + + protected isPaperAll() { + return BaseView.isPaperAll(this._base_view_name); + } + + protected isPop() { + return BaseView.isPop(this._base_view_name); + } + + protected isTop() { + return BaseView.isTop(this._base_view_name); + } + + protected is2D() { + return !this.is3D(); + } + + protected is3D() { + if (this.node.parent instanceof Scene) { + return this.node.parent.name === this.viewName; + } + const scene = director.getScene(); + return scene.name === this.viewName; + } + + @property + private _hideEvent = HideEvent.destroy; + @property({ + group: Group, + type: HideEvent, + tooltip: '何种模式隐藏节点\n1、destroy: 销毁UI并释放对应的所有资源\n2、active: 缓存UI并加速下次的打开速度', + }) + public get hideEvent() { + if (this.is3D()) return HideEvent.destroy; + return this._hideEvent; + } + public set hideEvent(value) { + if (this.is3D() && value !== HideEvent.destroy) { + this.log('3D模式下只能是destroy模式'); + return; + } + this._hideEvent = value; + } + + @property + private _singleton = true; + private static _singleton = true; + @property({ + group: Group, + tooltip: '是否是单例模式\n1、单例模式: UI只会被创建一次(onShow会被重复触发)\n2、非单例模式: UI会被重复创建', + }) + protected get singleton(): boolean { + if (this.isPage()) return true; + if (this.isPaperAll()) return true; + if (this.isPaper()) return true; + return this._singleton && (this.constructor)._singleton; + } + protected set singleton(value) { + if (!value) { + if (this.isPage()) { + this.log('Page只能是单例模式'); + return; + } + if (this.isPaper()) { + this.log('Paper只能是单例模式'); + return; + } + } + this._singleton = (this.constructor)._singleton = !!value; + } + + @property + private _captureFocus = true; + @property({ + group: Group, + tooltip: '是否捕获焦点<响应onLostFocus和onFocus>\n1、当一个捕获焦点的UI处于最上层并展示时\n下层的UI永远不会响应focus事件', + visible(this: BaseView) { + if (this.is3D()) return false; + return true; + } + }) + protected get captureFocus() { + if (this.is3D()) return false; + return this._captureFocus; + } + protected set captureFocus(value) { + if (value && this.is3D()) { + this.log('只有2D模式下才可以捕获焦点'); + return; + } + + if (!EDITOR && this._captureFocus !== value) { + this._captureFocus = value; + Core.inst?.manager?.ui?.refreshShade(); + } else { + this._captureFocus = value; + } + } + + @property + private _shade = true; + @property({ + group: Group, + tooltip: '是否需要底层遮罩', + visible(this: BaseView) { + if (this.is3D()) return false; + if (this.isPage()) return false; + return true; + } + }) + protected get shade() { + if (this.is3D()) return false; + if (this.isPage()) return false; + return this._shade; + } + protected set shade(value) { + if (value) { + if (this.is3D()) { + this.log('只有2D模式下才可以设置底层遮罩'); + return; + } + if (this.isPage()) { + this.log('Page不可以设置底层遮罩'); + return; + } + } + + if (!EDITOR && this._shade !== value) { + this._shade = value; + Core.inst?.manager?.ui?.refreshShade(); + } else { + this._shade = value; + } + } + + @property + private _blockInput = true; + @property({ + group: Group, + tooltip: '是否禁止点击事件向下层传递', + visible(this: BaseView) { + if (this.is3D()) return false; + return true; + } + }) + protected get blockInput() { + if (this.is3D()) return false; + return this._blockInput; + } + protected set blockInput(value) { + if (value && this.is3D()) { + this.log('只有2D模式下才可以设置阻断点击事件'); + return; + } + this._blockInput = value; + } + + /** 修改框架、新增isAlwaysExist选项,如果勾选,则不会自动隐藏旧页面 */ + @property + private _alwaysExist = false; + @property({ + group: Group, + tooltip: '界面是否始终存在\- 打开另外界面后不会被关闭', + visible(this: BaseView) { + if (this.is3D()) return false; + return true; + } + }) + protected get alwaysExist() { + if (this.is3D()) return false; + return this._alwaysExist; + } + protected set alwaysExist(value) { + if (value && this.is3D()) { + this.log('只有2D模式下才可以设置界面是否始终存在'); + return; + } + this._alwaysExist = value; + } + + /** + * 子界面(只能用于Page) + */ + protected miniViews: IMiniViewNames = []; + + /** + * 当前view名字 + */ + public get viewName() { + return this._base_view_name; + } + + /** + * 基础名字, 如PageHome => Home + */ + public get baseName() { + return this._base_view_name.slice(this.typeName.length); + } + + /** + * 类型名字, 如PageHome => Page + */ + public get typeName() { + if (this._base_view_name.indexOf(ViewType.Paper) === 0) return ViewType.Paper; + if (this._base_view_name.indexOf(ViewType.Pop) === 0) return ViewType.Pop; + if (this._base_view_name.indexOf(ViewType.Top) === 0) return ViewType.Top; + return ViewType.Page; + } + + /** + * 是否是单例模式 + */ + public get isSingleton(): boolean { + return this.singleton; + } + + /** + * 是否捕获焦点 + */ + public get isCaptureFocus(): boolean { + return this.captureFocus; + } + + /** + * 是否需要遮罩 + */ + public get isNeedShade(): boolean { + return this.shade; + } + + /** + * 是否展示了(不为Hid状态) + */ + public get isShow(): boolean { + return this._base_view_state != ViewState.Hid; + } + + /** + * 打开其他界面时,此界面不关闭 + */ + public get isAlwaysExist(): boolean { + return this._alwaysExist; + } + + /** + * 是否show了某个子界面 + */ + protected isMiniViewShow(name: IMiniViewName) { + return this._base_mini_show.has(name); + } + + // 用来初始化组件或节点的一些属性,当该组件被第一次添加到节点上或用户点击了它的 Reset 菜单时调用。这个回调只会在编辑器下调用。 + resetInEditor(): any { + if (EDITOR) { + const is3D = this.is3D(); + if (this.viewName.indexOf(ViewType.Page) >= 0) { + this.shade = false; + this.blockInput = is3D ? false : true; + this.captureFocus = is3D ? false : true; + } else if (this.viewName.indexOf(ViewType.Paper) >= 0) { + this.shade = false; + this.captureFocus = false; + this.blockInput = false; + } + + if (is3D) return; + this.node.getComponent(UITransform) || this.node.addComponent(UITransform); + + const widget = this.node.getComponent(Widget) || this.node.addComponent(Widget); + widget.isAlignBottom = true; + widget.isAlignLeft = true; + widget.isAlignRight = true; + widget.isAlignTop = true; + widget.top = 0; + widget.left = 0; + widget.right = 0; + widget.bottom = 0; + widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE; + } + } + + /** + * 设置是否可点击 + */ + protected setTouchEnabled(enabled: boolean = true): any { + this._base_touch_enable = !!enabled; + } + + private blockPropagation(event: EventTouch) { + if (this.blockInput) { + event.propagationStopped = true; + if (event.type === Node.EventType.TOUCH_START) { + this.log('阻断触摸向下层传递'); + } + } + } + + private stopPropagation(event: EventTouch) { + if (!this._base_touch_enable) { + event.propagationStopped = true; + event.propagationImmediateStopped = true; + if (event.type === Node.EventType.TOUCH_START) { + this.log('屏蔽触摸'); + } + } + } + + private onBaseViewCreate(): any { + if (this.is3D()) return; + const uiTransform = this.getComponent(UITransform); + if (uiTransform) uiTransform.hitTest = (...args: any[]): boolean => { + if (this.blockInput) { + return UITransform.prototype.hitTest.apply(uiTransform, args); + } + return false; + }; + + for (let i = 0; i < BlockEvents.length; i++) { + this.node.on(BlockEvents[i], this.blockPropagation, this); + this.node.on(BlockEvents[i], this.stopPropagation, this, true); + } + } + + /** + * 关闭所有子界面 + */ + protected hideAllMiniViews(data?: any) { + this._base_mini_show.forEach((name) => { + Core.inst.manager.ui.hide({ name, data }); + }); + this._base_mini_show.clear(); + } + + /** + * 关闭子界面 + */ + protected hideMiniViews({ data, views }: { data?: any, views: IMiniViewNames }) { + if (this.miniViews.length === 0) return; + if (views.length === 0) return; + + views.forEach(name => { + if (this.miniViews.indexOf(name) === -1) { + this.warn('hideMiniViews', `${name}不在miniViews中, 已跳过`); + return; + } + + // 验证 + if (!this._base_mini_show.has(name)) return; + // 关闭 + Core.inst.manager.ui.hide({ name, data }); + }); + // TODO 手动刷新一下Paper下的UI顺序(原因是原生环境,显示层级正确但触摸层级可能会不正确) + Core.inst.manager.ui.sortUserInterface('Paper'); + } + + /** + * 展示子界面 + */ + protected showMiniViews({ data, views, onShow, onHide, onFinish }: { + /**传递给子界面的数据 */ + data?: any, + /**子界面名字列表 */ + views: Array, + /**子界面展示回调 */ + onShow?: IMiniOnShow, + /**子界面关闭回调 */ + onHide?: IMiniOnHide, + /**子界面融合完成回调 */ + onFinish?: IMiniOnFinish + }) { + if (views.length === 0) return false; + if (this.typeName !== ViewType.Page) { + this.warn('showMiniViews', '仅支持Page类型'); + return false; + } + + const task = Core.inst.lib.task.createSync(); + + for (let index = 0; index < views.length; index++) { + const names = views[index]; + if (names instanceof Array) { + task.add(next => { + this.createMixMiniViewsTask(names, data, onShow, onHide).start(next); + }); + } else { + task.add(next => { + this.createMixMiniViewsTask([names], data, onShow, onHide).start(next); + }); + } + } + + task.start(onFinish && function () { + onFinish(); + }); + + return true; + } + + /** + * 创建自定义加载任务 + */ + private createMixMiniViewsTask(views: IMiniViewNames = [], data?: any, onShow?: IMiniOnShow, onHide?: IMiniOnHide) { + const task = Core.inst.lib.task.createSync(); + + if (this.typeName !== ViewType.Page) { + this.warn('showMiniViews', '仅支持Page类型'); + return task; + } + + views = views.filter(name => { + if (!name) { + this.warn('showMiniViews', 'name不能为空'); + return false; + } + if (this._base_mini_show.has(name)) { + this.warn('showMiniViews', `重复融合${name}, 已跳过`); + return false; + } + if (this.miniViews.indexOf(name) === -1) { + this.warn('showMiniViews', `${name}不在miniViews中, 已跳过`); + return false; + } + if (name.indexOf(this.baseName) !== ViewType.Paper.length && name.indexOf(ViewType.PaperAll) !== 0) { + this.warn('showMiniViews', `${name}不属于当前Page, 已跳过`); + return false; + } + + this._base_mini_show.add(name); + return true; + }); + + if (views.length === 0) return task; + + // 先load全部 + task.add((next) => { + const aSync = Core.inst.lib.task.createASync(); + views.forEach(name => { + aSync.add((next, retry) => { + this.log(`下载子页面: ${name}`); + Core.inst.manager.ui.load(name as any, result => { + result ? next() : this.scheduleOnce(retry, 0.1); + }); + }); + }); + aSync.start(next); + }); + + // 再show全部 + task.add((next) => { + const aSync = Core.inst.lib.task.createASync(); + views.forEach(name => { + aSync.add((next) => { + if (!this._base_mini_show?.has(name)) return next(); + + this.log(`展示子页面: ${name}`); + // 是PaperAll,设置owner + if (BaseView.isPaperAll(name)) { + PaperAllToOwner.set(name, this.uuid); + } + Core.inst.manager.ui.show({ + name, data, + silent: true, + attr: { zIndex: this.miniViews.indexOf(name) }, + onShow: (result) => { + if (onShow) onShow(name, result); + next(); + }, + onHide: (result) => { + if (BaseView.isPaperAll(name)) { + // 验证PaperAll是否属于当前Page + const owner = PaperAllToOwner.get(name); + if (owner && owner === this.uuid) { + PaperAllToOwner.delete(name); + } + } + this._base_mini_show?.delete(name); + if (onHide) onHide(name, result); + }, + onError: (result, code) => { + if (code === Core.inst.Manager.UI.ErrorCode.LoadError) return true; + if (BaseView.isPaperAll(name)) { + // 验证PaperAll是否属于当前Page + const owner = PaperAllToOwner.get(name); + if (owner && owner === this.uuid) { + PaperAllToOwner.delete(name); + Core.inst.manager.ui.hide({ name }); + } + } + this._base_mini_show?.delete(name); + this.warn('忽略子页面', name, result); + next(); + }, + }); + }); + }); + aSync.start(() => { + // TODO 手动刷新一下Paper下的UI顺序(原因是原生环境,显示层级正确但触摸层级可能会不正确) + Core.inst.manager.ui.sortUserInterface('Paper'); + next(); + }); + }); + + return task; + } + + /** + * 设置节点属性 + */ + private setNodeAttr(attr: IShowParamAttr) { + if (!attr) return; + if (typeof attr.zIndex === 'number') { + // 以z坐标来代替2.x时代的zIndex + this.node.setPosition(this.node.position.x, this.node.position.y, attr.zIndex); + } + + if (typeof attr.siblingIndex === 'number') { + this.node.setSiblingIndex(attr.siblingIndex); + } + } + + private show(data?: any, attr?: IShowParamAttr, onShow?: IShowParamOnShow, onHide?: IShowParamOnHide, beforeShow?: IShowParamBeforeShow) { + // 当前show操作需要等待其它流程 + if (this._base_view_state !== ViewState.Showed && + this._base_view_state !== ViewState.Hid) { + this._base_show_hide_delays.push( + this.show.bind(this, data, attr, onShow, onHide, beforeShow) + ); + return; + } + + // show流程 + const changeState = this._base_view_state === ViewState.Hid; + if (changeState) this._base_view_state = ViewState.BeforeShow; + const next = (error: string) => { + if (!error) { + // 所有Paper只会是单例,而且所有Paper都不允许被当前Page重复show + // 但PaprAll比较特殊,会被不同的Page使用,在PaperAll被不同的Page重复show时,清除之前的onHide + if (this.isPaperAll()) this.node.emit('onHide'); + } + beforeShow && beforeShow(error); + if (!error) { + // 设置展示中 + if (changeState) this._base_view_state = ViewState.Showing; + onHide && this.node.once('onHide', onHide); + + // 触发onCreate + if (this._base_view_created === false) { + this._base_view_created = true; + this.onBaseViewCreate(); + } + + // 设置属性 + this.setNodeAttr(attr); + + // 触发onLoad、onEnable + if (this.node.active !== true) { this.node.active = true; } + + this.log('onShow'); + let result = null; + try { + result = this.onShow(data); + } catch (err) { + this.onError(); + console.error(err); + } + + // 设置遮罩,触发focus逻辑 + Core.inst.manager.ui.refreshShade(); + + try { + onShow && onShow(result); + this.node.emit('onShow', result); + Core.inst.manager.ui.emit(this._base_view_name, { event: 'onShow', result: result }); + Core.inst.manager.ui.emit('onShow', { name: this._base_view_name, result: result }); + } catch (err) { + console.error(err); + } + + if (changeState) this._base_view_state = ViewState.Showed; + } else { + if (changeState) this._base_view_state = ViewState.Hid; + } + + if (this._base_show_hide_delays.length > 0) { + this._base_show_hide_delays.shift()(); + } + }; + + this.log('beforeShow'); + let isNextCalled = false; + this.beforeShow((error) => { + if (isNextCalled) return this.error('beforeShow', 'next被重复调用'); + isNextCalled = true; + next(error || null); + }, data); + } + + protected hide( + //@ts-ignore + data?: Parameters[0], + onHide?: IHideParamOnHide) { + + // 当前hide操作需要等待其它流程 + if (this._base_view_state !== ViewState.Hid && + this._base_view_state !== ViewState.Showed) { + this._base_show_hide_delays.push( + this.hide.bind(this, data, onHide) + ); + return; + } + + // hide流程 + const changeState = this._base_view_state === ViewState.Showed; + if (changeState) this._base_view_state = ViewState.BeforeHide; + this.log('beforeHide'); + const error = this.beforeHide(data); + if (!error) { + this.log('onHide'); + if (changeState) this._base_view_state = ViewState.Hiding; + this.hideAllMiniViews(data); + + let result = null; + try { + result = this.onHide(data); + } catch (error) { + console.error(error); + } + + try { + onHide && onHide(result); + this.node.emit('onHide', result); + Core.inst.manager.ui.emit(this._base_view_name, { event: 'onHide', result: result }); + Core.inst.manager.ui.emit('onHide', { name: this._base_view_name, result: result }); + } catch (error) { + console.error(error); + } + + if (changeState) this._base_view_state = ViewState.Hid; + + if (this.hideEvent === HideEvent.active) { this.node.active = false; } + else if (this.hideEvent === HideEvent.destroy) { Core.inst.manager.ui.release(this); } + Core.inst.manager.ui.refreshShade(); + } else { + if (changeState) this._base_view_state = ViewState.Showed; + } + + if (this._base_show_hide_delays.length > 0) { + this._base_show_hide_delays.shift()(); + } + } + + private focus(boo: boolean): any { + let result = null; + let event = ''; + if (boo) { + result = this.onFocus(); + event = 'onFocus'; + } else { + result = this.onLostFocus(); + event = 'onLostFocus'; + } + + this.node.emit(event, result); + Core.inst.manager.ui.emit(this._base_view_name, { event: event, result: result }); + Core.inst.manager.ui.emit(event, { name: this._base_view_name, result: result }); + } + + /** + * 加载UI目录下resources里面的资源 + * @param path 相对于resources的路径 + * @param callback 回调 + * this.loadRes('Bag', Prefab, function(asset){}) + */ + protected loadRes(path: string, type: T, callback?: (result: InstanceType | null) => any) { + Core.inst.manager.ui.loadRes(this, path, type, callback); + } + + /** + * 预加载UI目录下resources里面的资源 + * @param path 相对于resources的路径 + * this.preloadRes('Bag', Prefab) + */ + protected preloadRes(path: string, type: T) { + Core.inst.manager.ui.preloadRes(this, path, type); + } + + /** + * 加载UI目录下resources里面的资源 + * @param path 相对于resources的路径 + * @param callback 回调 + * this.loadResDir('Bag', Prefab, function(asset){}) + */ + protected loadResDir(path: string, type: T, callback?: (result: InstanceType[] | null) => any) { + Core.inst.manager.ui.loadResDir(this, path, type, callback); + } + + /** + * 预加载UI目录下resources里面的资源 + * @param path 相对于resources的路径 + * this.preloadResDir('Bag', Prefab) + */ + protected preloadResDir(path: string, type: T) { + Core.inst.manager.ui.preloadResDir(this, path, type); + } + + /** + * 设置字体资源 + * @param path UI的resources目录下的相对路径 + */ + protected setFont(target: Label, path: string, onComplete?: (success: boolean) => any) { + this.loadRes(path, Font, (font) => { + if (!font || !isValid(target)) { + return onComplete && onComplete(false); + } + target.font = font; + onComplete && onComplete(true); + }); + } + + /** + * 设置Spine资源 + * @param path UI的resources目录下的相对路径 + */ + protected setSpine(target: sp.Skeleton, path: string, onComplete?: (success: boolean) => any) { + this.loadRes(path, sp.SkeletonData, (skeletonData) => { + if (!skeletonData || !isValid(target)) { + return onComplete && onComplete(false); + } + target.skeletonData = skeletonData; + onComplete && onComplete(true); + }); + } + + /** + * 设置图片资源 + * @param path UI的resources目录下的相对路径(必须以/spriteFrame结尾) + * + * @example + * setSprite(sprite, 'img/a/spriteFrame', onComplete:(succ)=>{}) + */ + protected setSprite(target: Sprite, path: string, onComplete?: (success: boolean) => any) { + this.loadRes(path, SpriteFrame, (spriteFrame) => { + if (!spriteFrame || !isValid(target)) { + return onComplete && onComplete(false); + } + target.spriteFrame = spriteFrame; + onComplete && onComplete(true); + }); + } + + /**打印日志 */ + protected get log() { + return Logger.create('log', '#1e90ff', DEV ? `[${this._base_view_name}] LOG` : `[${this._base_view_name}] [LOG]`); + } + + /**打印警告 */ + protected get warn() { + return Logger.create('warn', '#ff7f50', DEV ? `[${this._base_view_name}] WARN` : `[${this._base_view_name}] [WARN]`); + } + + /**打印错误 */ + protected get error() { + return Logger.create('error', '#ff4757', DEV ? `[${this._base_view_name}] ERROR` : `[${this._base_view_name}] [ERROR]`); + } + + //////////////以下为可重写////////////// + /** + * 展示 + * @param data 传递给onShow的参数 + * @returns + */ + protected onShow(data?: any): any { + return data; + } + + /** + * 隐藏 + * @param data 传递给onHide的参数 + * @returns + */ + protected onHide(data?: any): any { + return data; + } + + /** + * 失去焦点 + * @returns + */ + protected onLostFocus(): any { + return true; + } + + /** + * 获得焦点 + * @returns + */ + protected onFocus(): any { + return true; + } + + /** + * onShow前调用 + * @param next 回调,传递的error不为空时,表示错误,onShow不会执行 + * @param data 传递给onShow的参数 + */ + protected beforeShow(next: (error?: string) => void, data?: any): any { + next(null); + } + + /** + * hide前调用 + * @param data 传递给onHide的参数 + * @returns 如果返回字符串,则表示错误信息 + */ + protected beforeHide(data?: any): string | void { + return null; + } + + /** + * onShow报错会执行 + */ + protected onError(): any { + return; + } + + /** + * 背景遮照的参数 + */ + protected onShade(): IShade { + return {}; + } +} \ No newline at end of file diff --git a/extensions/app/assets/base/BaseView.ts.meta b/extensions/app/assets/base/BaseView.ts.meta new file mode 100644 index 0000000..cb00cec --- /dev/null +++ b/extensions/app/assets/base/BaseView.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "eddc0411-4239-423d-8710-77fdf92affc2", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/lib.meta b/extensions/app/assets/lib.meta new file mode 100644 index 0000000..7d44e6f --- /dev/null +++ b/extensions/app/assets/lib.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "6ff04fb4-44cd-4fc4-a4b8-28ac28d83a0b", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/lib/debug.meta b/extensions/app/assets/lib/debug.meta new file mode 100644 index 0000000..dc90178 --- /dev/null +++ b/extensions/app/assets/lib/debug.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "e939f63c-c853-403c-aed7-b8f0925106f0", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/lib/debug/debug.ts b/extensions/app/assets/lib/debug/debug.ts new file mode 100644 index 0000000..e3de7a9 --- /dev/null +++ b/extensions/app/assets/lib/debug/debug.ts @@ -0,0 +1,40 @@ +import { DEBUG, DEV } from 'cc/env'; + +function jsGetSet(obj: unknown, prop: string, getter: Function, setter?: Function) { + Object.defineProperty(obj, prop, { + get: getter as any, + set: setter as any, + enumerable: false, + configurable: false + }); +} +function clear(object: Record) { + if (!object) return; + for (const key of Object.keys(object)) { + delete object[key]; + } +} +/** + * 将某个变量设置为不可观测(不可在浏览器中打印) + * @param owner object | string | number | boolean | Array | Function | ... + * @param callback 被观测时触发回调 + * @returns + */ +export function unobservable(owner: unknown, callback?: Function) { + if (DEV || DEBUG) return; + if (!owner) return; + function define() { + function accessor() { + if (callback) { + callback(); + } else { + clear(owner); + } + } + try { + jsGetSet(owner, 'unobservable', accessor.bind(null, 'de' + 'bu' + 'gg' + 'er')); + } + catch (e) { !0; } + } + define(); +} \ No newline at end of file diff --git a/extensions/app/assets/lib/debug/debug.ts.meta b/extensions/app/assets/lib/debug/debug.ts.meta new file mode 100644 index 0000000..a8648d2 --- /dev/null +++ b/extensions/app/assets/lib/debug/debug.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "c0d5da3b-23f0-400e-85bb-6c754b9c08eb", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/lib/logger.meta b/extensions/app/assets/lib/logger.meta new file mode 100644 index 0000000..b3ba8c6 --- /dev/null +++ b/extensions/app/assets/lib/logger.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "140d98c1-6885-4e37-bf16-2ee67ffe087e", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/lib/logger/logger.ts b/extensions/app/assets/lib/logger/logger.ts new file mode 100644 index 0000000..12ca8e5 --- /dev/null +++ b/extensions/app/assets/lib/logger/logger.ts @@ -0,0 +1,77 @@ +import { DEV } from 'cc/env'; + +interface ILog { + (title: string, ...args: any[]): void +} + +function empty() { } + +/** + * 日志管理类,用于统一日志输出格式 + */ +export class Logger { + static setting: { + filter: Array<'log' | 'warn' | 'error'> + } = { + filter: ['error', 'log', 'warn'] + }; + + /** + * 创建日志输出函数 + */ + static create(level: 'log' | 'warn' | 'error', styleColor: string, title: string, titleColor = '#fff') { + if (this.setting.filter.indexOf(level) == -1) { + return empty; + } + + if (DEV) { + return window.console[level].bind(window.console, + '%c %s %c %s ', + `background:${styleColor}; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid ${styleColor}; color: ${titleColor}; font-weight: normal;`, + `${title} ${new Date().toLocaleString()}`, + `background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid ${styleColor}; color: ${styleColor}; font-weight: normal;` + ); + } + return window.console[level].bind(window.console, + `${title} [${new Date().toLocaleString()}]` + ); + } + + /** + * 用于输出一般信息 + */ + get log() { + return Logger.create('log', '#6495ed', '[LOG]', '#000') as ILog; + } + + /** + * 用于输出警告信息 + */ + + get warn() { + return Logger.create('warn', '#ff7f50', '[WARN]', '#000') as ILog; + } + + /** + * 用于输出错误信息 + */ + get error() { + return Logger.create('error', '#ff4757', '[ERROR]', '#000') as ILog; + } + + /** + * 用于输出调试信息 + */ + get debug() { + return Logger.create('log', '#ff6347', '[DEBUG]', '#000') as ILog; + } + + /** + * 用于输出成功信息 + */ + get success() { + return Logger.create('log', '#00ae9d', '[SUCC]', '#000') as ILog; + } +} + +export default new Logger(); \ No newline at end of file diff --git a/extensions/app/assets/lib/logger/logger.ts.meta b/extensions/app/assets/lib/logger/logger.ts.meta new file mode 100644 index 0000000..0d81a61 --- /dev/null +++ b/extensions/app/assets/lib/logger/logger.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "0b5812e8-b67d-4ba9-83d8-12ca1e46cfd0", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/lib/storage.meta b/extensions/app/assets/lib/storage.meta new file mode 100644 index 0000000..c56449e --- /dev/null +++ b/extensions/app/assets/lib/storage.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "0c157f59-fd16-449c-b42c-d0efa2dc1401", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/lib/storage/storage.ts b/extensions/app/assets/lib/storage/storage.ts new file mode 100644 index 0000000..c94bb60 --- /dev/null +++ b/extensions/app/assets/lib/storage/storage.ts @@ -0,0 +1,236 @@ +import { error, js, log, sys } from 'cc'; + +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + +function encode(text: string, key: string) { + key = key || chars; + let encrypted = ''; + for (let i = 0; i < text.length; i++) { + const charCode = text.charCodeAt(i) ^ key.charCodeAt(i % key.length); + encrypted += String.fromCharCode(charCode); + } + return encrypted; +} + +function decode(encryptedText: string, key: string) { + key = key || chars; + let decrypted = ''; + for (let i = 0; i < encryptedText.length; i++) { + const charCode = encryptedText.charCodeAt(i) ^ key.charCodeAt(i % key.length); + decrypted += String.fromCharCode(charCode); + } + return decrypted; +} + +const weekOfYear = function (curDate?: Date) { + /* + date1是当前日期 + date2是当年第一天 + d是当前日期是今年第多少天 + 用d + 当前年的第一天的周差距的和在除以7就是本年第几周 + */ + curDate = curDate || new Date(); + let a = curDate.getFullYear(); + let b = curDate.getMonth() + 1; + let c = curDate.getDate(); + + let date1 = new Date(a, b - 1, c), date2 = new Date(a, 0, 1), + d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000); + return Math.ceil( + (d + ((date2.getDay() + 1) - 1)) / 7 + ); +}; + +const getWeekUpdateTime = function () { + const date = new Date(); + const year = date.getFullYear(); + const week = weekOfYear(date); + return year + '' + week; +}; + +const getDayUpdateTime = function (curDate?: Date) { + curDate = curDate || new Date(); + return curDate.toLocaleDateString(); +}; + +export class Storage { + static setting: { + /** + * 加密密钥 + * - 如果需要加密内容,请设置密钥的值 + */ + secretKey: string + } = { + secretKey: '' + }; + + private _cache = {}; + + /** + * 返回值为false代表调用失败 + */ + set(key: string, value: unknown) { + if (typeof key === 'string' && typeof value !== 'undefined') { + try { + const data = JSON.stringify(value); + if (Storage.setting.secretKey) { + sys.localStorage.setItem(key, encode(data, Storage.setting.secretKey)); + } else { + sys.localStorage.setItem(key, data); + } + // 设置缓存 + this._cache[key] = data; + return true; + } catch (err) { log(err); } + } else { + error('storage set error'); + } + return false; + } + + /** + * 返回值为undefined代表调用失败 + */ + get(key: string) { + // 先读取缓存 + if (typeof this._cache[key] !== 'undefined') { + return JSON.parse(this._cache[key]); + } + + let result = null; + try { + let data = sys.localStorage.getItem(key); + if (data && typeof data === 'string') { + if (Storage.setting.secretKey) data = decode(data, Storage.setting.secretKey); + // 设置缓存 + this._cache[key] = data; + result = JSON.parse(data); + } else if (data !== '' && data !== null) { + result = undefined; + } + } catch (e) { + result = undefined; + } + return result; + } + + /** + * 返回值为false代表调用失败 + */ + add(key: string, value: number = 1) { + let result = this.get(key); + if (result !== undefined) { + result = result || 0; + result += value; + if (this.set(key, result)) { + return result; + } + } + return false; + } + + /** + * 返回值为false代表调用失败 + */ + remove(key: string) { + try { + sys.localStorage.removeItem(key); + delete this._cache[key]; + return true; + } catch (err) { + return false; + } + } + + /** + * 返回值为false代表调用失败 + */ + clear() { + try { + sys.localStorage.clear(); + js.clear(this._cache); + return true; + } catch (err) { + return false; + } + } + + /** + * 设置本周数据 [返回值为false代表调用失败] + * @param {Function} cb 当已存在本周的数据时,会根据cb的返回决定是否存储,true代表存储 + */ + setWeek(key: string, value: unknown, cb?: (oldValue: unknown, newValue: unknown) => boolean) { + const updateTime = getWeekUpdateTime(); + + if (cb) { + const data = this.getWeek(key); + if (data !== undefined) { + if (data === null || cb(data, value)) { + return this.set(key, { + data: value, + updateTime: updateTime + }); + } + } + } else { + return this.set(key, { + data: value, + updateTime: updateTime + }); + } + + return false; + } + + /** + * 获取本周数据 [返回值为undefined代表调用失败] + */ + getWeek(key: string) { + const data = this.get(key); + if (data && data.updateTime == getWeekUpdateTime()) { + return data.data; + } + return data && null; + } + + /** + * 设置本天数据 [返回值为false代表调用失败] + * @param {Function} cb 当已存在本天的数据时,会根据cb的返回决定是否存储,true代表存储 + */ + setDay(key: string, value: unknown, cb?: (oldValue: unknown, newValue: unknown) => boolean) { + const updateTime = getDayUpdateTime(); + + if (cb) { + const data = this.getDay(key); + if (data !== undefined) { + if (data === null || cb(data, value)) { + return this.set(key, { + data: value, + updateTime: updateTime + }); + } + } + } else { + return this.set(key, { + data: value, + updateTime: updateTime + }); + } + + return false; + } + + /** + * 获取本天数据 [返回值为undefined代表调用失败] + * @param {*} key + */ + getDay(key: string) { + const data = this.get(key); + if (data && data.updateTime == getDayUpdateTime()) { + return data.data; + } + return data && null; + } +} + +export default new Storage(); \ No newline at end of file diff --git a/extensions/app/assets/lib/storage/storage.ts.meta b/extensions/app/assets/lib/storage/storage.ts.meta new file mode 100644 index 0000000..06beb7e --- /dev/null +++ b/extensions/app/assets/lib/storage/storage.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "be3da7ca-1bb5-4a41-894b-f82751c78ef2", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/lib/task.meta b/extensions/app/assets/lib/task.meta new file mode 100644 index 0000000..1035c96 --- /dev/null +++ b/extensions/app/assets/lib/task.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "54e30e53-aef2-4e16-8969-e38bea0ea336", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/lib/task/task.ts b/extensions/app/assets/lib/task/task.ts new file mode 100644 index 0000000..c8d4c5e --- /dev/null +++ b/extensions/app/assets/lib/task/task.ts @@ -0,0 +1,440 @@ +interface IHandle { + (next: (data?: any) => boolean, retry: (timeout?: number) => Promise, end: (data?: any) => boolean): void +} + +interface IFinish { + (results?: T, success?: boolean): any +} + +export interface ITask = any[]> { + readonly results: Readonly; + size(): number; + add(handle: IHandle): this; + start(finish?: IFinish | Function): this; + stop(): boolean; + isRunning(): boolean; +} + +/** + * 顺序执行 + */ +export class Sync> implements ITask { + private running = false; + private index: number = -1; + private list: IHandle[] = []; + private finish: IFinish | Function = null; + + /** + * 每个handle的返回值,通过next或end存储 + */ + public results: T = [] as T; + + /** + * 任务数量 + * @returns + */ + public size(): number { + return this.list.length; + } + + /** + * 添加一个任务 + * @param handle + * @returns + */ + public add(handle: IHandle) { + this.list.push(handle); + this.results.push(undefined); + return this; + } + + /** + * 开始执行所有任务 + * @param finish 执行完毕回调 + * @returns + */ + public start(finish?: IFinish | Function) { + if (this.running) { + return this; + } + + this.running = true; + this.index = -1; + this.finish = finish; + + this.next(this.index); + + return this; + } + + /** + * 停止所有任务 + * @returns + */ + public stop(): boolean { + if (!this.running) { + return false; + } + + this.running = false; + if (this.finish) { + this.finish(this.results, false); + } + + return true; + } + + /** + * 是否正在执行 + * @returns + */ + public isRunning() { + return this.running; + } + + /** + * @deprecated + * @returns + */ + public isStop() { + return !this.running; + } + + private end(data?: any): boolean { + if (!this.running) { + return false; + } + + if (typeof data !== 'undefined') { + this.results[this.index] = data; + } + + this.running = false; + if (this.finish) { + this.finish(this.results, true); + } + + return true; + } + + private next(index: number, data?: any): boolean { + if (!this.running) { + return false; + } + + if (index !== this.index) return false; + + if (typeof data !== 'undefined') { + this.results[this.index] = data; + } + + if (++this.index < this.list.length) { + this.retry(this.index); + } else { + this.end(); + } + + return true; + } + + private retry(index: number): boolean { + if (!this.running) { + return false; + } + + if (index !== this.index) return false; + + const handle = this.list[index]; + handle && handle( + (data?: any) => this.next(index, data), + (timeout = 0) => { + return new Promise(resolve => { + if (timeout > 0) { + setTimeout(() => { + resolve(this.retry(index)); + }, timeout * 1000); + } else { + resolve(this.retry(index)); + } + }); + }, + (data?: any) => this.end(data) + ); + + return true; + } +} + +/** + * 同时执行 + */ +export class ASync> implements ITask { + private running = false; + private count: number = 0; + private list: IHandle[] = []; + private finish: IFinish | Function = null; + + /** + * 每个handle的返回值,通过next或end存储 + */ + public results: T = [] as T; + + /** + * 任务数量 + * @returns + */ + public size(): number { + return this.list.length; + } + + /** + * 添加一个任务 + * @param handle + * @returns + */ + public add(handle: IHandle) { + this.list.push(handle); + this.results.push(undefined); + + if (this.running) { + this.retry(this.list.length - 1); + } + return this; + } + + /** + * 开始执行所有任务 + * @param finish 执行完毕回调 + * @returns + */ + public start(finish?: IFinish | Function) { + if (this.running) { + return this; + } + + this.running = true; + this.count = 0; + this.finish = finish; + + if (this.list.length) { + for (let index = 0; index < this.list.length; index++) { + this.retry(index); + } + } else { + this.end && this.end(this.count); + } + + return this; + } + + /** + * 停止所有任务 + * @returns + */ + public stop(): boolean { + if (!this.running) { + return false; + } + this.running = false; + if (this.finish) { + this.finish(this.results, false); + } + + return true; + } + + /** + * 是否正在执行 + * @returns + */ + public isRunning() { + return this.running; + } + + /** + * @deprecated + * @returns + */ + public isStop() { + return !this.running; + } + + private end(index: number, data?: any): boolean { + if (!this.running) { + return false; + } + + if (index >= 0 && index < this.results.length) { + if (this.results[index] || this.results[index] === null) return false; + this.results[index] = typeof data !== 'undefined' ? data : null; + } + + this.running = false; + if (this.finish) { + this.finish(this.results, true); + } + + return true; + } + + private next(index: number, data?: any): boolean { + if (!this.running) { + return false; + } + + if (index >= 0 && index < this.results.length) { + if (this.results[index] || this.results[index] === null) return false; + this.results[index] = typeof data !== 'undefined' ? data : null; + } + + if (++this.count === this.list.length) { + this.end && this.end(this.count); + } + + return true; + } + + private retry(index: number): boolean { + if (!this.running) { + return false; + } + + const handle = this.list[index]; + handle && handle( + (data?: any) => this.next(index, data), + (timeout = 0) => { + return new Promise(resolve => { + if (timeout > 0) { + setTimeout(() => { + resolve(this.retry(index)); + }, timeout * 1000); + } else { + resolve(this.retry(index)); + } + }); + }, + (data?: any) => this.end(index, data) + ); + + return true; + } +} + +export class Any> implements ITask { + private task = new Sync(); + + /** + * 每个handle的返回值,通过next或end存储 + */ + public get results(): T { + return this.task.results as T; + } + + /** + * 任务数量 + * @returns + */ + public size() { + return this.task.size(); + } + + /** + * 添加一个任务 + * @param handle + * @returns + */ + public add(handles: IHandle | IHandle[]) { + if (handles instanceof Array) { + const async = new ASync(); + handles.forEach(handle => async.add(handle)); + this.task.add(async.start.bind(async)); + } else { + this.task.add(handles); + } + return this; + } + + /** + * 开始执行所有任务 + * @param finish 执行完毕回调 + * @returns + */ + public start(finish?: IFinish | Function) { + this.task.start(finish); + return this; + } + + /** + * 停止所有任务 + * @returns + */ + public stop() { + return this.task.stop(); + } + + /** + * 是否正在执行 + * @returns + */ + public isRunning() { + return this.task.isRunning(); + } + + /** + * @deprecated + * @returns + */ + public isStop() { + return this.task.isStop(); + } +} + +interface IExecuteCallBack { + (retry: (timeout?: number) => void): void +} + +const task = { + /** + * 任务顺序执行 + */ + createSync>(): Sync { + return new Sync(); + }, + + /** + * 任务同时执行 + */ + createASync>(): ASync { + return new ASync(); + }, + + /** + * 根据参数指定执行顺序 + * @example + * createAny() + * .add(1).add(2).add(3).add(4) + * .add([5,6,7]) + * .add(8) + * 执行顺序,1,2,3,4依次执行,然后同时执行5,6,7,最后执行8 + */ + createAny>() { + return new Any(); + }, + + /** + * 执行单个任务 + */ + execute(fun: IExecuteCallBack, retryMax = -1, retryFinish?: Function) { + fun(function retry(timeout = 0) { + if (retryMax === 0) return retryFinish && retryFinish(); + retryMax = retryMax > 0 ? retryMax - 1 : retryMax; + if (timeout > 0) { + setTimeout(() => task.execute(fun, retryMax, retryFinish), timeout * 1000); + } else { + task.execute(fun, retryMax, retryFinish); + } + }); + } +}; + +export default task; \ No newline at end of file diff --git a/extensions/app/assets/lib/task/task.ts.meta b/extensions/app/assets/lib/task/task.ts.meta new file mode 100644 index 0000000..d7ac692 --- /dev/null +++ b/extensions/app/assets/lib/task/task.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "721e6dcc-aab3-48d6-aa4e-e1baf821263b", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager.meta b/extensions/app/assets/manager.meta new file mode 100644 index 0000000..e176b4b --- /dev/null +++ b/extensions/app/assets/manager.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "b50df186-2646-40b3-83c5-5dca8bf01803", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/MainManager.prefab b/extensions/app/assets/manager/MainManager.prefab new file mode 100644 index 0000000..25e4c28 --- /dev/null +++ b/extensions/app/assets/manager/MainManager.prefab @@ -0,0 +1,626 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "MainManager", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "MainManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 6 + }, + { + "__id__": 10 + }, + { + "__id__": 14 + }, + { + "__id__": 18 + } + ], + "_active": true, + "_components": [ + { + "__id__": 26 + }, + { + "__id__": 28 + } + ], + "_prefab": { + "__id__": 30 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "EventManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + } + ], + "_prefab": { + "__id__": 5 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "b4ea6NEN3hCPZiqp3hRVbvU", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "38T7Dsd1BPcZKW0ht+pktn" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "d6NoKoYv9Gk4UlM7XwQPMZ", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "TimerManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "b5636+NNRZFEKq6dPkgK4qf", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 6 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1dkZGh7HlMao6WFTkih0ky" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "48d9+lep1ML4jLQU06pY4T", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "LoaderManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + } + ], + "_prefab": { + "__id__": 13 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "b3bf5M3DHNHcYe1nnNZYr6B", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 12 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8eHWii+rhPFp6edhCSGQYK" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "f2JbolDiVMXbduKISlIjVg", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "SoundManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 15 + } + ], + "_prefab": { + "__id__": 17 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "58002Ha2adOWbt2LDr8rmBT", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 14 + }, + "_enabled": true, + "__prefab": { + "__id__": 16 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8bj+DC16xOWa/0aihp7pcS" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "54fbQjsl1HwJD2+SejsBvm", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "UIManager", + "_objFlags": 512, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 19 + }, + { + "__id__": 21 + }, + { + "__id__": 23 + } + ], + "_prefab": { + "__id__": 25 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "234f6Lx69NNFJ9vC2nHCWRJ", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 18 + }, + "_enabled": true, + "__prefab": { + "__id__": 20 + }, + "loadingPre": { + "__uuid__": "fe542035-b018-493e-bea8-084fe4e01905", + "__expectedType__": "cc.Prefab" + }, + "shadePre": { + "__uuid__": "000cee21-922c-4fcd-bd39-6f80ac2436a4", + "__expectedType__": "cc.Prefab" + }, + "toastPre": { + "__uuid__": "b2a00c44-d199-4031-8fa7-ea681618b9d4", + "__expectedType__": "cc.Prefab" + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "67aJm34PdM/ItCntR8+zcy" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 18 + }, + "_enabled": true, + "__prefab": { + "__id__": 22 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 750, + "height": 1334 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "c3fJug795H8Zpvt/9PivC1" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 18 + }, + "_enabled": true, + "__prefab": { + "__id__": 24 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "152XoOPG1D3KEcrikGio7Z" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "4d13DruoVK/5VWhsBYQS/E", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 27 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 750, + "height": 1334 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "bab8wNsgZHRICm9NXgLsKC" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 29 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "12csQGnuVJRr1L+07HdNSc" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "09f6AV8NhG8amoujtBeGc3", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/extensions/app/assets/manager/MainManager.prefab.meta b/extensions/app/assets/manager/MainManager.prefab.meta new file mode 100644 index 0000000..23bd8ab --- /dev/null +++ b/extensions/app/assets/manager/MainManager.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "5e43bb09-848f-434a-b3a5-a6b6602e00af", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "MainManager" + } +} diff --git a/extensions/app/assets/manager/event.meta b/extensions/app/assets/manager/event.meta new file mode 100644 index 0000000..941786e --- /dev/null +++ b/extensions/app/assets/manager/event.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "4f12d0c8-895c-48a5-8805-79653aadb7e4", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/event/EventManager.ts b/extensions/app/assets/manager/event/EventManager.ts new file mode 100644 index 0000000..6b1c2b7 --- /dev/null +++ b/extensions/app/assets/manager/event/EventManager.ts @@ -0,0 +1,89 @@ +import { EventTarget, _decorator } from 'cc'; +import BaseManager from '../../base/BaseManager'; +const { ccclass } = _decorator; + +class Event { + static destroy(event: Event) { + if (!event) return; + event._event = null; + } + + // 事件管理器 + private _event: EventTarget = new EventTarget(); + + /** + * 事件分发 + */ + public emit(event: string | number, ...data: any[]) { + if (!this._event) { + throw Error('当前event已销毁,无法继续调用'); + } + this._event.emit(event as any, ...data); + } + + /** + * 事件监听 + */ + public on(event: string | number, cb: (...any: any[]) => void, target?: any) { + if (!this._event) { + throw Error('当前event已销毁,无法继续调用'); + } + this._event.on(event as any, cb, target); + } + + /** + * 事件监听 + */ + public once(event: string | number, cb: (...any: any[]) => void, target?: any) { + if (!this._event) { + throw Error('当前event已销毁,无法继续调用'); + } + this._event.once(event as any, cb, target); + } + + /** + * 事件移除监听 + */ + public off(event: string | number, cb?: (...any: any[]) => void, target?: any) { + if (!this._event) { + throw Error('当前event已销毁,无法继续调用'); + } + this._event.off(event as any, cb, target); + } + + /** + * 事件移除监听 + */ + public targetOff(target: any) { + if (!this._event) { + throw Error('当前event已销毁,无法继续调用'); + } + this._event.targetOff(target); + } +} + +@ccclass('EventManager') +export default class EventManager extends BaseManager { + private events: Map = new Map(); + + clear() { + this.events.forEach(event => Event.destroy(event)); + return this.events.clear(); + } + + delete(key: string | number | Symbol) { + Event.destroy(this.events.get(key)); + return this.events.delete(key); + } + + get(key: string | number | Symbol): Event { + if (this.events.has(key)) { + return this.events.get(key); + } + + const event = new Event(); + this.events.set(key, event); + + return event; + } +} diff --git a/extensions/app/assets/manager/event/EventManager.ts.meta b/extensions/app/assets/manager/event/EventManager.ts.meta new file mode 100644 index 0000000..dc2fe29 --- /dev/null +++ b/extensions/app/assets/manager/event/EventManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "b4ea6344-3778-423d-98aa-a7785155bbd4", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/loader.meta b/extensions/app/assets/manager/loader.meta new file mode 100644 index 0000000..ceba3ff --- /dev/null +++ b/extensions/app/assets/manager/loader.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "d8954580-884f-4927-b59a-dfb9553d4ce6", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/loader/LoaderManager.ts b/extensions/app/assets/manager/loader/LoaderManager.ts new file mode 100644 index 0000000..ef95e28 --- /dev/null +++ b/extensions/app/assets/manager/loader/LoaderManager.ts @@ -0,0 +1,869 @@ +import { Asset, AssetManager, Font, ImageAsset, JsonAsset, Label, SceneAsset, Sprite, SpriteFrame, Texture2D, TextureCube, _decorator, assetManager, isValid, path, sp } from 'cc'; +import { MINIGAME } from 'cc/env'; +import BaseManager from '../../base/BaseManager'; +import Core from '../../Core'; +const { ccclass } = _decorator; +const REGEX = /^https?:\/\/.*/; + +class Command { + private static cache: Command[] = []; + + static create(onComplete: (items: unknown) => void, onProgress: (finish: number, total: number, item: AssetManager.RequestItem) => void = null) { + const command = Command.cache.pop() || new Command(); + onProgress && command.onProgress.push(onProgress); + onComplete && command.onComplete.push(onComplete); + return command; + } + + static put(command: Command) { + command.onProgress.length = 0; + command.onComplete.length = 0; + Command.cache.push(command); + } + + onProgress: Array<(finish: number, total: number, item: AssetManager.RequestItem) => void> = []; + onComplete: Array<(items: unknown) => void> = []; + + private constructor() { } +} + +class Loader { + private assetMap = new Map(); + private loadingMap = new Map(); + + /** + * 预加载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public preload(params: { path: string, bundle?: string, version?: string, type?: typeof Asset, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (item: AssetManager.RequestItem[] | null) => void }) { + return Core.inst.manager.loader.preload(params); + } + + /** + * 预加载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public preloadDir(params: { path: string, bundle?: string, version?: string, type?: typeof Asset, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (items: AssetManager.RequestItem[] | null) => void }) { + return Core.inst.manager.loader.preloadDir(params); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundel名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public load(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (item: InstanceType | null) => void }) { + const key = `${params.bundle || 'resources'}-${params.type.name}-${params.path}-${params.version || ''}`; + + if (this.loadingMap.has(key)) { + const command = this.loadingMap.get(key); + params.onProgress && command.onProgress.push(params.onProgress); + params.onComplete && command.onComplete.push(params.onComplete); + return; + } + + // 加载中 + const command = Command.create(params.onComplete, params.onProgress); + this.loadingMap.set(key, command); + + // 有缓存 + if (this.assetMap.has(key)) { + const asset = this.assetMap.get(key); + // 有缓存的情况下不触发onProgress回调 + setTimeout(() => { + // 加载无效 + if (!this.loadingMap.has(key)) return; + this.loadingMap.delete(key); + command.onComplete.forEach(cb => cb(asset)); + Command.put(command); + }, 0); + return; + } + + Core.inst.manager.loader.load({ + ...params, + onProgress: (finish, total, item) => { + if (!this.loadingMap.has(key)) return; + command.onProgress.forEach(cb => cb(finish, total, item)); + }, + onComplete: (asset) => { + // 加载无效 + if (!this.loadingMap.has(key)) { + asset.addRef(); + asset.decRef(); + return; + } + this.loadingMap.delete(key); + if (asset) { + asset.addRef(); + this.assetMap.set(key, asset); + } + command.onComplete.forEach(cb => cb(asset)); + Command.put(command); + } + }); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadAsync(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void }): Promise | null> { + return new Promise((resolve) => { + this.load({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundel名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadDir(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (items: InstanceType[] | null) => void }) { + const key = `${params.bundle || 'resources'}-${params.type.name}-${params.path}-${params.version || ''}:`; + + if (this.loadingMap.has(key)) { + const command = this.loadingMap.get(key); + params.onProgress && command.onProgress.push(params.onProgress); + params.onComplete && command.onComplete.push(params.onComplete); + return; + } + + // 加载中 + const command = Command.create(params.onComplete, params.onProgress); + this.loadingMap.set(key, command); + + const results = [] as InstanceType[]; + this.assetMap.forEach((asset, path) => { + if (path.indexOf(key) === 0) { + results.push(asset as InstanceType); + } + }); + + // 有缓存 + if (results.length) { + // 有缓存的情况下不触发onProgress回调 + setTimeout(() => { + // 加载无效 + if (!this.loadingMap.has(key)) return; + this.loadingMap.delete(key); + command.onComplete.forEach(cb => cb(results)); + Command.put(command); + }, 0); + return; + } + + Core.inst.manager.loader.loadDir({ + ...params, + onProgress: (finish, total, item) => { + if (!this.loadingMap.has(key)) return; + command.onProgress.forEach(cb => cb(finish, total, item)); + }, + onComplete: (assets) => { + // 加载无效 + if (!this.loadingMap.has(key)) { + assets?.forEach((asset) => { + asset.addRef(); + asset.decRef(); + }); + return; + } + this.loadingMap.delete(key); + assets?.forEach((asset) => { + asset.addRef(); + this.assetMap.set(key + asset.uuid, asset); + }); + command.onComplete.forEach(cb => cb(assets)); + Command.put(command); + } + }); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadDirAsync(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void }): Promise[] | null> { + return new Promise((resolve) => { + this.loadDir({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 加载远程资源 + * @example + * loadRemote({url:'', ext:'.png', onComplete:(result){ }}) + */ + public loadRemote({ url, ext, onComplete }: { url: string, ext?: string, onComplete?: (result: Asset | null) => void }) { + if (this.loadingMap.has(url)) { + const command = this.loadingMap.get(url); + onComplete && command.onComplete.push(onComplete); + return; + } + + // 加载中 + const command = Command.create(onComplete); + this.loadingMap.set(url, command); + + // 有缓存 + if (this.assetMap.has(url)) { + const asset = this.assetMap.get(url); + // 有缓存的情况下不触发onProgress回调 + setTimeout(() => { + // 加载无效 + if (!this.loadingMap.has(url)) return; + this.loadingMap.delete(url); + command.onComplete.forEach(cb => cb(asset)); + Command.put(command); + }, 0); + return; + } + + Core.inst.manager.loader.loadRemote({ + url, ext, + onComplete: (asset) => { + // 加载无效 + if (!this.loadingMap.has(url)) { + asset.addRef(); + asset.decRef(); + return; + } + this.loadingMap.delete(url); + if (asset) { + asset.addRef(); + this.assetMap.set(url, asset); + } + command.onComplete.forEach(cb => cb(asset)); + Command.put(command); + } + }); + } + + /** + * 加载远程资源 + * @example + * await loadRemoteAsync({url:'', ext:'.png'}) + */ + public loadRemoteAsync(params: { url: string, ext?: string }): Promise { + return new Promise((resolve) => { + this.loadRemote({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 设置字体资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setFont({target:label, path:'font/num', bundle:'resources', onComplete:(succ)=>{}}) + * setFont({target:label, url:'http://img/a/font',ext:'.ttf', onComplete:(succ)=>{}}) + */ + public setFont(params: { target: Label, url: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setFont(params: { target: Label, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setFont(params: { target: Label, path?: string, bundle?: string, url?: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + if (params.url) { + this.loadRemote({ + url: params.url, + ext: params.ext, + onComplete: (font: Font) => { + if (!font || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.font = font; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } else { + this.load({ + path: params.path, + bundle: params.bundle, + type: Font, + onComplete: (font) => { + if (!font || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.font = font; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + } + + /** + * 设置Spine资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setSpine({target:spine, path:'spine/role', bundle:'resources', onComplete:(succ)=>{}}) + */ + public setSpine(params: { target: sp.Skeleton, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + this.load({ + path: params.path, + bundle: params.bundle, + type: sp.SkeletonData, + onComplete: (skeletonData) => { + if (!skeletonData || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.skeletonData = skeletonData; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + + /** + * 设置图片资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setSprite({target:sprite, path:'img/a/spriteFrame', bundle:'resources', onComplete:(succ)=>{}}) + * setSprite({target:sprite, url:'http://img/a/avatar',ext:'.png', onComplete:(succ)=>{}}) + */ + public setSprite(params: { target: Sprite, url: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setSprite(params: { target: Sprite, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setSprite(params: { target: Sprite, path?: string, bundle?: string, url?: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + if (params.url) { + this.loadRemote({ + url: params.url, + ext: params.ext, + onComplete: (imageAsset: ImageAsset) => { + if (!imageAsset || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + const spriteFrame = SpriteFrame.createWithImage(imageAsset); + params.target.spriteFrame = spriteFrame; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } else { + this.load({ + path: params.path, + bundle: params.bundle, + type: SpriteFrame, + onComplete: (spriteFrame) => { + if (!spriteFrame || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.spriteFrame = spriteFrame; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + } + + /** + * 释放所有资源 + */ + public releaseAll() { + const assetList: Asset[] = []; + this.assetMap.forEach(asset => assetList.push(asset)); + this.assetMap.clear(); + this.loadingMap.clear(); + // 延迟一秒释放资源 + setTimeout(() => { + assetList.forEach(asset => asset.decRef()); + }, 1000); + } +} + +@ccclass('LoaderManager') +export default class LoaderManager extends BaseManager { + /** + * `Loader`的目的是对资源加载进行分组引用计数管理。比如两个`Loader`实例都加载了同一个资源,当某个实例执行releaseAll后,并不会让引擎资源释放资源,只有两个实例都执行了释放资源后,才会让引擎资源释放资源。 + * @example + * // 创建Loader实例 + * const loader = new LoaderManager.Loader(); + * // 加载资源 + * loader.load({path:'img/a/spriteFrame', bundle:'resources', type:SpriteFrame, onComplete:(spriteFrame)=>{}}) + * // 加载远程图片资源 + * loader.loadRemote({url:'http://img/a/avatar',ext:'.png', onComplete:(imageAsset)=>{}}) + * // 释放所有资源 + * loader.releaseAll(); + */ + static Loader = Loader; + + private handle(handle: string, { bundle, version, path, type, onProgress, onComplete }: { bundle?: string, version?: string, path: string, type?: typeof Asset, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (result: unknown | null) => void }) { + if (!handle) { + this.error('handle is empty'); + return onComplete && onComplete(null); + } + if (!path) { + this.error(`${handle} fail. path is empty`); + return onComplete && onComplete(null); + } + if (!bundle) bundle = 'resources'; + + const args: any[] = [path]; + if (type) args.push(type); + if (onProgress) args.push(onProgress); + args.push((err: string, res: any) => { + if (err) { + this.error(`${handle} "${path}" fail`, err); + if (type === SpriteFrame && path.slice(-12) !== '/spriteFrame') { + this.warn(`加载SpriteFrame类型的资源, 路径可能需要以/spriteFrame结尾, 如: 「${path}」 -> 「${path}/spriteFrame」`); + } else if (type === Texture2D && path.slice(-8) !== '/texture') { + this.warn(`加载Texture2D类型的资源, 路径可能需要以/texture结尾, 如: 「${path}」 -> 「${path}/texture」`); + } else if (type === TextureCube && path.slice(-12) !== '/textureCube') { + this.warn(`加载TextureCube类型的资源, 路径可能需要以/textureCube结尾, 如: 「${path}」 -> 「${path}/textureCube」`); + } + onComplete && onComplete(null); + } else { + onComplete && onComplete(res); + } + }); + + this.loadBundle({ + bundle, version, + onComplete(bundle) { + if (!bundle) return onComplete && onComplete(null); + bundle[handle](args[0], args[1], args[2], args[3]); + }, + }); + } + + /** + * 预加载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public preload(params: { path: string, bundle?: string, version?: string, type?: typeof Asset, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (item: AssetManager.RequestItem[] | null) => void }) { + if (SceneAsset === params.type as typeof Asset) { + this.handle('preloadScene', { path: params.path, bundle: params.bundle, version: params.version, onProgress: params.onProgress, onComplete: params.onComplete }); + } else { + this.handle('preload', params); + } + } + + /** + * 预加载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public preloadDir(params: { path: string, bundle?: string, version?: string, type?: typeof Asset, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (items: AssetManager.RequestItem[] | null) => void }) { + this.handle('preloadDir', params); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public load(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (item: InstanceType | null) => void }) { + if (SceneAsset === params.type as typeof Asset) { + this.handle('loadScene', { path: params.path, bundle: params.bundle, version: params.version, onProgress: params.onProgress, onComplete: params.onComplete }); + } else { + this.handle('load', params); + } + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadAsync(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void }): Promise | null> { + return new Promise((resolve) => { + this.load({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadDir(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void, onComplete?: (items: InstanceType[] | null) => void }) { + this.handle('loadDir', params); + } + + /** + * 加载bundle下的资源 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public loadDirAsync(params: { path: string, bundle?: string, version?: string, type?: T, onProgress?: (finish: number, total: number, item: AssetManager.RequestItem) => void }): Promise[] | null> { + return new Promise((resolve) => { + this.loadDir({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 销毁一个bundle中对应path和type的资源 + * @param params.bundle 默认为resources,如果是远程bundle,则使用url末位作为bundle名 + * @param params.path bundle下的相对路径 + * @param params.type 资源类型 + */ + public release({ path, bundle, type }: { path: string, bundle?: string, type?: typeof Asset }) { + if (!bundle) bundle = 'resources'; + assetManager.getBundle(bundle)?.release(path, type); + } + + /** + * 销毁一个bundle中所有的资源 + * @param bundle 默认为resources,如果是远程bundle,则使用url末位作为bundle名 + */ + public releaseAll(bundle?: string) { + if (!bundle) bundle = 'resources'; + const _bundle = assetManager.getBundle(bundle); + if (!_bundle) return; + // 只释放自己内部的资源,依赖的资源只减少引用计数 + _bundle.getDirWithPath('/', Asset).forEach((asset) => { + _bundle.release(asset.path, asset.ctor); + }); + // cocos提供的方法会将依赖的资源也卸载(这个设计很奇怪) + // _bundle?.releaseAll(); + } + + /** + * 销毁一个bundle中未使用的资源 + * @param bundle 默认为resources,如果是远程bundle,则使用url末位作为bundle名 + */ + public releaseUnused(bundle?: string) { + if (!bundle) bundle = 'resources'; + //@ts-ignore + assetManager.getBundle(bundle)?.releaseUnusedAssets(); + } + + /** + * 加载一个bundle + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public loadBundle({ bundle, version, onComplete }: { bundle?: string, version?: string, onComplete?: (bundle: AssetManager.Bundle | null) => any }) { + if (!bundle) bundle = 'resources'; + + if (MINIGAME) { + if (REGEX.test(bundle)) { + this.warn('小游戏环境下只支持加载远程Bundle的资源数据, 不会加载脚本'); + this.reloadBundle({ bundle, version, onComplete }); + return; + } + if (version && assetManager.downloader.bundleVers[bundle] !== version) { + this.warn('小游戏环境下只支持更新Bundle的远程资源数据, 不会更新脚本'); + // 先加载本地bundle运行脚本 + assetManager.loadBundle(bundle, (err: Error, b: AssetManager.Bundle) => { + if (err || !b) return onComplete?.(null); + // 然后再走重载逻辑更新资源 + this.reloadBundle({ bundle, version, onComplete }); + }); + } else { + assetManager.loadBundle(bundle, (err: Error, bundle: AssetManager.Bundle) => { + onComplete && onComplete(err ? null : bundle); + }); + } + return; + } + + if (version) { + assetManager.loadBundle(bundle, { version }, (err: Error, bundle: AssetManager.Bundle) => { + onComplete && onComplete(err ? null : bundle); + }); + } else { + assetManager.loadBundle(bundle, (err: Error, bundle: AssetManager.Bundle) => { + onComplete && onComplete(err ? null : bundle); + }); + } + } + + /** + * 加载一个bundle + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public loadBundleAsync(params: { bundle?: string, version?: string }): Promise { + return new Promise((resolve) => { + this.loadBundle({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 获取一个已经加载的bundle + * @param bundle 默认为resources,如果是远程bundle,则使用url末位作为bundle名 + */ + public getBundle(bundle?: string) { + if (!bundle) bundle = 'resources'; + return assetManager.getBundle(bundle); + } + + /** + * 移除一个已经加载的bundle + * @param bundle 默认为resources,如果是远程bundle,则使用url末位作为bundle名 + */ + public removeBundle(bundle?: string) { + if (!bundle) bundle = 'resources'; + const b = assetManager.getBundle(bundle); + if (b) assetManager.removeBundle(b); + } + + /** + * 重载一个bundle(只重载资源列表) + * - 只有远程bundle支持重载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public reloadBundle({ bundle, version, onComplete }: { bundle?: string, version?: string, onComplete?: (bundle: AssetManager.Bundle | null) => any }) { + if (!bundle) bundle = 'resources'; + + let baseUrl = ''; + let configUrl = ''; + + if (REGEX.test(bundle)) { + baseUrl = bundle; + const suffix = version ? `${version}.` : ''; + configUrl = `${baseUrl}config.${suffix}json`; + } + else { + baseUrl = `${assetManager.downloader.remoteServerAddress}remote/${bundle}/`; + const suffix = version ? `${version}.` : ''; + configUrl = `${baseUrl}config.${suffix}json`; + } + + // 清除可能存在的config缓存 + assetManager.cacheManager?.removeCache(configUrl); + assetManager.loadRemote(configUrl, (err: Error, data: JsonAsset) => { + if (err) { + this.error(`下载Bundle配置失败: ${configUrl}`); + onComplete?.(null); + return; + } + + this.releaseAll(path.basename(bundle)); + this.removeBundle(path.basename(bundle)); + + const ab = new AssetManager.Bundle(); + const config = data.json as any; + config.base = baseUrl; + ab.init(config); + onComplete?.(ab); + }); + } + + /** + * 重载一个bundle(只重载资源列表) + * - 只有远程bundle支持重载 + * @param params.bundle 默认为resources, 可以是项目中的bundle名,也可以是远程bundle的url(url末位作为bundle名),参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#%E5%8A%A0%E8%BD%BD-asset-bundle + * @param params.version 远程bundle的版本,参考https://docs.cocos.com/creator/manual/zh/asset/bundle.html#asset-bundle-%E7%9A%84%E7%89%88%E6%9C%AC + */ + public reloadBundleAsync(params: { bundle?: string, version?: string }): Promise { + return new Promise((resolve) => { + this.reloadBundle({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 加载远程资源 + * @example + * loadRemote({url:'', ext:'.png', onComplete:(result){ }}) + */ + public loadRemote({ url, ext, onComplete }: { url: string, ext?: string, onComplete?: (result: Asset | null) => void }) { + if (ext) { + assetManager.loadRemote(url, { ext }, (error, res) => { + if (error) { + this.error(`loadRemote ${url} fail`); + return onComplete && onComplete(null); + } + onComplete && onComplete(res); + }); + } else { + assetManager.loadRemote(url, (error, res) => { + if (error) { + this.error(`loadRemote ${url} fail`); + return onComplete && onComplete(null); + } + onComplete && onComplete(res); + }); + } + } + + /** + * 加载远程资源 + * @example + * await loadRemoteAsync({url:'', ext:'.png'}) + */ + public loadRemoteAsync(params: { url: string, ext?: string }): Promise { + return new Promise((resolve) => { + this.loadRemote({ + ...params, + onComplete: resolve + }); + }); + } + + /** + * 设置字体资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setFont({target:label, path:'font/num', bundle:'resources', onComplete:(succ)=>{}}) + * setFont({target:label, url:'http://img/a/font',ext:'.ttf', onComplete:(succ)=>{}}) + */ + public setFont(params: { target: Label, url: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setFont(params: { target: Label, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setFont(params: { target: Label, path?: string, bundle?: string, url?: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + if (params.url) { + this.loadRemote({ + url: params.url, + ext: params.ext, + onComplete: (font: Font) => { + if (!font || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.font = font; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } else { + this.load({ + path: params.path, + bundle: params.bundle, + type: Font, + onComplete: (font) => { + if (!font || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.font = font; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + } + + /** + * 设置Spine资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setSpine({target:spine, path:'spine/role', bundle:'resources', onComplete:(succ)=>{}}) + */ + public setSpine(params: { target: sp.Skeleton, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + this.load({ + path: params.path, + bundle: params.bundle, + type: sp.SkeletonData, + onComplete: (skeletonData) => { + if (!skeletonData || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.skeletonData = skeletonData; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + + /** + * 设置图片资源 + * @param params.bundle 默认为resources + * @param params.path bundle下的相对路径 + * + * @example + * setSprite({target:sprite, path:'img/a/spriteFrame', bundle:'resources', onComplete:(succ)=>{}}) + * setSprite({target:sprite, url:'http://img/a/avatar',ext:'.png', onComplete:(succ)=>{}}) + */ + public setSprite(params: { target: Sprite, url: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setSprite(params: { target: Sprite, path: string, bundle?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }): void; + public setSprite(params: { target: Sprite, path?: string, bundle?: string, url?: string, ext?: string, onComplete?: (success: boolean) => any, onSuccess?: () => void, onFail?: () => void }) { + if (params.url) { + this.loadRemote({ + url: params.url, + ext: params.ext, + onComplete: (imageAsset: ImageAsset) => { + if (!imageAsset || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + const spriteFrame = SpriteFrame.createWithImage(imageAsset); + params.target.spriteFrame = spriteFrame; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } else { + this.load({ + path: params.path, + bundle: params.bundle, + type: SpriteFrame, + onComplete: (spriteFrame) => { + if (!spriteFrame || !isValid(params.target)) { + params.onFail && params.onFail(); + params.onComplete && params.onComplete(false); + return; + } + params.target.spriteFrame = spriteFrame; + params.onSuccess && params.onSuccess(); + params.onComplete && params.onComplete(true); + } + }); + } + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/loader/LoaderManager.ts.meta b/extensions/app/assets/manager/loader/LoaderManager.ts.meta new file mode 100644 index 0000000..66dd237 --- /dev/null +++ b/extensions/app/assets/manager/loader/LoaderManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "b3bf5337-0c73-4771-87b5-9e735962be81", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/sound.meta b/extensions/app/assets/manager/sound.meta new file mode 100644 index 0000000..2d175c8 --- /dev/null +++ b/extensions/app/assets/manager/sound.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "a99e9a5e-e037-428c-b8f4-e5ad266db8ee", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/sound/Audio.ts b/extensions/app/assets/manager/sound/Audio.ts new file mode 100644 index 0000000..364d520 --- /dev/null +++ b/extensions/app/assets/manager/sound/Audio.ts @@ -0,0 +1,152 @@ +import { AudioClip, AudioSource, Node } from 'cc'; + +export default class Audio { + private volume = 1; + private volumeScale = 1; + private mute = false; + private endedCallback: Function = null; + private startedCallback: Function = null; + + private _playing = false; + public get playing() { + return this._playing; + } + private set playing(value) { + this._playing = value; + } + + private _paused = false; + public get paused() { + return this._paused; + } + private set paused(value) { + this._paused = value; + } + + private audioSource: AudioSource = null; + constructor() { + const node = new Node('audio'); + this.audioSource = node.addComponent(AudioSource); + node.on(AudioSource.EventType.ENDED, this.onAudioEnded, this); + node.on(AudioSource.EventType.STARTED, this.onAudioStarted, this); + } + + private onAudioEnded() { + if (this.endedCallback) { + const endedCallback = this.endedCallback; + this.endedCallback = null; + endedCallback(); + } + } + + private onAudioStarted() { + if (this.startedCallback) { + const startedCallback = this.startedCallback; + this.startedCallback = null; + startedCallback(); + } + } + + play(clip: AudioClip, onEnded: Function = null, onStarted: Function = null) { + this.audioSource.clip = clip; + this.endedCallback = onEnded; + this.startedCallback = onStarted; + this.audioSource.play(); + this.playing = true; + this.paused = false; + return this; + } + + stop() { + this.playing = false; + this.paused = false; + this.audioSource.stop(); + this.audioSource.node.emit(AudioSource.EventType.ENDED); + return this; + } + + pause() { + if (!this.playing) return this; + + this.paused = true; + this.audioSource.pause(); + return this; + } + + resume() { + if (!this.playing) return this; + if (!this.paused) return this; + + this.paused = false; + this.audioSource.play(); + return this; + } + + setVolume(volume = 1, scale?: number) { + this.volume = volume; + if (typeof scale === 'number') this.volumeScale = scale; + this.audioSource.volume = volume * this.volumeScale * (this.mute ? 0 : 1); + return this; + } + + getVolume() { + return this.volume; + } + + setVolumeScale(scale = 1) { + this.volumeScale = scale; + this.audioSource.volume = this.volume * scale * (this.mute ? 0 : 1); + return this; + } + + getVolumeScale() { + return this.volumeScale; + } + + setLoop(loop: boolean) { + this.audioSource.loop = loop; + return this; + } + + getLoop() { + return this.audioSource.loop; + } + + setMute(mute = true) { + this.mute = mute; + this.setVolume(this.volume); + return this; + } + + getMute() { + return this.mute; + } + + onEnded(endedCallback: Function) { + this.endedCallback = endedCallback; + return this; + } + + clear() { + this.volume = 1; + this.volumeScale = 1; + this.mute = false; + this.paused = false; + this.endedCallback = null; + this.startedCallback = null; + if (this.audioSource) { + this.audioSource.stop(); + this.audioSource.volume = 1; + this.audioSource.clip = null; + this.audioSource.loop = false; + } + return this; + } + + destroy() { + this.clear(); + this.audioSource.destroy(); + this.audioSource.node.destroy(); + this.audioSource = null; + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/sound/Audio.ts.meta b/extensions/app/assets/manager/sound/Audio.ts.meta new file mode 100644 index 0000000..9944147 --- /dev/null +++ b/extensions/app/assets/manager/sound/Audio.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "a40e77a6-cdac-445c-a50c-a8ced2411dbc", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/sound/AudioEngine.ts b/extensions/app/assets/manager/sound/AudioEngine.ts new file mode 100644 index 0000000..38cdb3f --- /dev/null +++ b/extensions/app/assets/manager/sound/AudioEngine.ts @@ -0,0 +1,287 @@ +import { AudioClip } from 'cc'; +import Audio from './Audio'; +import AudioManager from './AudioManager'; + +export default class AudioEngine { + private static _inst: AudioEngine = null; + static get inst() { + if (!this._inst) this._inst = new AudioEngine(); + return this._inst; + } + private constructor() { } + + /**effect的id从1开始,music的id始终为0 */ + private audioID = 1; + private endedCallbackMap: Map = new Map(); + private effectMap: Map = new Map(); + private music: Audio = null; + + private musicMute = false; + private musicVolumeScale = 1; + + private effectMute = false; + private effectVolumeScale = 1; + + //////////////////////////////// + // 音效 // + //////////////////////////////// + playEffect(audioClip: AudioClip, volume = 1, loop = false, onStarted: (audioID: number) => any = null, onEnded: Function = null) { + if (this.audioID > 100000) this.audioID = 1; + + const audioID = this.audioID++; + const audio = AudioManager.inst.getAudio(); + this.effectMap.set(audioID, audio); + if (onEnded) this.endedCallbackMap.set(audioID, onEnded); + + audio.setLoop(loop) + .setMute(this.effectMute) + .setVolume(volume, this.effectVolumeScale) + .play(audioClip, () => { + AudioManager.inst.putAudio(audio); + this.effectMap.delete(audioID); + const callback = this.endedCallbackMap.get(audioID); + if (callback) { + this.endedCallbackMap.delete(audioID); + callback(); + } + }, () => { + onStarted && onStarted(audioID); + }); + + return audioID; + } + + stopEffect(id: number) { + return !!this.effectMap.get(id)?.stop(); + } + + stopAllEffects() { + this.effectMap.forEach((audio) => { + audio.stop(); + }); + } + + pauseEffect(id: number) { + return !!this.effectMap.get(id)?.pause(); + } + + pauseAllEffects() { + this.effectMap.forEach((audio) => { + audio.pause(); + }); + } + + resumeEffect(id: number) { + return !!this.effectMap.get(id)?.resume(); + } + + resumeAllEffects() { + this.effectMap.forEach((audio) => { + audio.resume(); + }); + } + + setEffectMute(id: number, mute: boolean) { + return !!this.effectMap.get(id)?.setMute(mute); + } + + getEffectMute(id: number) { + return !!this.effectMap.get(id)?.getMute(); + } + + setEffectVolume(id: number, volume: number) { + return !!this.effectMap.get(id)?.setVolume(volume); + } + + getEffectVolume(id: number) { + return this.effectMap.get(id)?.getVolume() || 0; + } + + setAllEffectsVolume(volume: number) { + this.effectMap.forEach((audio) => { + audio.setVolume(volume); + }); + } + + setEffectVolumeScale(id: number, volume: number) { + return !!this.effectMap.get(id)?.setVolumeScale(volume); + } + + getEffectVolumeScale(id: number) { + return this.effectMap.get(id)?.getVolumeScale() || 0; + } + + setGlobalEffectsVolumeScale(scale: number) { + this.effectVolumeScale = scale; + this.effectMap.forEach((audio) => { + audio.setVolumeScale(scale); + }); + } + + getGlobalEffectsVolumeScale() { + return this.effectVolumeScale; + } + + setGlobalEffectsMute(mute: boolean) { + this.effectMute = mute; + this.effectMap.forEach((audio) => { + audio.setMute(mute); + }); + } + + getGlobalEffectsMute() { + return this.effectMute; + } + + //////////////////////////////// + // 音乐 // + //////////////////////////////// + playMusic(audioClip: AudioClip, volume = 1, onStarted: Function = null) { + this.stopMusic(); + + this.music = AudioManager.inst.getAudio(); + this.music + .setLoop(true) + .setMute(this.musicMute) + .setVolume(volume, this.musicVolumeScale) + .play(audioClip, null, onStarted); + + return 0; + } + + stopMusic() { + if (!this.music) return false; + this.music.destroy(); + this.music = null; + return true; + } + + pauseMusic() { + if (!this.music) return false; + this.music.pause(); + return true; + } + + resumeMusic() { + if (!this.music) return false; + this.music.resume(); + return true; + } + + setMusicVolume(volume: number) { + if (!this.music) return false; + this.music.setVolume(volume); + return true; + } + + getMusicVolume() { + if (!this.music) return -1; + return this.music.getVolume(); + } + + setMusicVolumeScale(scale: number) { + this.musicVolumeScale = scale; + this.music?.setVolumeScale(scale); + return true; + } + + getMusicVolumeScale() { + return this.musicVolumeScale; + } + + setMusicMute(mute: boolean) { + this.musicMute = mute; + this.music?.setMute(mute); + return true; + } + + getMusicMute() { + return this.musicMute; + } + + //////////////////////////////// + // 通用 // + //////////////////////////////// + setEndedCallback(audioID: number, callback: Function) { + if (audioID === 0) { + return !!this.music?.onEnded(callback); + } else { + if (this.effectMap.has(audioID)) { + this.endedCallbackMap.set(audioID, callback); + return true; + } + return false; + } + } + + stop(audioID: number) { + if (audioID === 0) { + return this.stopMusic(); + } else { + return this.stopEffect(audioID); + } + } + + pause(audioID: number) { + if (audioID === 0) { + return this.pauseMusic(); + } else { + return this.pauseEffect(audioID); + } + } + + resume(audioID: number) { + if (audioID === 0) { + return this.resumeMusic(); + } else { + return this.resumeEffect(audioID); + } + } + + pauseAll() { + this.pauseMusic(); + this.pauseAllEffects(); + } + + resumeAll() { + this.resumeMusic(); + this.resumeAllEffects(); + } + + stopAll() { + this.stopMusic(); + this.stopAllEffects(); + } + + setVolume(audioID: number, volume: number) { + if (audioID === 0) { + return this.setMusicVolume(volume); + } else { + return this.setEffectVolume(audioID, volume); + } + } + + getVolume(audioID: number) { + if (audioID === 0) { + return this.getMusicVolume(); + } else { + return this.getEffectVolume(audioID); + } + } + + setVolumeScale(audioID: number, scale: number) { + if (audioID === 0) { + return this.setMusicVolumeScale(scale); + } else { + return this.setEffectVolumeScale(audioID, scale); + } + } + + getVolumeScale(audioID: number) { + if (audioID === 0) { + return this.getMusicVolumeScale(); + } else { + return this.getEffectVolumeScale(audioID); + } + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/sound/AudioEngine.ts.meta b/extensions/app/assets/manager/sound/AudioEngine.ts.meta new file mode 100644 index 0000000..fe4808a --- /dev/null +++ b/extensions/app/assets/manager/sound/AudioEngine.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "7a638f5c-801f-4e69-88cc-3fc72e1be985", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/sound/AudioManager.ts b/extensions/app/assets/manager/sound/AudioManager.ts new file mode 100644 index 0000000..e20f24b --- /dev/null +++ b/extensions/app/assets/manager/sound/AudioManager.ts @@ -0,0 +1,24 @@ +import Audio from './Audio'; + +export default class AudioManager { + private static _inst: AudioManager = null; + static get inst() { + if (!this._inst) this._inst = new AudioManager(); + return this._inst; + } + private constructor() { } + + private audioArray: Audio[] = []; + + getAudio() { + if (this.audioArray.length) { + return this.audioArray.pop(); + } + return new Audio(); + } + + putAudio(audio: Audio) { + audio.clear(); + this.audioArray.push(audio); + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/sound/AudioManager.ts.meta b/extensions/app/assets/manager/sound/AudioManager.ts.meta new file mode 100644 index 0000000..dd54786 --- /dev/null +++ b/extensions/app/assets/manager/sound/AudioManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "5902cecf-4966-4675-95a9-ab0f0f271857", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/sound/SoundManager.ts b/extensions/app/assets/manager/sound/SoundManager.ts new file mode 100644 index 0000000..bccb1c4 --- /dev/null +++ b/extensions/app/assets/manager/sound/SoundManager.ts @@ -0,0 +1,717 @@ +import { AssetManager, AudioClip, Button, Game, _decorator, game, isValid, sys } from 'cc'; +import { IEffectName, IMusicName } from '../../../../../assets/app-builtin/app-admin/executor'; +import Core from '../../Core'; +import BaseManager from '../../base/BaseManager'; +import AudioEngine from './AudioEngine'; +const { ccclass } = _decorator; + +interface playMusic { name: T, volume?: number, force?: boolean, onPlay?: Function, onError?: Function } +interface playEffect { name: T, volume?: number, loop?: boolean, interval?: number, onPlay?: (audioID: number) => any, onError?: Function, onEnded?: Function } +interface playMusicAsync { name: T, volume?: number, force?: boolean } +interface playEffectAsync { name: T, volume?: number, loop?: boolean, interval?: number, onEnded?: Function } + +interface playMusicWidthBundle { name: string, bundle: string, volume?: number, force?: boolean, onPlay?: Function, onError?: Function } +interface playEffectWidthBundle { name: string, bundle: string, volume?: number, loop?: boolean, interval?: number, onPlay?: (audioID: number) => any, onError?: Function, onEnded?: Function } +interface playMusicWidthBundleAsync { name: string, bundle: string, volume?: number, force?: boolean } +interface playEffectWidthBundleAsync { name: string, bundle: string, volume?: number, loop?: boolean, interval?: number, onEnded?: Function } + +const storage = { + set(key: string, value: any) { + sys.localStorage.setItem(key, JSON.stringify(value)); + }, + get(key: string) { + const data = sys.localStorage.getItem(key); + if (data && typeof data === 'string') { + return JSON.parse(data); + } + return undefined; + } +}; + +/** + * 音乐名字枚举 + */ +const MusicName: { [key in IMusicName]: key } = new Proxy({} as any, { + get: function (target, key) { + if (target[key]) return target[key]; + target[key] = key; + return key; + } +}); + +/** + * 音效名字枚举 + */ +const EffectName: { [key in IEffectName]: key } = new Proxy({} as any, { + get: function (target, key) { + if (target[key]) return target[key]; + target[key] = key; + return key; + } +}); + +const BundleName = 'app-sound'; +@ccclass('SoundManager') +export default class SoundManager extends BaseManager { + /**静态设置 */ + static setting: { + /**预加载 */ + preload?: (IMusicName | IEffectName)[], + + /**默认播放的音乐名 */ + defaultMusicName?: IMusicName | '', + /**默认音乐的音量 */ + defaultMusicVolume?: number, + + /**默认按钮的音效名 */ + defaultEffectName?: IEffectName | '', + /**默认按钮音效的音量 */ + defaultEffectVolume?: number + } = {}; + + /**音乐名字枚举 */ + static MusicName = MusicName; + /**音效名字枚举 */ + static EffectName = EffectName; + + private musicMuteCacheKey = 'SoundManager:MusicMute'; + private effectMuteCacheKey = 'SoundManager:EffectMute'; + private musicVolumeScaleCacheKey = 'SoundManager:MusicVolumeScale'; + private effectVolumeScaleCacheKey = 'SoundManager:EffectVolumeScale'; + + private defaultMusicName = ''; + private defaultMusicVolume = 0.5; + private defaultEffectName = ''; + private defaultEffectVolume = 1; + + private audioCache = {}; + private effectInterval: { [key in string]: number } = {}; + private playingMusic = { uuid: '', id: -1, name: '', volume: 1, playing: false, paused: false }; + + protected init(finish: Function) { + const setting = SoundManager.setting; + + // 默认音乐 + if (setting.defaultMusicName) this.defaultMusicName = setting.defaultMusicName; + if (typeof setting.defaultMusicVolume === 'number') this.defaultMusicVolume = setting.defaultMusicVolume; + + // 默认按钮音效 + if (setting.defaultEffectName) this.defaultEffectName = setting.defaultEffectName; + if (typeof setting.defaultEffectVolume === 'number') this.defaultEffectVolume = setting.defaultEffectVolume; + + if (this.musicMuteCacheKey) { + const musicMute = storage.get(this.musicMuteCacheKey) === true; + AudioEngine.inst.setMusicMute(musicMute); + } else { + this.warn('musicMuteCacheKey不能为空'); + } + if (this.effectMuteCacheKey) { + const effectMute = storage.get(this.effectMuteCacheKey) === true; + AudioEngine.inst.setGlobalEffectsMute(effectMute); + } else { + this.warn('effectMuteCacheKey不能为空'); + } + if (this.musicVolumeScaleCacheKey) { + const musicVolumeScale = storage.get(this.musicVolumeScaleCacheKey); + if (typeof musicVolumeScale === 'number') AudioEngine.inst.setMusicVolumeScale(musicVolumeScale); + } else { + this.warn('musicVolumeScaleCacheKey不能为空'); + } + if (this.effectVolumeScaleCacheKey) { + const effectVolumeScale = storage.get(this.effectVolumeScaleCacheKey); + if (typeof effectVolumeScale === 'number') AudioEngine.inst.setGlobalEffectsVolumeScale(effectVolumeScale); + } else { + this.warn('effectVolumeScaleCacheKey不能为空'); + } + + super.init(finish); + + // 预加载 + setting.preload?.forEach((path: string) => { + Core.inst.manager.loader.preload({ + bundle: BundleName, + type: AudioClip, + path: path + }); + }); + } + + protected onLoad() { + game.on(Game.EVENT_HIDE, function () { + AudioEngine.inst.pauseAll(); + }); + game.on(Game.EVENT_SHOW, function () { + AudioEngine.inst.resumeAll(); + }); + } + + /** + * 预加载声音资源 + * @param name sound路径 + * @param bundle Bundle名,默认为app-sound + */ + public preload(name: string, bundle: string, complete?: (item: AssetManager.RequestItem[] | null) => any): void; + public preload(name: (E | M), complete?: (item: AssetManager.RequestItem[] | null) => any): void; + public preload(name: string, ...args: any[]) { + const bundleName = (args.length >= 1 + && (typeof args[0] === 'string') + ? (args[0] || BundleName) + : BundleName + ) as string; + const complete = (args.length >= 1 + && (args[args.length - 1] instanceof Function) + ? args[args.length - 1] + : null + ) as (item: AssetManager.RequestItem[] | null) => any; + + if (!name) { + this.error('preload', 'fail'); + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(null); + }); + return; + } + + if (name.indexOf('effect') !== 0 && name.indexOf('music') !== 0) { + this.error('preload', 'fail', name); + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(null); + }); + return; + } + + // 远程加载 + Core.inst.manager.loader.preload({ + bundle: bundleName, + path: name, + type: AudioClip, + onComplete: complete + }); + } + + /** + * 加载声音资源 + * @param name sound路径 + * @param bundle Bundle名,默认为app-sound + * @param progress 加载进度回调 + * @param complete 加载完成回调 + */ + public load(name: string, bundle: string): void; + public load(name: string, bundle: string, complete: (result: AudioClip | null) => any): void; + public load(name: string, bundle: string, progress: (finish: number, total: number, item: AssetManager.RequestItem) => void, complete: (result: AudioClip | null) => any): void; + public load(name: (E | M)): void; + public load(name: (E | M), complete: (result: AudioClip | null) => any): void; + public load(name: (E | M), progress: (finish: number, total: number, item: AssetManager.RequestItem) => void, complete: (result: AudioClip | null) => any): void; + public load(name: string, ...args: any[]): void { + const bundleName = (args.length >= 1 + && (typeof args[0] === 'string') + ? (args[0] || BundleName) + : BundleName + ) as string; + const progress = (args.length >= 2 + && (args[args.length - 1] instanceof Function) + && (args[args.length - 2] instanceof Function) + ? args[args.length - 2] + : null + ) as (finish: number, total: number, item: AssetManager.RequestItem) => void; + const complete = (args.length >= 1 + && (args[args.length - 1] instanceof Function) + ? args[args.length - 1] + : null + ) as (result: AudioClip | null) => any; + + if (!name) { + this.error('load', 'fail'); + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(null); + }); + return; + } + + const soundName = `${bundleName}://${name}`; + + // 判断有无缓存 + const audio = this.audioCache[soundName]; + if (audio) { + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(audio); + }); + return; + } + + // 远程加载 + Core.inst.manager.loader.load({ + path: name, + bundle: bundleName, + type: AudioClip, + onProgress: progress, + onComplete: (audioClip) => { + if (!isValid(this)) return; + if (audioClip) { + this.audioCache[soundName] = audioClip; + complete && complete(audioClip); + } else { + complete && complete(null); + } + } + }); + } + + /** + * 释放声音资源 + * @param name 声音路径 + * @param bundle Bundle名,默认为app-sound + */ + public release(name: string, bundle: string): void; + public release(name: E | M): void; + public release(name: string, bundle?: string) { + const bundleName = bundle || BundleName; + const soundName = `${bundleName}://${name}`; + + delete this.audioCache[soundName]; + Core.inst.manager.loader.release({ bundle: bundleName, path: name, type: AudioClip }); + } + + /** + * 播放默认音乐 + */ + public playDefaultMusic(onPlay?: Function) { + if (this.defaultMusicName) { + this.playMusic({ name: this.defaultMusicName, volume: this.defaultMusicVolume, onPlay }); + } else { + this.warn('defaultMusicName 不存在'); + } + } + + /** + * 播放默认音效 + */ + public playDefaultEffect(onPlay?: (audioID: number) => void) { + if (this.defaultEffectName) { + this.playEffect({ name: this.defaultEffectName, volume: this.defaultEffectVolume, onPlay }); + } else { + this.warn('defaultEffectName 不存在'); + } + } + + /** + * 设置按钮点击播放的音效,优先级高于默认音效 + * @param name 音效(如果为空,则使用默认音效) + * @param opts.volume 音量 + * @param opts.interval 多少秒内不会重复播放 + */ + public setButtonEffect(target: Button, name?: E, opts?: { + volume: number, + interval: number + }) { + if (name) { + const { volume = 1, interval = 0 } = opts || {}; + //@ts-ignore + target.node['useDefaultEffect'] = false; + target.node.targetOff(this); + target.node.on(Button.EventType.CLICK, function (this: SoundManager) { + this.playEffect({ name, volume, interval }); + }, this); + } else { + //@ts-ignore + target.node['useDefaultEffect'] = true; + target.node.targetOff(this); + } + } + + /** + * 播放音效 + * @param name 音效 + * @param bundle Bundle名,默认为app-sound + * @param loop 循环播放 + * @param volume 音量 + * @param interval 多少秒内不会重复播放 + */ + public playEffect({ name, volume, loop, interval, onEnded, onPlay, onError }: playEffect): void; + public playEffect({ name, bundle, volume, loop, interval, onEnded, onPlay, onError }: playEffectWidthBundle): void; + public playEffect({ name, bundle, volume = 1, loop = false, interval = 0, onEnded, onPlay, onError }) { + if (!name) { + onError && onError(); + return; + } + + const bundleName = bundle || BundleName; + const soundName = `${bundleName}://${name}`; + + // 静音不允许播放 + if (this.isEffectMute) { + onError && onError(); + return; + } + // 正在播放中,不允许重复播放 + if (this.effectInterval[soundName] && Date.now() < this.effectInterval[soundName]) { + onError && onError(); + return; + } + + // 加载音乐 + this.load(name, bundleName, (audioClip) => { + if (!isValid(this)) { + onError && onError(); + return; + } + // 静音不允许播放 + if (this.isEffectMute) { + onError && onError(); + return; + } + // 正在播放中,不允许重复播放 + if (this.effectInterval[soundName] && Date.now() < this.effectInterval[soundName]) { + onError && onError(); + return; + } + if (!audioClip) { + this.error(`playEffect ${name} 不存在或加载失败`); + onError && onError(); + return; + } + + if (interval > 0) { + this.effectInterval[soundName] = Date.now() + interval * 1000; + } + + AudioEngine.inst.playEffect(audioClip, volume, loop, onPlay, onEnded); + }); + } + + /** + * 播放音效 + * @param name 音效 + * @param bundle Bundle名,默认为app-sound + * @param loop 循环播放 + * @param volume 音量 + * @param interval 多少秒内不会重复播放 + * @returns 如果Promise返回值是null(非真),则播放失败 + */ + public async playEffectAsync(params: playEffectAsync): Promise; + public async playEffectAsync(params: playEffectWidthBundleAsync): Promise; + public async playEffectAsync(params: any): Promise { + return new Promise((resolve) => { + this.playEffect({ + ...params, + onPlay: (audioID) => { + resolve(audioID); + }, + onError: () => { + resolve(null); + } + }); + }); + } + + /** + * 暂停音效 + * @param id + * @returns + */ + public pauseEffect(id: number) { + return AudioEngine.inst.pauseEffect(id); + } + + /** + * 暂停所有音效 + * @returns + */ + public pauseAllEffects() { + return AudioEngine.inst.pauseAllEffects(); + } + + /** + * 恢复音效 + * @param id + * @returns + */ + public resumeEffect(id: number) { + return AudioEngine.inst.resumeEffect(id); + } + + /** + * 恢复所有音效 + * @returns + */ + public resumeAllEffects() { + return AudioEngine.inst.resumeAllEffects(); + } + + /** + * 停止音效 + * @param id + * @returns + */ + public stopEffect(id: number) { + return AudioEngine.inst.stopEffect(id); + } + + /** + * 停止所有音效 + * @returns + */ + public stopAllEffects() { + return AudioEngine.inst.stopAllEffects(); + } + + /** + * 播放音乐 + * @param volume 音量 + * @param bundle Bundle名,默认为app-sound + * @param force 是否强制重新播放 + */ + public playMusic(params: playMusic): void; + public playMusic(params: playMusicWidthBundle): void; + public playMusic({ name, bundle, volume = 1, force = false, onPlay, onError }): void { + if (!name) { + onError && onError(); + return; + } + + const bundleName = bundle || BundleName; + const soundName = `${bundleName}://${name}`; + + // 该音乐正在播放中 + if (!force && this.playingMusic.id !== -1 && this.playingMusic.name === soundName) { + AudioEngine.inst.setMusicVolume(volume); + onPlay && onPlay(); + return; + } + + // 先停止当前音乐 + this.stopMusic(); + + // 播放操作uuid + const uuid = this.createUUID(); + this.playingMusic.uuid = uuid; + // 记录要播放音乐的名字 + this.playingMusic.name = soundName; + // 记录要播放音乐的音量 + this.playingMusic.volume = volume; + // 记录音乐状态 + this.playingMusic.playing = true; + this.playingMusic.paused = false; + + // 静音 + if (this.isMusicMute) { + onPlay && onPlay(); + return; + } + + // 加载音乐 + this.load(name, bundleName, (audioClip) => { + if (!isValid(this)) { + onError && onError(); + return; + } + // 不合法 + if (this.playingMusic.id !== -1) { + onError && onError(); + return; + } + if (this.playingMusic.name !== soundName) { + onError && onError(); + return; + } + if (this.playingMusic.uuid !== this.playingMusic.uuid) { + onError && onError(); + return; + } + // 不存在 + if (!audioClip) { + this.error(`playMusic ${name} 不存在或加载失败`); + onError && onError(); + return; + } + // 静音 + if (this.isMusicMute) { + onPlay && onPlay(); + return; + } + + this.playingMusic.id = AudioEngine.inst.playMusic(audioClip, volume, onPlay); + }); + } + + /** + * 播放音乐 + * @param volume 音量 + * @param bundle Bundle名,默认为app-sound + * @param force 是否强制重新播放 + * @returns 如果Promise返回值是false,则播放失败 + */ + public playMusicAsync(params: playMusicAsync): Promise; + public playMusicAsync(params: playMusicWidthBundleAsync): Promise; + public playMusicAsync(params: any): Promise { + return new Promise((resolve) => { + this.playMusic({ + ...params, + onPlay: () => { + resolve(true); + }, + onError: () => { + resolve(false); + } + }); + }); + } + + /** + * 重新播放音乐 + */ + public replayMusic(onPlay?: Function) { + if (!this.playingMusic.playing) return; + if (!this.playingMusic.name) return; + if (this.playingMusic.name.indexOf('://') > 0) { + const [bundle, name] = this.playingMusic.name.split('://'); + this.playMusic({ + name, + bundle, + volume: this.playingMusic.volume, + force: true, + onPlay + }); + } else { + this.playMusic({ + name: this.playingMusic.name as any, + volume: this.playingMusic.volume, + force: true, + onPlay + }); + } + } + + /** + * 暂停音乐 + */ + public pauseMusic() { + if (!this.playingMusic.playing) return false; + this.playingMusic.paused = true; + return AudioEngine.inst.pauseMusic(); + } + + /** + * 恢复音乐 + */ + public resumeMusic() { + if (!this.playingMusic.playing) return false; + this.playingMusic.paused = false; + return AudioEngine.inst.resumeMusic(); + } + + /** + * 停止音乐 + */ + public stopMusic() { + this.playingMusic.playing = false; + this.playingMusic.paused = false; + this.playingMusic.volume = 1; + this.playingMusic.name = ''; + this.playingMusic.uuid = ''; + this.playingMusic.id = -1; + return AudioEngine.inst.stopMusic(); + } + + /** + * 设置音乐静音 + * @param mute 是否静音 + * @param isCache 静音状态是否写入缓存(通过localstorage) + */ + public setMusicMute(mute: boolean, isCache = false) { + isCache && storage.set(this.musicMuteCacheKey, mute); + AudioEngine.inst.setMusicMute(mute); + if (!mute && this.playingMusic.name) { + if (this.playingMusic.name.indexOf('://') > 0) { + const [bundle, name] = this.playingMusic.name.split('://'); + this.playMusic({ + name, + bundle, + volume: this.playingMusic.volume, + + }); + } else { + this.playMusic({ + name: this.playingMusic.name as any, + volume: this.playingMusic.volume + }); + } + } + } + + /** + * 音乐是否正在播放 + */ + get isMusicPlaying() { + return this.playingMusic.playing; + } + + /** + * 音乐是否暂停 + */ + get isMusicPaused() { + return this.playingMusic.paused; + } + + /** + * 音乐是否静音 + */ + public get isMusicMute() { + return AudioEngine.inst.getMusicMute(); + } + + /** + * 设置音效静音 + * @param mute 是否静音 + * @param isCache 静音状态是否写入缓存(通过localstorage) + */ + public setEffectMute(mute: boolean, isCache = false) { + AudioEngine.inst.setGlobalEffectsMute(mute); + isCache && storage.set(this.effectMuteCacheKey, mute); + } + + /** + * 音效是否静音 + */ + public get isEffectMute() { + return AudioEngine.inst.getGlobalEffectsMute(); + } + + /** + * 设置音乐音量倍率 + * @param scale + * @param isCache 音量倍率是否写入缓存(通过localstorage) + */ + public setMusicVolumeScale(scale: number, isCache = false) { + AudioEngine.inst.setMusicVolumeScale(scale); + isCache && storage.set(this.musicVolumeScaleCacheKey, scale); + } + + /** + * 音乐音量倍率 + */ + public get musicVolumeScale() { + return AudioEngine.inst.getMusicVolumeScale(); + } + + /** + * 设置音效音量倍率 + * @param scale + * @param isCache 音量倍率是否写入缓存(通过localstorage) + */ + public setEffectVolumeScale(scale: number, isCache = false) { + AudioEngine.inst.setGlobalEffectsVolumeScale(scale); + isCache && storage.set(this.effectVolumeScaleCacheKey, scale); + } + + /** + * 音效音量倍率 + */ + public get effectVolumeScale() { + return AudioEngine.inst.getGlobalEffectsVolumeScale(); + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/sound/SoundManager.ts.meta b/extensions/app/assets/manager/sound/SoundManager.ts.meta new file mode 100644 index 0000000..72b4a43 --- /dev/null +++ b/extensions/app/assets/manager/sound/SoundManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "580021da-d9a7-4e59-bb76-2c3afcae6053", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/timer.meta b/extensions/app/assets/manager/timer.meta new file mode 100644 index 0000000..d63ed8b --- /dev/null +++ b/extensions/app/assets/manager/timer.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "ea45b442-c58f-49d1-9b11-edc7bc719a73", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/timer/TimerManager.ts b/extensions/app/assets/manager/timer/TimerManager.ts new file mode 100644 index 0000000..435fd89 --- /dev/null +++ b/extensions/app/assets/manager/timer/TimerManager.ts @@ -0,0 +1,276 @@ +import { _decorator } from 'cc'; +import BaseManager from '../../base/BaseManager'; +const { ccclass } = _decorator; + +type ICallback = (...args: any[]) => any; + +class DailyTimer { + // 获取当前时间相对于当日零点的毫秒数 + private static getDayTimeMs(date: Date): number { + return ( + date.getHours() * 3600 + + date.getMinutes() * 60 + + date.getSeconds() + ) * 1000 + date.getMilliseconds(); + } + + // 静态方法解析时间为毫秒数 + private static parseTimeToMs(h: number, m: number, s: number): number { + return ((h * 3600 + m * 60 + s) * 1000) % 86400000; + } + + private readonly startMs: number; // 起始时间毫秒数(相对于当日零点) + private readonly endMs: number; // 结束时间毫秒数 + + // 用于检查当前时间是否可触发回调 + private checkDay = 0; + + constructor( + time: string, + public readonly callback: ICallback, + public readonly target?: unknown, + public readonly once: boolean = false + ) { + // 使用解构赋值提高可读性 + const [startSegment, endSegment = startSegment] = time.split('-'); + + // 开始时间 + const [startH = 0, startM = 0, startS = 0] = startSegment.split(':').map( + part => Math.max(0, parseInt(part, 10) || 0) + ); + this.startMs = DailyTimer.parseTimeToMs(startH, startM, startS); + + // 结束时间 + const [endH = 0, endM = 0, endS = 0] = endSegment.split(':').map( + part => Math.max(0, parseInt(part, 10) || 0) + ); + this.endMs = DailyTimer.parseTimeToMs(endH, endM, endS); + // 结束时间与开始时间不能相同 + if (this.endMs === this.startMs) { + if (startM === 0 && startS === 0) { + this.endMs = DailyTimer.parseTimeToMs(startH + 1, startM, startS); + } else if (startS === 0) { + this.endMs = DailyTimer.parseTimeToMs(startH, startM + 1, startS); + } else { + this.endMs = DailyTimer.parseTimeToMs(startH, startM, startS + 1); + } + } + } + + // 获取当前时间是否在时间范围内 + private isInRange(now: Date): boolean { + const currentMs = DailyTimer.getDayTimeMs(now); + + // 处理跨天时间段(如 23:00-01:00) + return this.startMs <= this.endMs + ? currentMs >= this.startMs && currentMs < this.endMs + : currentMs >= this.startMs || currentMs < this.endMs; + } + + update(now: Date): boolean { + const dateDay = now.getDay(); + + if (this.checkDay === dateDay) return false; + if (!this.isInRange(now)) return false; + + this.checkDay = dateDay; + this.callback.call(this.target); + + return this.once; + } +} + +class IntervalTimer { + private elapsed: number = 0; + + constructor( + public readonly interval: number, + public readonly callback: ICallback, + public readonly target?: unknown, + public readonly once: boolean = false + ) { } + + update(dt: number): boolean { + this.elapsed += dt; + let completed = false; + + // 处理可能多次触发的情况(当dt > interval时) + while (this.elapsed >= this.interval) { + this.callback.call(this.target); + this.elapsed -= this.interval; + + if (this.once) { + completed = true; + break; + } + } + + return completed; + } +} + +class Timer { + static update(timer: Timer, dt: number) { + return timer.update(dt); + } + + private intervalTimer: IntervalTimer[] = []; + + /** + * 注册定时器 + * @param interval + * @param callback + * @param target + * @param once + */ + register( + interval: number, + callback: ICallback, + target?: unknown, + once?: boolean + ): void { + const timer = new IntervalTimer(interval, callback, target, once || false); + this.intervalTimer.push(timer); + } + + /** + * 取消定时器 + * @param callback + * @param target + */ + unregister(callback: ICallback, target?: unknown): void { + if (typeof target === 'undefined') { + this.intervalTimer = this.intervalTimer.filter( + timer => timer.callback !== callback + ); + } else { + this.intervalTimer = this.intervalTimer.filter( + timer => !(timer.callback === callback && timer.target === target) + ); + } + } + + /** + * 取消所有定时器 + */ + unregisterAll() { + this.intervalTimer = []; + } + + private dailyTimers: DailyTimer[] = []; + + /** + * 注册每日触发器 + * @param time 24小时制,精确到秒 + * + * @example + * registerDailyTrigger('16', ...) 等同于 registerDailyTrigger('16-17', ...) + * registerDailyTrigger('8-9:00', ...) 等同于 registerDailyTrigger('8', ...) + * registerDailyTrigger('8:00:01-24', ...) + */ + registerDailyTrigger( + time: string, + callback: ICallback, + target?: unknown, + once?: boolean + ) { + const timer = new DailyTimer(time, callback, target, once || false); + this.dailyTimers.push(timer); + } + + /** + * 取消每日触发器 + */ + unregisterDailyTrigger(callback: ICallback, target?: unknown) { + if (typeof target === 'undefined') { + this.dailyTimers = this.dailyTimers.filter( + timer => timer.callback !== callback + ); + } else { + this.dailyTimers = this.dailyTimers.filter( + timer => !(timer.callback === callback && timer.target === target) + ); + } + } + + /** + * 取消所有每日触发器 + */ + unregisterAllDailyTrigger() { + this.dailyTimers = []; + } + + /** + * 清除所有定时器和触发器 + */ + clear() { + this.intervalTimer = []; + this.dailyTimers = []; + } + + protected update(dt: number): void { + for (let index = 0; index < this.intervalTimer.length; index++) { + const timer = this.intervalTimer[index]; + if (timer.update(dt)) { + this.intervalTimer.splice(index, 1); + index--; + } + } + + const date = new Date(); + for (let index = 0; index < this.dailyTimers.length; index++) { + const timer = this.dailyTimers[index]; + if (timer.update(date)) { + this.dailyTimers.splice(index, 1); + index--; + } + } + } +} + +@ccclass('TimerManager') +export default class TimerManager extends BaseManager { + private timers: Map = new Map(); + + /** + * 清除所有定时器 + */ + clear() { + this.timers.forEach((timer) => { + timer.clear(); + }); + this.timers.clear(); + } + + /** + * 删除定时器 + * @param key 定时器key + */ + delete(key: string | number | Symbol) { + const timer = this.timers.get(key); + if (!timer) return; + + this.timers.delete(key); + timer.clear(); + } + + /** + * 获取定时器 + * @param key 定时器key + */ + get(key: string | number | Symbol): Timer { + if (this.timers.has(key)) { + return this.timers.get(key); + } + + const timer = new Timer(); + this.timers.set(key, timer); + return timer; + } + + protected update(dt: number): void { + this.timers.forEach((timer) => { + Timer.update(timer, dt); + }); + } +} diff --git a/extensions/app/assets/manager/timer/TimerManager.ts.meta b/extensions/app/assets/manager/timer/TimerManager.ts.meta new file mode 100644 index 0000000..ce5bce1 --- /dev/null +++ b/extensions/app/assets/manager/timer/TimerManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "b5636f8d-3516-4510-aaba-74f9202b8a9f", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui.meta b/extensions/app/assets/manager/ui.meta new file mode 100644 index 0000000..45d4dc9 --- /dev/null +++ b/extensions/app/assets/manager/ui.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "714739c4-f4c0-4313-bc98-2d350df6b208", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/ui/UIManager.ts b/extensions/app/assets/manager/ui/UIManager.ts new file mode 100644 index 0000000..501f619 --- /dev/null +++ b/extensions/app/assets/manager/ui/UIManager.ts @@ -0,0 +1,1617 @@ +import { Asset, AssetManager, Camera, Canvas, Component, Event, Layers, Node, Prefab, RenderTexture, ResolutionPolicy, Scene, SceneAsset, Settings, UITransform, Widget, _decorator, director, instantiate, isValid, js, screen, settings, size, view } from 'cc'; +import { DEV } from 'cc/env'; +import { IMiniViewName, IViewName } from '../../../../../assets/app-builtin/app-admin/executor'; +import Core from '../../Core'; +import BaseManager from '../../base/BaseManager'; +import BaseView, { IHideParamOnHide, IShade, IShowParamAttr, IShowParamOnHide, IShowParamOnShow, IViewType, ViewType } from '../../base/BaseView'; +import UIMgrLoading from './comp/UIMgrLoading'; +import UIMgrShade from './comp/UIMgrShade'; +import UIMgrToast from './comp/UIMgrToast'; +import UIMgrZOrder from './comp/UIMgrZOrder'; + +const { ccclass, property } = _decorator; + +interface IShowParams { + /**UI名 */ + name: T, + /** + * 数据 + * - 被onShow接收 + */ + data?: IShow, + /** + * 是否将UI显示在最上 + * - 默认true + */ + top?: boolean, + /** + * 队列模式,一个UI关闭后,是否展示下一个UI + * - join: 排队 + * - jump: 插队(到首位) + */ + queue?: 'join' | 'jump', + /**静默 默认false(不显示加载loading,也不屏蔽触摸) */ + silent?: boolean, + /**UI触发onShow后 */ + onShow?: IShowParamOnShow, + /**UI触发onHide后 */ + onHide?: IShowParamOnHide, + /**当code的值为ErrorCode.LogicError时,如果返回true,则自动重试 */ + onError?: (result: string, code: ErrorCode) => true | void, + /** + * @private + * @deprecated + */ + attr?: IShowParamAttr, +} + +interface IShowAsyncParams { + /**UI名 */ + name: T, + /** + * 数据 + * - 被onShow接收 + */ + data?: IShow, + /** + * 是否将UI显示在最上 + * - 默认true + */ + top?: boolean, + /** + * 队列模式,一个UI关闭后,是否展示下一个UI + * - join: 排队 + * - jump: 插队(到首位) + */ + queue?: 'join' | 'jump', + /**静默 默认false(不显示加载loading,也不屏蔽触摸) */ + silent?: boolean, + /**UI触发onShow后 */ + onShow?: IShowParamOnShow, + /**当code的值为ErrorCode.LogicError时,如果返回true,则自动重试 */ + onError?: (result: string, code: ErrorCode) => true | void, + /** + * @private + * @deprecated + */ + attr?: IShowParamAttr, +} + +interface IHideParams { + name: T, + data?: IHide, + onHide?: IHideParamOnHide +} + +const UIScene = 'UIScene'; +const UserInterfacePath = 'UserInterface'; +const ViewTypes = [ViewType.Page, ViewType.Paper, ViewType.Pop, ViewType.Top]; + +const BlockEvents = [ + Node.EventType.TOUCH_START, Node.EventType.TOUCH_MOVE, Node.EventType.TOUCH_END, Node.EventType.TOUCH_CANCEL, + Node.EventType.MOUSE_DOWN, Node.EventType.MOUSE_MOVE, Node.EventType.MOUSE_UP, + Node.EventType.MOUSE_ENTER, Node.EventType.MOUSE_LEAVE, Node.EventType.MOUSE_WHEEL +]; + +/** + * 错误码 + */ +enum ErrorCode { + /**加载失败 */ + LoadError, + /**beforeShow返回错误 */ + LogicError, + /**UI无效(UI的isViewValid返回false) */ + InvalidError, +} + +/** + * 界面名字枚举 + */ +const ViewName: { [key in IViewName]: key } = new Proxy({} as any, { + get: function (target, key) { + if (target[key]) return target[key]; + target[key] = key; + return key; + } +}); + +/** + * 子界面名字枚举 + */ +const MiniViewName: { [key in IMiniViewName]: key } = new Proxy({} as any, { + get: function (target, key) { + if (target[key]) return target[key]; + target[key] = key; + return key; + } +}); + +/** + * 将驼峰命名转成串式命名 + * @param str 驼峰字符串 + * @returns + */ +function stringCaseNegate(str: string) { + return str.replace(/[A-Z]/g, (searchStr, startIndex) => { + if (startIndex === 0) { + return searchStr.toLowerCase(); + } else { + return '-' + searchStr.toLowerCase(); + } + }); +} + +@ccclass('UIManager') +export default class UIManager extends BaseManager { + /**静态设置 */ + static setting: { + /**预加载列表,会在UI初始化阶段进行 */ + preload?: (IViewName | IMiniViewName | Array)[], + /**默认UI,框架初始化完毕后会自动加载 */ + defaultUI?: IViewName, + /**给默认UI传递的数据 */ + defaultData?: any, + /**弹窗背景遮罩的参数 */ + shade?: IShade, + /** + * 是否自动适配分辨率策略 + * - 开启后会弃用当前的适配策略,并根据实际设备分辨率与设计分辨率的比值,计算出新的适配策略(宽适配或高适配),保证游戏区域不会被裁减只会扩边 + * - 当实际设备分辨率「高/宽」>= 设计分辨率「高/宽」时,为宽适配 + * - 当实际设备分辨率「高/宽」< 设计分辨率「高/宽」时,为高适配 + */ + autoFit?: boolean, + } = {}; + + /**错误码 */ + static ErrorCode = ErrorCode; + + /**界面名字枚举 */ + static ViewName = ViewName; + + /**子界面名字枚举 */ + static MiniViewName = MiniViewName; + + @property({ + type: Prefab, + tooltip: '位置: app://manager/ui/prefab/UIMgrLoading' + }) + private loadingPre: Prefab = null; + + @property({ + type: Prefab, + tooltip: '位置: app://manager/ui/prefab/UIMgrShade' + }) + private shadePre: Prefab = null; + + @property({ + type: Prefab, + tooltip: '位置: app://manager/ui/prefab/UIMgrToast' + }) + private toastPre: Prefab = null; + + // UI根节点 + private UserInterface: Node = null; + + // 加载和遮罩节点 + private loading: Node = null; + private shade: Node = null; + private toast: Node = null; + + private defaultUI: UIName = null; + private defaultData: string = ''; + + private currScene: string = ''; + private currPage: BaseView = null; + private currFocus: BaseView = null; + + // 预制体缓存 + private prefabCache: { [name in string]: Prefab } = {}; + private sceneCache: { [name in string]: SceneAsset } = {}; + + // 全局触摸有效 + private touchEnabled: boolean = true; + + // 记录触摸屏蔽 + private touchMaskMap = new Map(); + // 记录展示加载 + private showLoadingMap = new Map(); + + // 记录正在加载中的有效的ui + private uiLoadingMap: Map = new Map(); + // 记录正在展示中的有效的ui + private uiShowingMap: Map = new Map(); + + private showQueue: IShowParams[] = []; + + /**UI根节点 */ + public get root() { + return this.node.parent.parent; + } + + /**相机 */ + public get camera() { + return this.canvas.cameraComponent; + } + + /**画布*/ + public get canvas() { + return this.root.getComponent(Canvas); + } + + protected init(finish: Function) { + const setting = UIManager.setting; + + this.defaultUI = setting.defaultUI as UIName; + this.defaultData = setting.defaultData; + + super.init(finish); + + // 预加载,符合AnyTask规则 + if (setting.preload?.length) { + const task = Core.inst.lib.task.createAny(); + setting.preload.forEach((preload) => { + if (preload instanceof Array) { + task.add(preload.map(name => { + return next => this.preload(name as any, next); + })); + } else { + task.add(next => this.preload(preload as any, next)); + } + }); + task.start(); + } + } + + protected onLoad() { + this.UserInterface = this.root.getChildByName(UserInterfacePath); + + this.root.getComponentsInChildren(Camera).forEach(camera => { + // 避免camera.priority<0的情况,否则会造成渲染异常 + if (camera.priority < 0) camera.priority = 0; + // 避免camera.far<=camera.near的情况,否则会造成渲染异常 + if (camera.far <= camera.near) camera.far = camera.near + 1; + }); + director.addPersistRootNode(this.root); + + this.createTypeRoot(); + + this.shade = instantiate(this.shadePre); + this.shade.parent = this.UserInterface; + this.shade.active = false; + this.shade.getComponent(Widget).target = this.root; + + this.loading = instantiate(this.loadingPre); + this.loading.parent = this.node; + this.loading.active = false; + + // toast是后面加的,需要做容错 + if (this.toastPre) { + this.toast = instantiate(this.toastPre); + this.toast.parent = this.node; + } + + // 自动适配分辨率策略 + if (UIManager.setting.autoFit) { + const designResolution = settings.querySettings(Settings.Category.SCREEN, 'designResolution') as { width: number, height: number, policy: number }; + const windowSize = size(screen.windowSize); + let resolutionPolicy = designResolution.policy; + const autoFitResolutionPolicy = function () { + if (windowSize.width / windowSize.height > designResolution.width / designResolution.height) { + if (resolutionPolicy === ResolutionPolicy.FIXED_HEIGHT) return; + view.setResolutionPolicy(ResolutionPolicy.FIXED_HEIGHT); + resolutionPolicy = ResolutionPolicy.FIXED_HEIGHT; + } else { + if (resolutionPolicy === ResolutionPolicy.FIXED_WIDTH) return; + view.setResolutionPolicy(ResolutionPolicy.FIXED_WIDTH); + resolutionPolicy = ResolutionPolicy.FIXED_WIDTH; + } + }; + autoFitResolutionPolicy(); + this.schedule(() => { + if (windowSize.equals(screen.windowSize)) return; + windowSize.set(screen.windowSize); + autoFitResolutionPolicy(); + }, 0.5); + } + } + + private createTypeRoot() { + ViewTypes.forEach((type) => { + const d2 = new Node(type); + d2.layer = Layers.Enum.UI_2D; + d2.addComponent(UIMgrZOrder); + d2.parent = this.UserInterface; + d2.addComponent(UITransform); + const widget = d2.addComponent(Widget); + widget.isAlignBottom = true; + widget.isAlignLeft = true; + widget.isAlignRight = true; + widget.isAlignTop = true; + widget.top = 0; + widget.left = 0; + widget.right = 0; + widget.bottom = 0; + widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE; + + if (DEV) { + d2.on(Node.EventType.CHILD_ADDED, (child: Node) => { + if (!child) return; + if (child === this.shade) return; + if (this.getBaseView(child)) return; + this.warn(`${UserInterfacePath}/${type}下非必要请不要添加非UI节点:`, child?.name); + }, this); + } + }); + } + + private addTouchMaskListener() { + if (!this.touchEnabled) return; + if (this.touchMaskMap.size > 0) return; + + for (let i = 0; i < BlockEvents.length; i++) { + this.root.on(BlockEvents[i], this.stopPropagation, this, true); + } + } + + private removeTouchMaskListener() { + if (!this.touchEnabled) return; + if (this.touchMaskMap.size > 0) return; + + for (let i = 0; i < BlockEvents.length; i++) { + this.root.off(BlockEvents[i], this.stopPropagation, this, true); + } + } + + private stopPropagation(event: Event) { + if (!this.touchEnabled || this.touchMaskMap.size > 0) { + event.propagationStopped = true; + if (event.type !== Node.EventType.MOUSE_MOVE) { + this.log('屏蔽触摸'); + } + } + } + + /** + * 获取一个节点上的BaseView组件, 获取不到返回null + */ + private getBaseView(node: Node): BaseView { + if (!node) return null; + return node.components.find(component => component instanceof BaseView) as BaseView; + } + + /** + * 在所有父节点中找到一个最近的view组件 + * @param target + * @returns + */ + private getViewInParents(target: Node) { + let node = target; + let com: BaseView = null; + + while (node.parent && !(node.parent instanceof Scene)) { + com = this.getBaseView(node.parent); + if (!com) { + node = node.parent; + } else { + break; + } + } + return com; + } + + /** + * 在子节点中找到一个最近的view组件 + * @param target + * @returns + */ + private getViewInChildren(target: Node) { + for (let index = 0; index < target.children.length; index++) { + const node = target.children[index]; + const com = this.getBaseView(node); + if (com) return com; + } + return null; + } + + /** + * 根据UI名字获取它的脚本类 + */ + private getUIClass(name: string): typeof BaseView { + return js.getClassByName(name) as (typeof BaseView); + } + + /** + * 根据UI名字获取UI路径 + * @param name ui名字 + * @returns + */ + private getUIPath(name: string) { + return name; + } + + /** + * 获取前缀 + * @param name ui名字 + */ + private getUIPrefix(name: string): ViewType { + for (let index = 0; index < ViewTypes.length; index++) { + const typeName = ViewTypes[index]; + if (name.indexOf(typeName) === 0) { + return typeName; + } + } + this.error('getUIPrefix', `${name}`); + } + + /** + * 根据UI名字查询父节点 + * @param name ui名字 + */ + private getUIParent(name: string): Node { + if (this.currScene === name) { + return director.getScene(); + } + + const prefix = this.getUIPrefix(name); + for (let index = 0; index < ViewTypes.length; index++) { + const viewType = ViewTypes[index]; + if (viewType === prefix) { + return this.UserInterface.getChildByName(viewType); + } + } + + this.error('getUIParent', `找不到${name}对应的Parent`); + return null; + } + + /** + * 根据UI名字获取场景内的节点 + * @param name ui名字 + */ + private getUIInScene(name: string): Node; + private getUIInScene(name: string, multiple: false): Node; + private getUIInScene(name: string, multiple: true): Node[]; + private getUIInScene(name: string, multiple = false) { + const parent = this.getUIParent(name); + + if (multiple) { + const result = parent.children.filter(node => node.name === name); + if (result.length) return result.filter(node => isValid(node, true)); + } else { + const result = parent.children.find(node => node.name === name); + if (result) return isValid(result, true) ? result : null; + } + + return multiple ? [] : null; + } + + /** + * 根据UI名字获取展示中的节点 + * @param name ui名字 + */ + private getUIInShowing(name: string): Node; + private getUIInShowing(name: string, multiple: false): Node; + private getUIInShowing(name: string, multiple: true): Node[]; + private getUIInShowing(name: string, multiple = false) { + if (multiple) { + const result: Node[] = []; + this.uiShowingMap.forEach((_name, com) => { + if (_name === name) result.push(com.node); + }); + return result; + } else { + let result: Node = null; + this.uiShowingMap.forEach((_name, com) => { + if (!result && _name === name) result = com.node; + }); + return result; + } + } + + /** + * 获取UI骨架Bundle名字 + * @deprecated 将会移除,请改为其它方案 + */ + public getNativeBundleName(uiName: UIName | MiniName) { + // 兼容旧版本 + const oldBundleName = `app-view_${uiName}`; + const projectBundles = settings.querySettings(Settings.Category.ASSETS, 'projectBundles') as string[]; + if (projectBundles && projectBundles.indexOf(oldBundleName) >= 0) { + return oldBundleName; + } + + return stringCaseNegate(uiName); + } + + /** + * 获取UI资源Bundle名字 + * @deprecated 将会移除,请改为其它方案 + */ + public getResBundleName(uiName: UIName | MiniName) { + // 兼容旧版本 + const oldBundleName = `app-view_${uiName}_Res`; + const projectBundles = settings.querySettings(Settings.Category.ASSETS, 'projectBundles') as string[]; + if (projectBundles && projectBundles.indexOf(oldBundleName) >= 0) { + return oldBundleName; + } + + return `${stringCaseNegate(uiName)}-res`; + } + + /** + * 初始化Bundle + */ + private initBundle(name: UIName | MiniName, onFinish: (result: [AssetManager.Bundle, AssetManager.Bundle]) => any) { + Core.inst.lib.task.createASync<[AssetManager.Bundle, AssetManager.Bundle]>() + .add((next) => { + Core.inst.manager.loader.loadBundle({ + bundle: this.getNativeBundleName(name), + onComplete: next + }); + }) + .add((next) => { + Core.inst.manager.loader.loadBundle({ + bundle: this.getResBundleName(name), + onComplete: next + }); + }) + .start(onFinish); + } + + /** + * 安装UI + */ + private installUI(name: UIName | MiniName, complete?: (result: Prefab | SceneAsset | null) => any, progress?: (finish: number, total: number, item: AssetManager.RequestItem) => void) { + if (this.sceneCache[name]) { + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(this.sceneCache[name]); + }); + return; + } else if (this.prefabCache[name]) { + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(this.prefabCache[name]); + }); + return; + } + + const task = Core.inst.lib.task.createSync<[[AssetManager.Bundle, AssetManager.Bundle], Prefab | SceneAsset]>() + .add(next => { + this.initBundle(name, next); + }) + .add((next) => { + // 失败 + const uiBundles = task.results[0]; + if (!uiBundles || !uiBundles[0] || !uiBundles[1]) return next(null); + + const isScene = uiBundles[0].getSceneInfo(name); + Core.inst.manager.loader.load({ + bundle: this.getNativeBundleName(name), + path: this.getUIPath(name), + type: isScene ? SceneAsset : Prefab, + onProgress: progress, + onComplete: next + }); + }) + .start((results) => { + if (!isValid(this)) return; + // 验证缓存 + const cache = this.sceneCache[name] || this.prefabCache[name]; + if (cache) { + return complete && complete(cache); + } + // 验证有效 + const asset = results[1]; + if (!asset) { + return complete && complete(null); + } + // 添加引用计数 + asset.addRef(); + // 添加缓存 + if (asset instanceof Prefab) { + this.prefabCache[name] = asset; + } else { + this.sceneCache[name] = asset; + } + this.log(`加载: ${name}`); + return complete && complete(asset); + }); + } + + /** + * 卸载UI + */ + private uninstallUI(name: UIName | MiniName) { + if (this.sceneCache[name]) { + // 释放引用计数 + this.sceneCache[name].decRef(); + // 删除缓存 + delete this.sceneCache[name]; + } else if (this.prefabCache[name]) { + // 释放引用计数 + this.prefabCache[name].decRef(); + // 删除缓存 + delete this.prefabCache[name]; + } + + const resBundle = this.getResBundleName(name); + const naBundle = this.getNativeBundleName(name); + Core.inst.manager.loader.releaseAll(resBundle); + Core.inst.manager.loader.releaseAll(naBundle); + Core.inst.manager.loader.removeBundle(resBundle); + Core.inst.manager.loader.removeBundle(naBundle); + this.log(`卸载: ${name}`); + } + + /** + * 加载ui内部资源 + */ + public loadRes(target: Component, path: string, type: T, callback?: (item: InstanceType | null) => any) { + if (typeof target === 'string') { + Core.inst.manager.loader.load({ + bundle: this.getResBundleName(target), + path: path, + type: type, + onComplete: callback + }); + } else { + const view = this.getBaseView(target.node) || this.getViewInParents(target.node) || this.getViewInChildren(director.getScene()); + if (view) { + Core.inst.manager.loader.load({ + bundle: this.getResBundleName(view.viewName as UIName | MiniName), + path: path, + type: type, + onComplete: callback + }); + } else { + this.error('loadRes', target.name, path); + callback && callback(null); + } + } + } + + /** + * 预加载ui内部资源 + */ + public preloadRes(target: Component | UIName | MiniName, path: string, type: T, complete?: (item: AssetManager.RequestItem[] | null) => any) { + if (typeof target === 'string') { + Core.inst.manager.loader.preload({ + bundle: this.getResBundleName(target), + path: path, + type: type, + onComplete: complete + }); + } else { + const view = this.getBaseView(target.node) || this.getViewInParents(target.node) || this.getViewInChildren(director.getScene()); + if (view) { + Core.inst.manager.loader.preload({ + bundle: this.getResBundleName(view.viewName as UIName | MiniName), + path: path, + type: type, + onComplete: complete + }); + } else { + this.error('preloadRes', target.name, path); + } + } + } + + /** + * 加载ui内部资源 + */ + public loadResDir(target: Component, path: string, type: T, callback?: (items: InstanceType[] | null) => any) { + if (typeof target === 'string') { + Core.inst.manager.loader.loadDir({ + bundle: this.getResBundleName(target), + path: path, + type: type, + onComplete: callback + }); + } else { + const view = this.getBaseView(target.node) || this.getViewInParents(target.node) || this.getViewInChildren(director.getScene()); + if (view) { + Core.inst.manager.loader.loadDir({ + bundle: this.getResBundleName(view.viewName as UIName | MiniName), + path: path, + type: type, + onComplete: callback + }); + } else { + this.error('loadResDir', target.name, path); + callback && callback([]); + } + } + } + + /** + * 预加载ui内部资源 + */ + public preloadResDir(target: Component | UIName | MiniName, path: string, type: T, complete?: (item: AssetManager.RequestItem[] | null) => any) { + if (typeof target === 'string') { + Core.inst.manager.loader.preloadDir({ + bundle: this.getResBundleName(target), + path: path, + type: type, + onComplete: complete + }); + } else { + const view = this.getBaseView(target.node) || this.getViewInParents(target.node) || this.getViewInChildren(director.getScene()); + if (view) { + Core.inst.manager.loader.preloadDir({ + bundle: this.getResBundleName(view.viewName as UIName | MiniName), + path: path, + type: type, + onComplete: complete + }); + } else { + this.error('preloadResDir', target.name, path); + } + } + } + + /** + * 预加载UI + */ + public preload(name: UIName | MiniName, complete?: (item: AssetManager.RequestItem[] | null) => any) { + // 验证name是否为真 + if (!name) { + this.error('preload', 'fail'); + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(null); + }); + return; + } + + this.initBundle(name, ([naBundle]) => { + const isScene = naBundle.getSceneInfo(name); + Core.inst.manager.loader.preload({ + bundle: this.getNativeBundleName(name), + path: this.getUIPath(name), + type: isScene ? SceneAsset : Prefab, + onComplete: complete + }); + }); + } + + /** + * 加载UI + */ + public load(name: UIName | MiniName): void; + public load(name: UIName | MiniName, complete: (result: Prefab | SceneAsset | null) => any): void; + public load(name: UIName | MiniName, progress: (finish: number, total: number, item: AssetManager.RequestItem) => void, complete: (result: Prefab | SceneAsset | null) => any): void; + public load(name: UIName | MiniName, ...args: Function[]): void { + const progress = (args[1] && args[0]) as (finish: number, total: number, item: AssetManager.RequestItem) => void; + const complete = (args[1] || args[0]) as (result: any) => any; + + // 验证name是否为真 + if (!name) { + this.error('load', 'fail'); + complete && setTimeout(() => { + if (!isValid(this)) return; + complete(null); + }); + return; + } + + // 异步加载 + this.installUI(name, (result) => { + if (!result) return complete && complete(null); + return complete && complete(result); + }, progress); + } + + /** + * 销毁UI,释放资源 + * - 直接销毁,不管是否是show状态 + * - 此流程一定是同步的 + */ + public release(nameOrCom: UIName | MiniName | BaseView) { + const uiName = typeof nameOrCom === 'string' ? nameOrCom : nameOrCom.viewName; + + if (!uiName) { + this.error('release', `${nameOrCom} fail`); + return; + } + + // 传入字符串是释放所有 + if (typeof nameOrCom === 'string') { + this.getUIInScene(uiName, true).forEach((node) => { + const com = this.getBaseView(node); + if (!com) { + this.error('release', `${uiName}不存在BaseView组件`); + return; + } + + if (com.isShow) { + this.warn('release', `${uiName}正处于show状态, 此处将直接销毁`); + } + if (com === this.currPage) { + this.currPage = null; + } + if (com === this.currFocus) { + this.currFocus = null; + } + + this.uiShowingMap.delete(com); + + if (node && isValid(node, true)) { + node.parent = null; + node.destroy(); + } + }); + } + // 传入组件是释放单个 + else { + if (nameOrCom.isShow) { + this.warn('release', `${uiName}正处于show状态, 此处将直接销毁`); + } + if (nameOrCom === this.currPage) { + this.currPage = null; + } + if (nameOrCom === this.currFocus) { + this.currFocus = null; + } + + this.uiShowingMap.delete(nameOrCom); + + const node = nameOrCom.node; + if (node && isValid(node, true)) { + node.parent = null; + node.destroy(); + } + } + + // 当全部释放时才清除缓存 + const nodes = this.getUIInScene(uiName, true); + if (nodes.length === 0 || nodes.every(node => !isValid(node, true))) { + this.uninstallUI(uiName as UIName | MiniName); + this.log(`释放资源: ${uiName}`); + } + } + + /** + * 销毁全部UI,释放资源 + * - 直接销毁,不管是否是show状态 + * - 此流程一定是同步的 + */ + public releaseAll(exclude?: UIName[]) { + Object.keys(this.prefabCache).forEach((name: UIName) => { + if (exclude && exclude.indexOf(name) !== -1) return; + this.release(name); + }); + Object.keys(this.sceneCache).forEach((name: UIName) => { + if (exclude && exclude.indexOf(name) !== -1) return; + this.release(name); + }); + } + + /** + * 检查UI是否有效 + * - -1: 加载失败 + * - 0: UI无效 + * - 1: UI有效 + */ + private checkUIValid(name: UIName | MiniName, data: any, callback: (valid: -1 | 0 | 1) => any) { + this.installUI(name, (result) => { + if (!result) return callback(-1); + const View = this.getUIClass(name); + if (!View) return callback(0); + if (!View.isViewValid) return callback(1); + View.isViewValid((valid: boolean) => { + callback(valid ? 1 : 0); + }, data); + }); + } + + /** + * 更新阴影的层级及显示 + */ + public refreshShade() { + // 借助refreshShade实现onFocus、onLostFocus(onFocus不会被每次都触发,只有产生变化时才触发) + let onFocus = false; + // 倒序遍历uiRoots + let uiRoots = this.UserInterface.children; + for (let index = uiRoots.length - 1; index >= 0; index--) { + const uiRoot = uiRoots[index]; + if (uiRoot !== this.shade && uiRoot !== this.loading) { + // 倒序遍历uiRoot + let children = uiRoot.children; + for (let i = children.length - 1; i >= 0; i--) { + const node = children[i]; + if (node === this.shade) continue; + + const com = this.getBaseView(node); + if (!com) continue; + + // 触发onFocus + if (!onFocus && com.isCaptureFocus && com.isShow) { + onFocus = true; + if (this.currFocus !== com) { + isValid(this.currFocus, true) && this.currFocus.constructor.prototype.focus.call(this.currFocus, false); + this.currFocus = com; + this.currFocus.constructor.prototype.focus.call(this.currFocus, true); + } + } + // 添加遮罩 + if (com.isNeedShade && com.isShow) { + const shadeSetting = Object.assign({}, UIManager.setting.shade, com.constructor.prototype.onShade.call(com)); + if (shadeSetting.blur) { + this.shade.getComponent(UIMgrShade).init(0, 255, 255, 0, true); + } else { + this.shade.getComponent(UIMgrShade).init( + typeof shadeSetting.delay !== 'number' ? 0 : shadeSetting.delay, + typeof shadeSetting.begin !== 'number' ? 60 : shadeSetting.begin, + typeof shadeSetting.end !== 'number' ? 180 : shadeSetting.end, + typeof shadeSetting.speed !== 'number' ? 100 : shadeSetting.speed, + false, + ); + } + this.shade.layer = node.layer; + this.shade.parent = uiRoot; + this.shade.active = true; + // 以z坐标来代替2.x时代的zIndex + this.shade.setPosition(this.shade.position.x, this.shade.position.y, node.position.z); + + let shadeIndex = this.shade.getSiblingIndex(); + let nodeIndex = node.getSiblingIndex(); + if (shadeIndex > nodeIndex) { + this.shade.setSiblingIndex(nodeIndex); + } else { + this.shade.setSiblingIndex(nodeIndex - 1); + } + return; + } + } + } + } + + this.shade.active = false; + this.shade.getComponent(UIMgrShade).clear(); + if (!onFocus) { + isValid(this.currFocus, true) && this.currFocus.constructor.prototype.focus.call(this.currFocus, false); + this.currFocus = null; + } + } + + // 解析prefab + private parsingPrefab(prefab: Prefab, name: string) { + if (!prefab) return null; + + const node = instantiate(prefab); + + node.active = false; + if (node.name !== name) { + this.warn('parsingPrefab', `节点名与UI名不一致, 已重置为UI名: ${this.getUIPath(name)}`); + node.name = name; + } + + node.parent = this.getUIParent(name); + node.getComponent(Widget)?.updateAlignment(); + return node; + } + + // 解析scene + private parsingScene(asset: SceneAsset, name: string) { + if (!asset || !asset.scene) return null; + + if (asset.scene.name !== name) { + this.warn('parsingScene', `场景名与UI名不一致, 已重置为UI名: ${this.getUIPath(name)}`); + asset.scene.name = name; + } + + const view = this.getViewInChildren(asset.scene); + if (!view) { + this.error('parsingScene', `解析场景时未查询到根节点存在BaseView: ${this.getUIPath(name)}`); + return null; + } + + view.node.active = false; + if (view.node.name !== name) { + this.warn('parsingScene', `节点名与UI名不一致, 已重置为UI名: ${this.getUIPath(name)}`); + view.node.name = name; + } + return view.node; + } + + private addUILoadingUuid(name: UIName, loadingUuid?: string) { + const uuid = loadingUuid || this.createUUID(); + if (!this.uiLoadingMap.has(name)) { + this.uiLoadingMap.set(name, [uuid]); + } else { + this.uiLoadingMap.get(name).push(uuid); + } + return uuid; + } + + private removeUILoadingUuid(name: UIName, uuid: string) { + if (!this.uiLoadingMap.has(name)) return false; + const index = this.uiLoadingMap.get(name).indexOf(uuid); + if (index === -1) return false; + this.uiLoadingMap.get(name).splice(index, 1); + return true; + } + + /** + * 创建UI + */ + private createUI(name: UIName, silent: boolean, callback: (node: Node, scene?: Scene) => any) { + // 生成一个UI加载的UUID + const loadingUuid = silent ? '' : this.showLoading(); + const uiLoadingUuid = this.addUILoadingUuid(name, loadingUuid); + + // 验证name + if (!name) { + setTimeout(() => { + if (!isValid(this)) return; + // 验证本次加载是否有效 + if (this.removeUILoadingUuid(name, uiLoadingUuid) === false) { + return this.hideLoading(loadingUuid); + } + callback(null); + this.hideLoading(loadingUuid); + }); + return; + } + + // 判断是否已经存在节点并且是单例模式 + const node = this.getUIInScene(name); + if (isValid(node, true) && this.getBaseView(node).isSingleton === true) { + setTimeout(() => { + if (!isValid(this)) return; + + // 验证本次加载是否有效 + if (this.removeUILoadingUuid(name, uiLoadingUuid) === false) { + return this.hideLoading(loadingUuid); + } + + // 验证节点是否有效 + if (isValid(node, true)) { + if (this.currScene === name) { + callback(node, director.getScene()); + } else { + callback(node); + } + this.hideLoading(loadingUuid); + } else { + this.createUI(name, silent, callback); + this.hideLoading(loadingUuid); + } + }); + return; + } + + // 加载UI + this.load(name, (asset) => { + if (!isValid(this)) return; + + // 验证本次加载是否有效 + if (this.removeUILoadingUuid(name, uiLoadingUuid) === false) { + return this.hideLoading(loadingUuid); + } + + // 是场景 + if (asset instanceof SceneAsset) { + callback(this.parsingScene(asset, name), asset.scene); + this.hideLoading(loadingUuid); + return; + } + + // 验证是否是单例(一个单例会有被同时load多次的情况,因为判断一个ui是否是单例,必须要至少实例化一个后才能获取) + const node = this.getUIInScene(name); + if (!isValid(node, true) || this.getBaseView(node).isSingleton === false) { + callback(this.parsingPrefab(asset, name)); + this.hideLoading(loadingUuid); + } else { + callback(node); + this.hideLoading(loadingUuid); + } + }); + } + + /** + * 展示默认View + */ + public showDefault(onShow?: (result?: any) => any) { + if (this.defaultUI) { + this.show({ + name: this.defaultUI, + data: this.defaultData, + onShow + }); + } else { + Core.inst.manager.ui.showToast('请先设置首界面\n在setting.ts中修改defaultUI', 100); + onShow && onShow(); + this.warn('defaultUI不存在,请在setting.ts中修改'); + } + } + + /** + * 是否展示了(包括加载中和队列中) + */ + public isShow(name: UIName) { + return !!this.getUIInShowing(name) || + this.isInQueue(name) || + this.isLoading(name); + } + + /** + * 是否在队列中 + */ + public isInQueue(name: UIName) { + return !!this.showQueue.find((v) => { return v.name == name; }); + } + + /** + * 是否在加载中 + */ + public isLoading(name: UIName) { + return this.uiLoadingMap.has(name) && this.uiLoadingMap.get(name).length > 0; + } + + /** + * 放入队列 + */ + private putInShowQueue(data: IShowParams) { + if (data.queue === 'join' || this.showQueue.length === 0) { + this.showQueue.push(data); + } else { + this.showQueue.splice(1, 0, data); + } + if (this.showQueue.length === 1) { + this.consumeShowQueue(); + } + } + + /** + * 消耗队列 + */ + private consumeShowQueue() { + if (this.showQueue.length === 0) return; + const data = this.showQueue[0]; + this.show({ + name: data.name, + data: data.data, + onShow: data.onShow, + onHide: (result: any) => { + data.onHide && data.onHide(result); + this.showQueue.shift(); + this.consumeShowQueue(); + }, + onError: data.onError ? (error: string, code: 0 | 1) => { + const ret = data.onError(error, code); + this.showQueue.shift(); + this.consumeShowQueue(); + return ret; + } : undefined, + top: data.top, + attr: data.attr, + silent: data.silent + }); + } + + private showUI(params: IShowParams) { + const { name, data, onShow, onHide, onError, top = true, attr = null, silent = false } = params; + + this.createUI(name, silent, (node, scene) => { + if (!node) { + this.error('show', `${name} 不存在或加载失败`); + // 「没有指定onError」或「onError返回true」会自动发起重试 + if (onError && onError(`${name} 不存在或加载失败`, UIManager.ErrorCode.LoadError) !== true) { + return; + } + this.scheduleOnce(() => this.showUI(params), 1); + if (!silent) this.showLoading(1); + return; + } + + !scene && top && node.setSiblingIndex(-1); + + const com = this.getBaseView(node); + this.uiShowingMap.set(com, name); + com.constructor.prototype.show.call(com, data, attr, + // onShow + (result: any) => { + this.uiShowingMap.set(com, name); + onShow && onShow(result); + }, + // onHide + (result: any) => { + this.uiShowingMap.delete(com); + onHide && onHide(result); + }, + // beforeShow + (error: string) => { + if (error) { + this.uiShowingMap.delete(com); + onError && onError(error, UIManager.ErrorCode.LogicError); + } else if (BaseView.isPage(name)) { + this.uiShowingMap.set(com, name); + const oldCom = this.currPage; + this.currPage = com; + if (isValid(oldCom, true) && oldCom !== com && oldCom.isShow && oldCom.isAlwaysExist === false) { + oldCom.constructor.prototype.hide.call(oldCom, { name }); + } + if (scene) { + if (oldCom !== com) { + this.currScene = name; + director.runSceneImmediate(scene, null, () => { + this.log(`切换场景: ${name}`); + }); + } + } else if (this.currScene !== UIScene) { + this.currScene = UIScene; + const scene = new Scene(UIScene); + scene.autoReleaseAssets = true; + director.runSceneImmediate(scene, null, () => { + this.log(`切换场景: ${UIScene}`); + }); + } + } + } + ); + }); + } + + /** + * 展示一个UI + * - 此流程一定是异步的 + */ + public show(params + // @ts-ignore + : IShowParams[0], ReturnType, ReturnType>) { + const { name, data, queue, onError, silent = false } = params; + + // 加入队列中 + if (queue) { + this.putInShowQueue(params); + return; + } + + this.log(`show: ${name}`); + + // 生成一个UI加载的UUID + const loadingUuid = silent ? '' : this.showLoading(); + const uiLoadingUuid = this.addUILoadingUuid(name, loadingUuid); + // 判断ui是否有效 + Core.inst.lib.task.execute((retry) => { + this.checkUIValid(name, data, (valid) => { + // 验证本次加载是否有效 + if (this.removeUILoadingUuid(name, uiLoadingUuid) === false) { + this.hideLoading(loadingUuid); + return; + } + + // 加载失败 + if (valid === -1) { + this.error('show', `${name} 不存在或加载失败`); + // 「没有指定onError」或「onError返回true」会自动发起重试 + if (onError && onError(`${name} 不存在或加载失败`, UIManager.ErrorCode.LoadError) !== true) { + return this.hideLoading(loadingUuid); + } + return retry(1); + } + + // ui无效 + if (valid === 0) { + this.warn('show', `${name} 无效`); + this.uninstallUI(name); + onError && onError(`${name} 无效`, UIManager.ErrorCode.InvalidError); + this.hideLoading(loadingUuid); + return; + } + + this.showUI(params); + this.hideLoading(loadingUuid); + }); + }); + } + + /** + * 展示一个UI + * - 此流程一定是异步的 + */ + public showAsync(params + // @ts-ignore + : IShowAsyncParams[0], ReturnType>): Promise> { + return new Promise((resolve) => { + this.show({ + ...params, + onHide(result) { + resolve(result); + } + }); + }); + } + + /** + * 关闭View + * - 此流程一定是同步的 + */ + public hide({ name, data, onHide } + // @ts-ignore + : IHideParams[0], ReturnType>) { + const nodes = this.getUIInShowing(name, true); + + this.log(`hide: ${name}`); + + if (nodes.length === 0) { + if (!this.uiLoadingMap.has(name) || this.uiLoadingMap.get(name).length === 0) { + return this.warn('hide', `${name} 不存在`); + } + } + + if (this.uiLoadingMap.has(name)) { + this.uiLoadingMap.get(name).forEach((loadingUuid) => this.hideLoading(loadingUuid)); + this.uiLoadingMap.get(name).length = 0; + } + + for (let index = nodes.length - 1; index >= 0; index--) { + const node = nodes[index]; + const com = this.getBaseView(node); + + if (this.currPage === com) { + this.currPage = null; + } + + com.constructor.prototype.hide.call(com, data, onHide); + } + } + + /** + * 从顶部关闭一个View(不会重复关闭节点) + * - 此流程一定是同步的 + */ + public pop({ name, data, onHide } + // @ts-ignore + : IHideParams[0], ReturnType>) { + const nodes = this.getUIInShowing(name, true); + + if (this.uiLoadingMap.has(name) && this.uiLoadingMap.get(name).length) { + const loadingUuid = this.uiLoadingMap.get(name).pop(); + this.hideLoading(loadingUuid); + this.log(`pop: ${name}`); + return; + } + + if (nodes.length) { + const node = nodes.pop(); + const com = this.getBaseView(node); + + if (this.currPage === com) { + this.currPage = null; + } + + com.constructor.prototype.hide.call(com, data, onHide); + this.log(`pop: ${name}`); + return; + } + + this.warn('pop', `${name} 不存在`); + } + + /** + * 从底部关闭一个View(不会重复关闭节点) + * - 此流程一定是同步的 + */ + public shift({ name, data, onHide } + // @ts-ignore + : IHideParams[0], ReturnType>) { + const nodes = this.getUIInShowing(name, true); + + if (nodes.length) { + const node = nodes[0]; + const com = this.getBaseView(node); + + if (this.currPage === com) { + this.currPage = null; + } + + com.constructor.prototype.hide.call(com, data, onHide); + this.log(`shift: ${name}`); + return; + } + + if (this.uiLoadingMap.has(name) && this.uiLoadingMap.get(name).length) { + const loadingUuid = this.uiLoadingMap.get(name).shift(); + this.hideLoading(loadingUuid); + this.log(`shift: ${name}`); + return; + } + + this.warn('shift', `${name} 不存在`); + } + + /** + * 关闭全部View + * - 不关闭展示中的Page(加载中的会停止) + * - 此流程一定是同步的 + */ + public hideAll({ data, exclude }: { data?: any, exclude?: UIName[] } = {}): void { + this.log('hideAll'); + // 展示中的 + this.uiShowingMap.forEach((name, com) => { + if (BaseView.isPaper(name)) return; + if (exclude && exclude.indexOf(name) !== -1) return; + if (com === this.currPage) return; + com.constructor.prototype.hide.call(com, data); + }); + // 加载中的 + this.uiLoadingMap.forEach((value, name) => { + if (BaseView.isPaper(name)) return; + if (exclude && exclude.indexOf(name) !== -1) return; + value.forEach((loadingUuid) => this.hideLoading(loadingUuid)); + value.length = 0; + }); + } + + public showLoading(timeout = 0) { + this.loading.active = true; + this.loading.setSiblingIndex(-1); + if (this.loading.getComponent(UIMgrLoading)) { + this.loading.getComponent(UIMgrLoading).init(); + } else { + // 兼容旧版本 + this.loading.getComponentInChildren(UIMgrLoading)?.init(); + } + const uuid = this.createUUID(); + this.showLoadingMap.set(uuid, true); + if (timeout > 0) this.scheduleOnce(() => { + this.hideLoading(uuid); + }, timeout); + return uuid; + } + + public hideLoading(uuid: string) { + if (!uuid) return; + this.showLoadingMap.delete(uuid); + if (this.showLoadingMap.size === 0) { + if (this.loading.getComponent(UIMgrLoading)) { + this.loading.getComponent(UIMgrLoading).clear(); + } else { + // 兼容旧版本 + this.loading.getComponentInChildren(UIMgrLoading)?.clear(); + } + this.loading.active = false; + } + } + + /** + * 添加触摸屏蔽 + */ + public addTouchMask(timeout = 0) { + this.addTouchMaskListener(); + const uuid = this.createUUID(); + this.touchMaskMap.set(uuid, true); + if (timeout > 0) this.scheduleOnce(() => { + this.removeTouchMask(uuid); + }, timeout); + return uuid; + } + + /** + * 移除触摸屏蔽 + * @param uuid addTouchMask的返回值 + */ + public removeTouchMask(uuid: string) { + if (!uuid) return; + this.touchMaskMap.delete(uuid); + this.removeTouchMaskListener(); + } + + /** + * 显示Toast + * @param message 文本 + * @param timeout 持续时间(秒),默认2秒 + */ + public showToast(message: string, timeout?: number) { + if (!this.toast) { + return this.error('showToast', '请确认首场景中「Canvas/Manager/UIManager」的「Toast Pre」属性存在'); + } + this.toast.setSiblingIndex(-1); + this.toast.getComponent(UIMgrToast).add({ + message, timeout + }); + } + + /** + * 清理Toast + */ + public clearToast() { + if (!this.toast) return; + this.toast.getComponent(UIMgrToast).clear(); + } + + /** + * 设置触摸是否启用 + * @param enabled 是否启用 + */ + public setTouchEnabled(enabled: boolean) { + if (enabled) { + this.touchEnabled = true; + this.removeTouchMaskListener(); + } else { + this.addTouchMaskListener(); + this.touchEnabled = false; + } + this.warn('setTouchEnabled', this.touchEnabled); + } + + /** + * 在2DUI根节点上处理事件 + */ + public onUserInterface(...args: Parameters) { + Node.prototype.on.apply(this.UserInterface, args); + } + + /** + * 在2DUI根节点上处理事件 + */ + public onceUserInterface(...args: Parameters) { + Node.prototype.once.apply(this.UserInterface, args); + } + + /** + * 在2DUI根节点上处理事件 + */ + public offUserInterface(...args: Parameters) { + Node.prototype.off.apply(this.UserInterface, args); + } + + /** + * 在2DUI根节点上处理事件 + */ + public targetOffUserInterface(...args: Parameters) { + Node.prototype.targetOff.apply(this.UserInterface, args); + } + + /** + * 立即给2DUI的子节点排序 + */ + public sortUserInterface(name: IViewType) { + this.UserInterface + ?.getChildByName(name) + ?.getComponent(UIMgrZOrder) + ?.updateZOrder(); + } + + /** + * 屏幕截图 + * - 需要在Director.EVENT_BEFORE_RENDER事件中调用 + * @example + * director.once(Director.EVENT_BEFORE_RENDER, () => { + * const renderTexture = new RenderTexture(); + * const size = view.getVisibleSize(); + * renderTexture.reset({ width: size.width, height: size.height }); + * app.manager.ui.screenshot(renderTexture); + * }); + */ + public screenshot(renderTexture: RenderTexture, opts?: { + /**摄像机筛选 */ + cameraFilter?: (camera: Camera) => boolean; + /**摄像机列表 */ + cameraList?: Camera[]; + }) { + const cameras = opts?.cameraList || director.getScene().getComponentsInChildren(Camera); + + const cameraList = cameras.sort((a, b) => a.priority - b.priority) + .filter(camera => { + if (!camera.enabledInHierarchy) return false; + if (camera.targetTexture) return false; + return opts?.cameraFilter ? opts.cameraFilter(camera) : true; + }); + const cameraList2 = cameraList.map(camera => camera.camera); + + cameraList.forEach(camera => { + camera.targetTexture = renderTexture; + }); + director.root.pipeline.render(cameraList2); + cameraList.forEach(camera => { + camera.targetTexture = null; + }); + + return renderTexture; + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/UIManager.ts.meta b/extensions/app/assets/manager/ui/UIManager.ts.meta new file mode 100644 index 0000000..e89199c --- /dev/null +++ b/extensions/app/assets/manager/ui/UIManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "234f62f1-ebd3-4d14-9f6f-0b69c7096449", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/comp.meta b/extensions/app/assets/manager/ui/comp.meta new file mode 100644 index 0000000..b03d0d5 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "cc9c8895-27f9-49df-aca5-a0d1b9ba6480", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts b/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts new file mode 100644 index 0000000..2abf30c --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts @@ -0,0 +1,114 @@ +import { Component, Graphics, Node, Size, UITransform, _decorator } from 'cc'; +const { ccclass, property, requireComponent } = _decorator; + +@ccclass('UIMgrLoading') +@requireComponent(UITransform) +export default class UIMgrLoading extends Component { + @property(Node) + private loading: Node; + + @property({ tooltip: '动画的尺寸' }) + private size: Size = new Size(60, 60); + + @property({ tooltip: '等待几秒后开始动画' }) + private delay = 0; + + private progress = 0; + private ringScale = 1; + private reverse = false; + + private angleSpeed = 120; + private ringSpeed = 0.02; + + private inited = false; + private drawing = false; + private timedown = 0; + + init() { + if (this.inited) return; + this.inited = true; + + this.progress = 0; + this.ringScale = 1; + this.loading.angle = 0; + this.reverse = false; + + this.drawing = false; + this.timedown = this.delay; + this.loading.getComponent(Graphics).clear(); + } + + clear() { + this.inited = false; + this.drawing = false; + } + + /** + * 需要重写 + */ + private onDraw() { + const graphics = this.loading.getComponent(Graphics); + const uiTransform = this.loading.getComponent(UITransform); + + const centerX = this.size.width * (0.5 - uiTransform.anchorX); + const centerY = this.size.height * (0.5 - uiTransform.anchorY); + + const r = Math.min(this.size.width / 2, this.size.height / 2); + + const allPI = Math.PI; + const offst = 0; + + graphics.clear(); + if (this.reverse) { + const start = 0.5 * Math.PI + offst; + const end = 0.5 * Math.PI + this.progress * 2 * allPI + offst; + graphics.arc(centerX, centerY, r, start, end, true); + } else { + const start = 0.5 * Math.PI - offst; + const end = 0.5 * Math.PI - this.progress * 2 * allPI - offst; + graphics.arc(centerX, centerY, r, start, end, false); + } + graphics.stroke(); + } + + protected update(dt: number): void { + if (!this.inited) return; + + // 倒计时 + if (!this.drawing) { + if (this.timedown > 0) { + this.timedown -= dt; + } + if (this.timedown <= 0) { + this.drawing = true; + } else { + return; + } + } + + // 旋转 + this.loading.angle -= this.angleSpeed * dt; + if (this.loading.angle >= 360 || this.loading.angle <= -360) { + this.loading.angle = this.loading.angle % 360; + } + + // 进度 + if (this.ringScale > 0) { + this.progress = Math.min(1, this.progress + this.ringSpeed * this.ringScale); + + if (this.progress == 1) { + this.ringScale = -1; + this.reverse = !this.reverse; + } + } else { + this.progress = Math.max(0, this.progress + this.ringSpeed * this.ringScale); + + if (this.progress == 0) { + this.ringScale = 1; + this.reverse = !this.reverse; + } + } + + this.onDraw(); + } +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts.meta b/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts.meta new file mode 100644 index 0000000..4a8cd86 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrLoading.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "4a8e5697-ae78-4a4a-8d08-17acc6823a27", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrShade.ts b/extensions/app/assets/manager/ui/comp/UIMgrShade.ts new file mode 100644 index 0000000..bb9ec5f --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrShade.ts @@ -0,0 +1,167 @@ +import { Camera, Color, Component, Director, Material, RenderTexture, Sprite, SpriteFrame, UIOpacity, UITransform, _decorator, director } from 'cc'; +import Core from '../../../Core'; +const { ccclass, property, requireComponent } = _decorator; + +@ccclass('UIMgrShade') +@requireComponent(Sprite) +@requireComponent(UIOpacity) +export default class UIMgrShade extends Component { + @property(Material) + private blurMaterial: Material = null; + + @property(SpriteFrame) + private shadeFrame: SpriteFrame = null; + + @property + private _delay = 0; + @property + get delay() { return this._delay; } + set delay(v) { this._delay = Math.max(v, 0); } + + @property + private _begin = 0; + @property + get begin() { return this._begin; } + set begin(v) { if (v >= 0 && v <= 255) this._begin = v; } + + @property + private _end = 255; + @property + get end() { return this._end; } + set end(v) { if (v >= 0 && v <= 255) this._end = v; } + + @property + private _speed = 10; + @property + get speed() { + if (this.begin == this.end) { + return 0; + } else if (this.begin > this.end) { + return this._speed > 0 ? -this._speed : this._speed; + } else { + return this._speed >= 0 ? this._speed : -this._speed; + } + } + set speed(v) { this._speed = v; } + + private get sprite() { + return this.node.getComponent(Sprite); + } + private get opacity() { + return this.node.getComponent(UIOpacity); + } + + private inited = false; + private drawing = false; + private timedown = 0; + + private blurFrame: SpriteFrame = null; + + init(delay: number, begin: number, end: number, speed: number, blur: boolean) { + if (blur) { + director.targetOff(this); + this.inited = false; + this.drawing = false; + + this.sprite.color = Color.WHITE; + this.sprite.customMaterial = null; + this.sprite.spriteFrame = this.blurFrame; + if (this.blurFrame) this.blurFrame.flipUVY = false; + + let count = 0; + const cameras = director.getScene().getComponentsInChildren(Camera); + director.on(Director.EVENT_BEFORE_RENDER, () => { + count++; + + const renderTexture = new RenderTexture(); + const size = this.node.getComponent(UITransform); + renderTexture.reset({ width: size.width / 2, height: size.height / 2 }); + renderTexture.addRef(); + + Core.inst.manager.ui.screenshot(renderTexture, { + cameraList: cameras + }); + + if (count === 1) { + this.blurFrame = new SpriteFrame(); + this.blurFrame?.texture?.decRef(); + this.blurFrame.texture = renderTexture; + this.blurFrame.flipUVY = true; + this.sprite.spriteFrame = this.blurFrame; + this.sprite.customMaterial = this.blurMaterial; + this.blurMaterial.setProperty('blurLevel', 2); + return; + } + + if (count === 5) { + director.targetOff(this); + this.sprite.spriteFrame.flipUVY = false; + this.sprite.customMaterial = null; + return; + } + + this.blurFrame?.texture?.decRef(); + this.blurFrame.texture = renderTexture; + this.blurFrame.flipUVY = true; + this.sprite.spriteFrame = this.blurFrame; + this.sprite.customMaterial = this.blurMaterial; + this.blurMaterial.setProperty('blurLevel', count === 2 ? 3 : 1); + }, this); + } else { + director.targetOff(this); + this.sprite.spriteFrame = this.shadeFrame; + this.sprite.color = Color.BLACK; + this.sprite.customMaterial = null; + } + + this.delay = delay; + this.begin = begin; + this.end = end; + this.speed = speed; + this.drawing = true; + + if (this.inited) return; + this.inited = true; + this.timedown = this.delay; + // 初始透明度 + this.opacity.opacity = this.timedown > 0 ? 0 : this.begin; + } + + clear() { + this.inited = false; + this.drawing = false; + director.targetOff(this); + this.blurFrame?.texture?.decRef(); + this.blurFrame?.destroy(); + this.blurFrame = null; + this.sprite.spriteFrame = null; + } + + protected update(dt: number) { + if (!this.inited) return; + if (!this.drawing) return; + + if (this.timedown > 0) { + this.timedown -= dt; + if (this.timedown > 0) return; + // 初始透明度 + this.opacity.opacity = this.begin; + } + + const uiOpacity = this.opacity; + if (this.speed > 0) { + uiOpacity.opacity += this.speed * dt; + if (uiOpacity.opacity > this.end) { + uiOpacity.opacity = this.end; + } + } else if (this.speed < 0) { + uiOpacity.opacity += this.speed * dt; + if (uiOpacity.opacity < this.end) { + uiOpacity.opacity = this.end; + } + } + if (uiOpacity.opacity == this.end) { + this.drawing = false; + } + } +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrShade.ts.meta b/extensions/app/assets/manager/ui/comp/UIMgrShade.ts.meta new file mode 100644 index 0000000..f78139c --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrShade.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "d0295d9b-b01d-493c-9e31-5ed78e6c33ab", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrToast.ts b/extensions/app/assets/manager/ui/comp/UIMgrToast.ts new file mode 100644 index 0000000..b09f9dd --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrToast.ts @@ -0,0 +1,111 @@ +import { Component, NodePool, Prefab, Tween, UIOpacity, UITransform, _decorator, instantiate, tween, view } from 'cc'; +import UIMgrToastCell from './UIMgrToastCell'; +const { property, ccclass, requireComponent } = _decorator; + +@ccclass('UIMgrToast') +@requireComponent(UITransform) +export default class UIMgrToast extends Component { + @property(Prefab) + private cell: Prefab = null; + + /**每条信息显示几秒 */ + private lifeTime = 2; + + /**消失时花费几秒渐隐 */ + private outTime = 0.2; + + /**挤压基础速度 */ + private squeezeSpeed = 200; + + /**节点缓存池子 */ + private pool = new NodePool(); + + add(data: { + message: string, + timeout?: number + }) { + const cell = this.pool.get() || instantiate(this.cell); + cell.setPosition(0, 0, 0); + cell.parent = this.node; + cell.active = true; + + cell.getComponent(UIMgrToastCell).init(data.message); + + cell.getComponent(UIOpacity).opacity = 255; + tween(cell.getComponent(UIOpacity)) + .delay(data.timeout || this.lifeTime) + .to(this.outTime, { opacity: 0 }) + .call(() => { + this.pool.put(cell); + }) + .start(); + } + + clear() { + const children = this.node.children; + for (let index = children.length - 1; index >= 0; index--) { + Tween.stopAllByTarget(children[index].getComponent(UIOpacity)); + children[index].destroy(); + } + } + + get size() { + return this.node.children.length; + } + + protected onDestroy() { + this.pool.clear(); + } + + protected update(dt: number) { + const children = this.node.children; + for (let index = children.length - 1, recovery = false; index >= 0; index--) { + const zero = index === children.length - 1; + const curr = children[index]; + + // 直接触发回收逻辑 + if (recovery) { + Tween.stopAllByTarget(curr.getComponent(UIOpacity)); + this.pool.put(curr); + continue; + } + + if (zero) { + const currUT = curr.getComponent(UITransform); + + const lastMaxY = 0 - currUT.height / 2; + const currMinY = curr.position.y + lastMaxY; + + if (currMinY > lastMaxY) { + // 存在空隙 + const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY); + curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z); + } + } else { + const last = children[index + 1]; + const currUT = curr.getComponent(UITransform); + const lastUT = last.getComponent(UITransform); + + const currMinY = curr.position.y - currUT.height / 2 - 6;//6像素的间隔 + const lastMaxY = last.position.y + lastUT.height / 2; + + if (currMinY < lastMaxY) { + // 存在重叠 + const addLen = Math.min(this.squeezeSpeed * dt * (children.length - index - 1), lastMaxY - currMinY); + curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z); + const winSize = view.getVisibleSize(); + if (currMinY > winSize.height / 2) { + // 触发回收逻辑 + recovery = true; + Tween.stopAllByTarget(curr.getComponent(UIOpacity)); + this.pool.put(curr); + } + } else if (currMinY > lastMaxY) { + // 存在空隙 + const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY); + curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z); + } + } + } + } +} \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/comp/UIMgrToast.ts.meta b/extensions/app/assets/manager/ui/comp/UIMgrToast.ts.meta new file mode 100644 index 0000000..48cf3b0 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrToast.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "cde1528c-f66c-40f4-bdd2-27bf138ce1df", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts b/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts new file mode 100644 index 0000000..d76ecea --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts @@ -0,0 +1,26 @@ +import { Component, Label, UIOpacity, UITransform, _decorator } from 'cc'; +const { ccclass, property, requireComponent } = _decorator; + +@ccclass('UIMgrToastCell') +@requireComponent(UIOpacity) +@requireComponent(UITransform) +export default class UIMgrToastCell extends Component { + @property(Label) + private title: Label = null; + + init(title: string) { + if (title.split('\n').find((v) => v.length > 30)) { + this.title.overflow = Label.Overflow.RESIZE_HEIGHT; + this.title.getComponent(UITransform).width = 600; + } else { + this.title.overflow = Label.Overflow.NONE; + } + this.title.string = title; + this.title.updateRenderData(true); + } + + unuse() { + this.title.string = ''; + } +} + diff --git a/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts.meta b/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts.meta new file mode 100644 index 0000000..2cd4a78 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "6cc631d6-b08e-4ee3-8bde-e307c4288734", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts b/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts new file mode 100644 index 0000000..bee4128 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts @@ -0,0 +1,68 @@ +import { _decorator, Component, Director, director, Node } from 'cc'; +const { ccclass } = _decorator; + +@ccclass('UIMgrZOrder') +export default class UIMgrZOrder extends Component { + private zOrder = false; + private tempArr: Node[] = []; + + protected onLoad() { + this.checkUpdateZOrder(); + this.node.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this); + this.node.on(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this); + if (Node.EventType.CHILDREN_ORDER_CHANGED) { + this.node.on(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this); + } else { + this.node.on(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this); + } + } + + protected onDestroy() { + director.off(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this); + this.node.off(Node.EventType.CHILD_ADDED, this.onChildAdded, this); + this.node.off(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this); + if (Node.EventType.CHILDREN_ORDER_CHANGED) { + this.node.off(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this); + } else { + this.node.off(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this); + } + } + + private onChildAdded(child: Node) { + this.checkUpdateZOrder(); + child.on(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this); + } + + private onChildRemoveed(child: Node) { + child.off(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this); + } + + private checkUpdateZOrder() { + if (this.zOrder) return; + this.zOrder = true; + director.once(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this); + } + + /** + * 更新节点树排序 + */ + public updateZOrder() { + if (!this.zOrder) return; + Array.prototype.push.apply(this.tempArr, this.node.children); + this.tempArr + .sort((a, b) => { + return (a.position.z - b.position.z) + || (a.getSiblingIndex() - b.getSiblingIndex()); + }) + .forEach((child, index) => { + child.setSiblingIndex(index); + }); + + // 一定要放到最后再设置false, + // 避免更新过程中设置siblingIndex, + // 导致无限重复调用 + this.zOrder = false; + this.tempArr.length = 0; + } +} + diff --git a/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts.meta b/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts.meta new file mode 100644 index 0000000..3cfea93 --- /dev/null +++ b/extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "ad5cb510-639e-40c2-acdd-399ad00629b9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/effect.meta b/extensions/app/assets/manager/ui/effect.meta new file mode 100644 index 0000000..3901f28 --- /dev/null +++ b/extensions/app/assets/manager/ui/effect.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "e3ac29f9-11a4-461c-a404-9e478271b953", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/effect/blur.effect b/extensions/app/assets/manager/ui/effect/blur.effect new file mode 100644 index 0000000..d507dd0 --- /dev/null +++ b/extensions/app/assets/manager/ui/effect/blur.effect @@ -0,0 +1,119 @@ +CCEffect %{ + techniques: + - name: opaque + passes: + - vert: vs:vert + frag: fs:frag + depthStencilState: + depthTest: false + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: src_alpha + blendSrcAlpha: src_alpha + blendDst: one_minus_src_alpha + blendDstAlpha: one_minus_src_alpha + rasterizerState: + cullMode: none + properties: + blurSize: { value: [750, 1334] } + blurriness: { value: 1, editor: {range:[0, 1, 0.01], slide: true} } + blurLevel: { value: 1, editor: {range:[1, 3, 1], slide: true} } + +}% + +CCProgram vs %{ + precision highp float; + #include + + in vec4 a_position; + in vec2 a_texCoord; + out vec2 v_texCoord; + + vec4 vert() { + vec4 pos = cc_matViewProj * a_position; + v_texCoord = a_texCoord; + return pos; + } +}% + +CCProgram fs %{ + precision highp float; + + in vec2 v_texCoord; + #pragma builtin(local) + layout(set = 2, binding = 10) uniform sampler2D cc_spriteTexture; + + uniform Constant { + vec2 blurSize; + float blurriness; + float blurLevel; + }; + + // 模糊处理函数 + vec4 blur (vec2 pos) { + float sum = 0.0; + vec4 color = vec4(0); + + if (blurLevel == 1.0) { + const float blurRadius = 10.0; + const float blurStep = 1.0; + // 采样周边像素并求出加权平均值,得到最终的像素值 + for (float rx = -blurRadius; rx <= blurRadius; rx += blurStep) { + for (float ry = -blurRadius; ry <= blurRadius; ry += blurStep) { + vec2 target = pos + vec2(rx / blurSize[0], ry / blurSize[1]); + float weight = (blurRadius - abs(rx)) * (blurRadius - abs(ry)); + target.x = clamp(target.x, 0.0, 1.0); + target.y = clamp(target.y, 0.0, 1.0); + color += texture(cc_spriteTexture, target) * weight; + sum += weight; + } + } + } else if(blurLevel == 2.0) { + const float blurRadius = 20.0; + const float blurStep = 2.0; + // 采样周边像素并求出加权平均值,得到最终的像素值 + for (float rx = -blurRadius; rx <= blurRadius; rx += blurStep) { + for (float ry = -blurRadius; ry <= blurRadius; ry += blurStep) { + vec2 target = pos + vec2(rx / blurSize[0], ry / blurSize[1]); + float weight = (blurRadius - abs(rx)) * (blurRadius - abs(ry)); + target.x = clamp(target.x, 0.0, 1.0); + target.y = clamp(target.y, 0.0, 1.0); + color += texture(cc_spriteTexture, target) * weight; + sum += weight; + } + } + } else { + const float blurRadius = 30.0; + const float blurStep = 3.0; + // 采样周边像素并求出加权平均值,得到最终的像素值 + for (float rx = -blurRadius; rx <= blurRadius; rx += blurStep) { + for (float ry = -blurRadius; ry <= blurRadius; ry += blurStep) { + vec2 target = pos + vec2(rx / blurSize[0], ry / blurSize[1]); + float weight = (blurRadius - abs(rx)) * (blurRadius - abs(ry)); + target.x = clamp(target.x, 0.0, 1.0); + target.y = clamp(target.y, 0.0, 1.0); + color += texture(cc_spriteTexture, target) * weight; + sum += weight; + } + } + } + + color /= sum; + return color; + } + + vec4 frag () { + // 获取纹理像素颜色 + vec4 o = vec4(1, 1, 1, 1); + o *= texture(cc_spriteTexture, v_texCoord); + + // 执行模糊逻辑 + vec4 color = blur(v_texCoord); + color.a = o.a; + o = o + (color-o) * blurriness; + + return o; + } +}% \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/effect/blur.effect.meta b/extensions/app/assets/manager/ui/effect/blur.effect.meta new file mode 100644 index 0000000..b7542e8 --- /dev/null +++ b/extensions/app/assets/manager/ui/effect/blur.effect.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.7.1", + "importer": "effect", + "imported": true, + "uuid": "b5376e0b-9e5d-4c91-b0a4-19448fd39179", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/effect/blur.mtl b/extensions/app/assets/manager/ui/effect/blur.mtl new file mode 100644 index 0000000..4258d47 --- /dev/null +++ b/extensions/app/assets/manager/ui/effect/blur.mtl @@ -0,0 +1,36 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "_effectAsset": { + "__uuid__": "b5376e0b-9e5d-4c91-b0a4-19448fd39179", + "__expectedType__": "cc.EffectAsset" + }, + "_techIdx": 0, + "_defines": [ + {} + ], + "_states": [ + { + "rasterizerState": {}, + "depthStencilState": {}, + "blendState": { + "targets": [ + {} + ] + } + } + ], + "_props": [ + { + "textureSize": { + "__type__": "cc.Vec2", + "x": 750, + "y": 1334 + }, + "blurDegree": 1 + } + ] +} \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/effect/blur.mtl.meta b/extensions/app/assets/manager/ui/effect/blur.mtl.meta new file mode 100644 index 0000000..ac640a1 --- /dev/null +++ b/extensions/app/assets/manager/ui/effect/blur.mtl.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.0.21", + "importer": "material", + "imported": true, + "uuid": "a313b5eb-b939-4c44-affc-32c713440cea", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/app/assets/manager/ui/prefab.meta b/extensions/app/assets/manager/ui/prefab.meta new file mode 100644 index 0000000..3ecc885 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "a32ee073-dc9a-4d81-b3c1-54283a151627", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab b/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab new file mode 100644 index 0000000..f48e276 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab @@ -0,0 +1,508 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "UIMgrLoading", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "UIMgrLoading", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 10 + } + ], + "_active": true, + "_components": [ + { + "__id__": 16 + }, + { + "__id__": 18 + }, + { + "__id__": 20 + }, + { + "__id__": 22 + } + ], + "_prefab": { + "__id__": 24 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "com_loading", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_prefab": { + "__id__": 9 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b6gxyfJgNBVaS8SKPwT/Vz" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "1fc6b57d-ae88-4565-be7a-545305c50cbb@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8a4b8JKQpNvZqGYGVCtasS" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 8 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 1081, + "_originalHeight": 1920, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "32ZXlYVf9Pkp3PQ2aMccxA" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "ffw3zb5phEaay+kRp1VHLQ", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.Node", + "_name": "loading", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + }, + { + "__id__": 13 + } + ], + "_prefab": { + "__id__": 15 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 12 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 0, + "height": 0 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "93a3D7kcNLmKSzPl3DUiom" + }, + { + "__type__": "cc.Graphics", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": { + "__id__": 14 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_lineWidth": 8, + "_strokeColor": { + "__type__": "cc.Color", + "r": 247, + "g": 155, + "b": 17, + "a": 255 + }, + "_lineJoin": 2, + "_lineCap": 1, + "_fillColor": { + "__type__": "cc.Color", + "r": 247, + "g": 155, + "b": 17, + "a": 255 + }, + "_miterLimit": 10, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "8cV7EpeTlFy50kiDgQAuVw" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "f1BL1+S9ZHKLm/dYTzeaLU", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 17 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 1080, + "height": 1920 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3brXLn6dBA1Zn+gXeG0T+V" + }, + { + "__type__": "4a8e5aXrnhKSo0IF6zGgjon", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "loading": { + "__id__": 10 + }, + "size": { + "__type__": "cc.Size", + "width": 60, + "height": 60 + }, + "delay": 1, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "07sEXIwyZEKI/ruuFHnBcu" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 100, + "_originalHeight": 100, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "1en2H6LWVAnbHn1Id9zrSK" + }, + { + "__type__": "cc.BlockInputEvents", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 23 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "23+7We+IdLxIZlOVikvEPE" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "daRB56CWxIRa37BwtucqYI", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab.meta b/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab.meta new file mode 100644 index 0000000..c4dbb55 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrLoading.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "fe542035-b018-493e-bea8-084fe4e01905", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "UIMgrLoading" + } +} diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab b/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab new file mode 100644 index 0000000..be97b33 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab @@ -0,0 +1,262 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "UIMgrShade", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "UIMgrShade", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 2 + }, + { + "__id__": 4 + }, + { + "__id__": 6 + }, + { + "__id__": 8 + }, + { + "__id__": 10 + }, + { + "__id__": 12 + } + ], + "_prefab": { + "__id__": 14 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 3 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 750, + "height": 1334 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7dX6ImdfBJcqlTYmg63cOq" + }, + { + "__type__": "cc.UIOpacity", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 5 + }, + "_opacity": 255, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "79YFX8QOxIqrfZHGmtwiec" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 7 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "22F/XyC25NNbnQRqf69Fet" + }, + { + "__type__": "d02952bsB1JPJ4xXteObDOr", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 9 + }, + "blurMaterial": { + "__uuid__": "a313b5eb-b939-4c44-affc-32c713440cea", + "__expectedType__": "cc.Material" + }, + "shadeFrame": { + "__uuid__": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_delay": 0, + "_begin": 60, + "_end": 180, + "_speed": 100, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "cfGNW3HSFJZ5C0B0FM1PtW" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 11 + }, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 750, + "_originalHeight": 1334, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "229/N15SBGH4HGma+cYqM5" + }, + { + "__type__": "cc.BlockInputEvents", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 13 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "82DtXS4ChDkLThlpVA53IU" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "61DZmvnnRICYRzOyDnyCeu", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab.meta b/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab.meta new file mode 100644 index 0000000..945fb2b --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrShade.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "000cee21-922c-4fcd-bd39-6f80ac2436a4", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "UIMgrShade" + } +} diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab b/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab new file mode 100644 index 0000000..cff94c7 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab @@ -0,0 +1,93 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "UIMgrToast", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "UIMgrToast", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 2 + } + ], + "_prefab": { + "__id__": 4 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cde15KM9mxA9L3SJ78TjOHf", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 3 + }, + "cell": { + "__uuid__": "5aa9450d-6710-4fac-a82c-ee2939cf9411", + "__expectedType__": "cc.Prefab" + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "3aBOvgZTJM7o51sRqaqstL" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "7cYDN4HdROmJQ7qqaDYftE", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab.meta b/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab.meta new file mode 100644 index 0000000..7f2a682 --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrToast.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "b2a00c44-d199-4031-8fa7-ea681618b9d4", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "UIMgrToast" + } +} diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab b/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab new file mode 100644 index 0000000..c0ebfeb --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab @@ -0,0 +1,438 @@ +[ + { + "__type__": "cc.Prefab", + "_name": "UIMgrToastCell", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "data": { + "__id__": 1 + }, + "optimizationPolicy": 0, + "persistent": false + }, + { + "__type__": "cc.Node", + "_name": "UIMgrToastCell", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + } + ], + "_active": true, + "_components": [ + { + "__id__": 8 + }, + { + "__id__": 10 + }, + { + "__id__": 12 + }, + { + "__id__": 14 + }, + { + "__id__": 16 + }, + { + "__id__": 18 + } + ], + "_prefab": { + "__id__": 20 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.Node", + "_name": "title", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + }, + { + "__id__": 5 + } + ], + "_prefab": { + "__id__": 7 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 3.552713678800501e-15, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 4 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 0, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "18U2eEmv1MSrJ3Kp8ChYCB" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": { + "__id__": 6 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_string": "", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 30, + "_fontSize": 30, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 0, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_enableOutline": false, + "_outlineColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_outlineWidth": 2, + "_enableShadow": false, + "_shadowColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_shadowOffset": { + "__type__": "cc.Vec2", + "x": 2, + "y": 2 + }, + "_shadowBlur": 2, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "fcBV+kyJJKoLa0miLOwB0D" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "17FiiUdlpA7INUb+CSPtXV", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 9 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 70.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "7bhW+VfdhFIZBU1YlNH87w" + }, + { + "__type__": "cc.UIOpacity", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 11 + }, + "_opacity": 255, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "85IfdKUvlDVobXX10lMYgh" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 13 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "7922bee9-7eb5-449b-884e-14ac57ae515c@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 1, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "d5KZg62HRMhqP9FpXXBvrN" + }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 15 + }, + "_resizeMode": 1, + "_layoutType": 1, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 40, + "_paddingRight": 40, + "_paddingTop": 10, + "_paddingBottom": 10, + "_spacingX": 0, + "_spacingY": 0, + "_verticalDirection": 1, + "_horizontalDirection": 0, + "_constraint": 0, + "_constraintNum": 1, + "_affectedByScale": false, + "_isAlign": false, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "e0RO5Tg+lAWq8B14qLuRXc" + }, + { + "__type__": "cc.Layout", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 17 + }, + "_resizeMode": 1, + "_layoutType": 2, + "_cellSize": { + "__type__": "cc.Size", + "width": 40, + "height": 40 + }, + "_startAxis": 0, + "_paddingLeft": 0, + "_paddingRight": 0, + "_paddingTop": 10, + "_paddingBottom": 10, + "_spacingX": 0, + "_spacingY": 0, + "_verticalDirection": 1, + "_horizontalDirection": 0, + "_constraint": 0, + "_constraintNum": 2, + "_affectedByScale": false, + "_isAlign": false, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "b4w/hORDRDYLZbEx1j4ybh" + }, + { + "__type__": "6cc63HWsI5O44ve4wfEKIc0", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 1 + }, + "_enabled": true, + "__prefab": { + "__id__": 19 + }, + "title": { + "__id__": 5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a82bayEVpB1YYG3zm38T3l" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "c46/YsCPVOJYA4mWEpNYRx", + "instance": null, + "targetOverrides": null + } +] \ No newline at end of file diff --git a/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab.meta b/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab.meta new file mode 100644 index 0000000..64354bf --- /dev/null +++ b/extensions/app/assets/manager/ui/prefab/UIMgrToastCell.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "5aa9450d-6710-4fac-a82c-ee2939cf9411", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "UIMgrToastCell" + } +} diff --git a/extensions/app/assets/manager/ui/texture.meta b/extensions/app/assets/manager/ui/texture.meta new file mode 100644 index 0000000..42788a9 --- /dev/null +++ b/extensions/app/assets/manager/ui/texture.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "f5f10a35-ca33-4eb2-81f1-52459832001b", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/extensions/app/assets/manager/ui/texture/singleColor.png b/extensions/app/assets/manager/ui/texture/singleColor.png new file mode 100644 index 0000000..09fa6c5 Binary files /dev/null and b/extensions/app/assets/manager/ui/texture/singleColor.png differ diff --git a/extensions/app/assets/manager/ui/texture/singleColor.png.meta b/extensions/app/assets/manager/ui/texture/singleColor.png.meta new file mode 100644 index 0000000..54efaf1 --- /dev/null +++ b/extensions/app/assets/manager/ui/texture/singleColor.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "5512993f-89ea-46fe-b788-0ecc0c2cd51c", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@6c48a", + "displayName": "singleColor", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "5512993f-89ea-46fe-b788-0ecc0c2cd51c", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@f9941", + "displayName": "singleColor", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 2, + "height": 2, + "rawWidth": 2, + "rawHeight": 2, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -1, + -1, + 0, + 1, + -1, + 0, + -1, + 1, + 0, + 1, + 1, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 2, + 2, + 2, + 0, + 0, + 2, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -1, + -1, + 0 + ], + "maxPos": [ + 1, + 1, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "hasAlpha": false, + "redirect": "5512993f-89ea-46fe-b788-0ecc0c2cd51c@6c48a" + } +} diff --git a/extensions/app/assets/manager/ui/texture/toastBox.png b/extensions/app/assets/manager/ui/texture/toastBox.png new file mode 100644 index 0000000..ea9b7f9 Binary files /dev/null and b/extensions/app/assets/manager/ui/texture/toastBox.png differ diff --git a/extensions/app/assets/manager/ui/texture/toastBox.png.meta b/extensions/app/assets/manager/ui/texture/toastBox.png.meta new file mode 100644 index 0000000..4b36a0d --- /dev/null +++ b/extensions/app/assets/manager/ui/texture/toastBox.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "b250e49c-5d79-4d07-a85f-a980fca36170", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "b250e49c-5d79-4d07-a85f-a980fca36170@6c48a", + "displayName": "toastBox", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "b250e49c-5d79-4d07-a85f-a980fca36170", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "b250e49c-5d79-4d07-a85f-a980fca36170@f9941", + "displayName": "toastBox", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 288, + "height": 78, + "rawWidth": 288, + "rawHeight": 78, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 40, + "borderRight": 40, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -144, + -39, + 0, + 144, + -39, + 0, + -144, + 39, + 0, + 144, + 39, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 78, + 288, + 78, + 0, + 0, + 288, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -144, + -39, + 0 + ], + "maxPos": [ + 144, + 39, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "b250e49c-5d79-4d07-a85f-a980fca36170@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "hasAlpha": true, + "redirect": "b250e49c-5d79-4d07-a85f-a980fca36170@6c48a" + } +} diff --git a/extensions/app/assets/manager/ui/texture/toastCell.png b/extensions/app/assets/manager/ui/texture/toastCell.png new file mode 100644 index 0000000..bc921ba Binary files /dev/null and b/extensions/app/assets/manager/ui/texture/toastCell.png differ diff --git a/extensions/app/assets/manager/ui/texture/toastCell.png.meta b/extensions/app/assets/manager/ui/texture/toastCell.png.meta new file mode 100644 index 0000000..fe005d6 --- /dev/null +++ b/extensions/app/assets/manager/ui/texture/toastCell.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "7922bee9-7eb5-449b-884e-14ac57ae515c", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "7922bee9-7eb5-449b-884e-14ac57ae515c@6c48a", + "displayName": "toastCell", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "7922bee9-7eb5-449b-884e-14ac57ae515c", + "isUuid": true, + "visible": false, + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0 + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "7922bee9-7eb5-449b-884e-14ac57ae515c@f9941", + "displayName": "toastCell", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 100, + "height": 100, + "rawWidth": 100, + "rawHeight": 100, + "borderTop": 15, + "borderBottom": 15, + "borderLeft": 15, + "borderRight": 15, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -50, + -50, + 0, + 50, + -50, + 0, + -50, + 50, + 0, + 50, + 50, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 100, + 100, + 100, + 0, + 0, + 100, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -50, + -50, + 0 + ], + "maxPos": [ + 50, + 50, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "7922bee9-7eb5-449b-884e-14ac57ae515c@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "hasAlpha": true, + "fixAlphaTransparencyArtifacts": false, + "redirect": "7922bee9-7eb5-449b-884e-14ac57ae515c@6c48a" + } +} diff --git a/extensions/app/engine/.gitignore b/extensions/app/engine/.gitignore new file mode 100644 index 0000000..d1d7911 --- /dev/null +++ b/extensions/app/engine/.gitignore @@ -0,0 +1,4 @@ +#///////////////////////////////////////////////////////////////////////////// +# files +#///////////////////////////////////////////////////////////////////////////// +/node_modules \ No newline at end of file diff --git a/extensions/app/engine/@types/editor.d.ts b/extensions/app/engine/@types/editor.d.ts new file mode 100644 index 0000000..af320d5 --- /dev/null +++ b/extensions/app/engine/@types/editor.d.ts @@ -0,0 +1,1227 @@ +/// + +/// +/// + +import * as NodeJSPath from 'path'; +import { EventEmitter } from 'events'; +import { FileFilter, BrowserWindow, OpenDialogReturnValue, SaveDialogReturnValue, MessageBoxReturnValue } from 'electron'; + +declare global { + export namespace Editor { + export namespace App { + export const userAgent: string; + /** + * 是否是开发模式 + * Development mode + */ + export const dev: boolean; + /** + * 编辑器版本号 + * Editor version + */ + export const version: string; + /** + * 主目录 + * Home directory + */ + export const home: string; + /** + * 编辑器程序文件夹 + * Program folder + */ + export const path: string; + /** + * 获取当前编辑器的临时缓存目录 + * Temporary cache directory + */ + export const temp: string; + /** + * 获取当前编辑器 icon 地址 + * Gets the icon address of the current editor + */ + export const icon: string; + /** + * 获取当前编辑器使用的 url 地址 + * Gets the URL used by the current editor + */ + export const urls: { + manual: string; + api: string; + forum: string; + }; + /** + * 退出程序 + * Exit the program + */ + export function quit(): void; + } + export namespace Clipboard { + export type ICopyType = 'image' | 'text' | 'files' | string; + /** + * 获取剪贴板内容 + * @param type + */ + export function read(type: ICopyType): any; + /** + * 写入剪贴板内容 + * @param type + * @param value + */ + export function write(type: 'image', value: string): boolean; + export function write(type: 'text', value: string): boolean; + export function write(type: 'files', value: FileList): boolean; + export function write(type: string, value: any): boolean; + + /** + * 判断当前剪贴板内是否是指定类型 + * @param type + */ + export function has(type: ICopyType): boolean; + /** + * 清空剪贴板 + */ + export function clear(): void; + } + export namespace Dialog { + + export interface SaveDialogOptions { + title?: string; + path?: string; + button?: string; + filters?: FileFilter[]; + } + export interface SelectDialogOptions { + title?: string; + path?: string; + type?: 'directory' | 'file'; + button?: string; + multi?: boolean; + filters?: FileFilter[]; + extensions?: string; + } + export interface MessageDialogOptions { + title?: string; + detail?: string; + default?: number; + cancel?: number; + checkboxLabel?: string; + checkboxChecked?: boolean; + buttons?: string[]; + } + + /** + * 选择文件弹窗 + * Select the file popover + * + * @param options 选择弹窗参数 Select popover parameters + * @param window 依附于哪个窗口(插件主进程才可使用) Which window it is attached to (only available to the plugin's main process) + */ + export function select(options?: SelectDialogOptions, window?: BrowserWindow): Promise; + /** + * 保存文件弹窗 + * Save the file popup + * + * @param options 保存文件窗口参数 Save the file window parameters + * @param window 依附于哪个窗口(插件主进程才可使用) Which window it is attached to (only available to the plugin's main process) + */ + export function save(options?: SaveDialogOptions, window?: BrowserWindow): Promise; + /** + * 信息弹窗 + * Information popup window + * + * @param message 显示的消息 Displayed message + * @param options 信息弹窗可选参数 Information popup optional parameter + * @param window 依附于哪个窗口(插件主进程才可使用) Which window it is attached to (only available to the plugin's main process) + */ + export function info(message: string, options?: MessageDialogOptions, window?: BrowserWindow): Promise; + /** + * 警告弹窗 + * Warning popup + * + * @param message 警告信息 Warning message + * @param options 警告弹窗可选参数 Warning popover optional parameter + * @param window 依附于哪个窗口(插件主进程才可使用) Which window it is attached to (only available to the plugin's main process) + */ + export function warn(message: string, options?: MessageDialogOptions, window?: BrowserWindow): Promise; + /** + * 错误弹窗 + * Error popup window + * + * @param message 错误信息 The error message + * @param options 错误弹窗可选参数 Error popover optional parameter + * @param window 依附于哪个窗口(插件主进程才可使用) Which window it is attached to (only available to the plugin's main process) + */ + export function error(message: string, options?: MessageDialogOptions, window?: BrowserWindow): Promise; + } + export namespace EditMode { + /** + * 标记编辑器进入了一种编辑模式 + * The tag editor goes into an edit mode + * + * @param mode 编辑模式的名字 The name of the edit mode + */ + export function enter(mode: string); + /** + * 当前所处的编辑模式 + * The current editing mode + * + */ + export function getMode(): string; + } + export namespace I18n { + export type I18nMap = { + [key: string]: I18nMap | string; + }; + /** + * 获取当前的语言 zh | en + * Get the current language + */ + export function getLanguage(): string; + /** + * 传入 key,翻译成当前语言 + * Passing in the key translates into the current language + * 允许翻译变量 {a},传入的第二个参数 obj 内定义 a + * The translation variable {a} is allowed, and a is defined in the second argument passed in obj + * + * @param key 用于翻译的 key 值 The key value for translation + * @param obj 翻译字段内如果有 {key} 等可以在这里传入替换字段 If you have {key} in the translation field, you can pass in the replacement field here + */ + export function t( + key: string, + obj?: { + [key: string]: string; + }, + ): string; + + /** + * 选择一种翻译语言 + * Choose a translation language + * + * @param language 选择当前使用的语言 Select the language currently in use + */ + export function select(language: string): void; + } + export namespace Layout { + /** + * 应用布局信息 + * Application layout information + * + * @param json 布局文件内容 Layout file content + */ + export function apply(json: any); + /** + * 初始化布局系统 + * Initialize the layout system + */ + export function init(); + } + export namespace Logger { + /** + * 清空所有的日志 + * Clear all logs + */ + export function clear(regexp?: string | RegExp): any; + /** + * 查询所有日志 + * Query all logs + */ + export function query(): any; + } + export namespace Menu { + export interface BaseMenuItem { + template?: string; + type?: string; + label?: string; + sublabel?: string; + checked?: boolean; + enabled?: boolean; + icon?: string; + accelerator?: string; + order?: number; + group?: string; + message?: string; + target?: string; + params?: any[]; + click?: Function | null; + role?: string; + submenu?: MenuTemplateItem[]; + } + export interface MainMenuItem extends BaseMenuItem { + path: string; + } + export interface ContextMenuItem extends BaseMenuItem { + accelerator?: string; + } + export type MenuTemplateItem = BaseMenuItem; + export interface PopupOptions { + x?: number; + y?: number; + menu: ContextMenuItem[]; + } + /** + * 右键弹窗 + * Right-click pop-up + * 只有面板进程可以使用 + * Only panel processes can be used + * + * @param json + */ + export function popup(json: PopupOptions): any; + } + export namespace Message { + export interface MessageInfo { + methods: string[]; + public?: boolean; + description?: string; + doc?: string; + sync?: boolean; + } + + export interface TableBase { + [x: string]: any; + params: any[]; + } + /** + * 发送一个消息,并等待返回 + * Send a message and wait for it to return + * + * @param name 目标插件的名字 The name of the target plug-in + * @param message 触发消息的名字 The name of the trigger message + * @param args 消息需要的参数 The parameters required for the message + */ + export function request( + name: J, + message: K, + ...args: EditorMessageMaps[J][K]['params'] + ): Promise; + /** + * 发送一个消息,没有返回 + * Send a message, no return + * + * @param name 目标插件的名字 The name of the target plug-in + * @param message 触发消息的名字 The name of the trigger message + * @param args 消息需要的参数 The parameters required for the message + */ + export function send( + name: M, + message: N, + ...args: EditorMessageMaps[M][N]['params'] + ): void; + /** + * 广播一个消息 + * Broadcast a message + * + * @param message 消息的名字 Name of message + * @param args 消息附加的参数 Parameter attached to the message + */ + export function broadcast(message: string, ...args: any[]): void; + /** + * 新增一个广播消息监听器 + * Add a new broadcast message listener + * 不监听的时候,需要主动取消监听 + * When not listening, you need to take the initiative to cancel listening + * + * @param message 消息名 Message name + * @param func 处理函数 The processing function + */ + export function addBroadcastListener(message: string, func: Function): any; + /** + * 新增一个广播消息监听器 + * Removes a broadcast message listener + * + * @param message 消息名 Message name + * @param func 处理函数 The processing function + */ + export function removeBroadcastListener(message: string, func: Function): any; + } + export namespace Network { + /** + * 查询当前电脑的 ip 列表 + * Query the IP list of the current computer + */ + export function queryIPList(): string[]; + /** + * 测试是否可以联通 passport.cocos.com 服务器 + * Test whether you can connect to the passport.cocos.com server + */ + export function testConnectServer(): Promise; + /** + * 检查一个端口是否被占用 + * Checks if a port is used + * + * @param port + */ + export function portIsOccupied(port: number): Promise; + /** + * 测试是否可以联通某一台主机 + * Test whether a host can be connected + * + * @param ip + */ + export function testHost(ip: string): Promise; + /** + * Get 方式请求某个服务器数据 + * GET requests data from a server + * + * @param url + * @param data + */ + export function get( + url: string, + data?: { + [index: string]: string | string[]; + }, + ): Promise; + /** + * Post 方式请求某个服务器数据 + * POST requests data from a server + * + * @param url + * @param data + */ + export function post( + url: string, + data?: { + [index: string]: string | number | string[]; + }, + ): Promise; + /** + * 获取某个可用的端口号 + * get the port that is free + * + * @param port + */ + export function getFreePort(port: number): Promise; + } + export namespace Package { + // export module VERSION: string; + export interface GetPackageOptions { + name?: string; + debug?: boolean; + path?: string; + enable?: boolean; + invalid?: boolean; + } + export interface PackageJson { + author?: string; + debug?: boolean; + description?: string; + main?: string; + menu?: any; + name: string; + version: string; + windows: string; + editor?: string; + panel?: any; + } + export type PathType = 'home' | 'data' | 'temp'; + /** + * 查询插件列表 + * Query Plug-in List + * + * @param options + */ + export function getPackages(options?: GetPackageOptions): Editor.Interface.PackageInfo[]; + /** + * 注册一个插件 + * Register a plug-in + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * + * @param path + */ + export function register(path: string): any; + /** + * 反注册一个插件 + * Unregister a plug-in + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * + * @param path + */ + export function unregister(path: string): any; + /** + * 启动一个插件 + * Enable a plug-in + * + * @param path + */ + export function enable(path: string): any; + /** + * 关闭一个插件 + * Disable a plug-in + * + * @param path + */ + export function disable(path: string, options: any): any; + /** + * 获取一个插件的几个预制目录地址 + * Gets several prefab directory addresses for a plug-in + * + * @param extensionName 扩展的名字 Name of the extension + * @param type 地址类型(temp 临时目录,data 需要同步的数据目录,不传则返回现在打开的插件路径) Address type (temp temporary directory, data need to synchronize data directory, do not pass to return the current open plug-in path) + */ + export function getPath(extensionName: string, type?: PathType): any; + } + export namespace Panel { + /** + * 打开一个面板 + * Open up a panel + * + * @param name + * @param args + */ + export function open(name: string, ...args: any[]): any; + /** + * 关闭一个面板 + * Close a panel + * + * @param name + */ + export function close(name: string): any; + /** + * 将焦点传递给一个面板 + * Pass focus to a panel + * + * @param name + */ + export function focus(name: string): any; + /** + * 检查面板是否已经打开 + * Check that the panel is open + * + * @param name + */ + export function has(name: string): Promise; + /** + * 查询当前窗口里某个面板里的元素列表 + * @param name + * @param selector + */ + export function querySelector(name: string, selector: string): Promise; + + export type Selector<$> = { $: Record }; + + export type Options void> = { + /** + * @en Listening to panel events + * @zh 监听面板事件 + */ + listeners?: { + /** + * @en Hooks triggered when the panel is displayed + * @zh 面板显示的时候触发的钩子 + */ + show?: () => any; + /** + * @en Hooks triggered when the panel is hidden + * @zh 面板隐藏的时候触发的钩子 + */ + hide?: () => any; + }; + + /** + * @en Template of the panel + * @zh 面板的内容 + */ + template: string; + /** + * @en Style of the panel + * @zh 面板上的样式 + * */ + style?: string; + /** + * @en Selector of the panel + * @zh 快捷选择器 + */ + $?: S; + /** + * @en Panel built-in function methods that can be called in Messages, Listeners, lifecycle functions + * @zh panel 内置的函数方法,可以在 messages、listeners、生命周期函数内调用 + */ + methods?: M; + /** + * @en Hooks triggered when the panel is update + * @zh 面板数据更新后触发的钩子函数 + */ + update?: (...args: Parameters) => void; + /** + * @en Hooks triggered when the panel is ready + * @zh 面板启动后触发的钩子函数 + */ + ready?: () => void; + /** + * @en The function that will be triggered when the panel is ready to close, and will terminate the closing of the panel if it + * returns false + * @zh 面板准备关闭的时候会触发的函数,return false 的话,会终止关闭面板 + * 生命周期函数,在 panel 准备关闭的时候触发 + * 如果 return false,则会中断关闭流程,请谨慎使用,错误的判断会导致编辑器无法关闭。 + */ + beforeClose?: () => Promise | boolean | void; + /** + * @en Hook functions after panel closure + * @zh 面板关闭后的钩子函数 + */ + close?: () => void; + } & ThisType & M>; // merge them together + + export function define void, Selector = Record, M = Record>( + options: Options, + ): any; + } + export namespace Profile { + export type preferencesProtocol = 'default' | 'global' | 'local'; + export type projectProtocol = 'default' | 'project'; + export type tempProtocol = 'temp'; + export interface ProfileGetOptions { + type: 'deep' | 'current' | 'inherit'; + } + export interface ProfileObj { + get: (key?: string, options?: ProfileGetOptions) => any; + set: (key?: string, value?: any) => any; + remove: (key: string) => void; + save: () => void; + clear: () => void; + reset: () => void; + } + /** + * 读取插件配置 + * Read the plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param type 配置的类型,选填 Type of configuration, optional(global,local,default) + */ + export function getConfig(name: string, key?: string, type?: preferencesProtocol): Promise; + /** + * 设置插件配置 + * Set the plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param value 配置的值 The value of the configuration + * @param type 配置的类型,选填 Type of configuration, optional(global,local,default) + */ + export function setConfig(name: string, key: string, value: any, type?: preferencesProtocol): Promise; + /** + * 删除某个插件配置 + * Delete a plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param type 配置的类型,选填 Type of configuration, optional(global,local,default) + */ + export function removeConfig(name: string, key: string, type?: preferencesProtocol): Promise; + /** + * 读取插件内的项目配置 + * Read the project configuration within the plug-in + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param type 配置的类型,选填 Type of configuration, optional(project,default) + */ + export function getProject(name: string, key?: string, type?: projectProtocol): Promise; + /** + * 设置插件内的项目配置 + * Set the project configuration within the plug-in + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param value 配置的值 The value of the configuration + * @param type 配置的类型,选填 Type of configuration, optional(project,default) + */ + export function setProject(name: string, key: string, value: any, type?: projectProtocol): Promise; + /** + * 删除插件内的项目配置 + * Delete the project configuration within the plug-in + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param type 配置的类型,选填 Type of configuration, optional(project,default) + */ + export function removeProject(name: string, key: string, type?: projectProtocol): Promise; + /** + * 读取插件配置 + * Read the plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + */ + export function getTemp(name: string, key?: string): Promise; + /** + * 设置插件配置 + * Set the plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + * @param value 配置的值 The value of the configuration + */ + export function setTemp(name: string, key: string, value: any): Promise; + /** + * 删除某个插件配置 + * Delete a plug-in configuration + * + * @param name 插件名 The plugin name + * @param key 配置路径 Configure path + */ + export function removeTemp(name: string, key: string): Promise; + /** + * 迁移插件某个版本的本地配置数据到编辑器最新版本 + * Migrate the local configuration data of a certain version of the plugin to the latest version of the editor + * + * @param pkgName + * @param profileVersion + * @param profileData + */ + export function migrateLocal(pkgName: string, profileVersion: string, profileData: any): any; + /** + * 迁移插件某个版本的全局配置数据到编辑器最新版本 + * Migrate the global configuration data of a certain version of the plugin to the latest version of the editor + * + * @param pkgName + * @param profileVersion + * @param profileData + */ + export function migrateGlobal(pkgName: string, profileVersion: string, profileData: any): any; + /** + * 迁移插件某个版本的项目配置数据到编辑器最新版本 + * Migrate the project configuration data of a certain version of the plugin to the latest version of the editor + * + * @param pkgName + * @param profileVersion + * @param profileData + */ + export function migrateProject(pkgName: string, profileVersion: string, profileData: any): any; + } + export namespace Project { + /** + * 创建一个项目 + * Creating a project + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export function create(): any; + /** + * 打开一个项目 + * Open a project + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * + * @param path + */ + export function open(path?: string): Promise; + /** + * 添加一个项目 + * Add a project + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * + * @param path + */ + export function add(path: string): any; + /** + * 当前项目路径 + * Current project path + */ + export const path: string; + /** + * 当前项目 uuid + * The current project UUID + */ + export const uuid: string; + /** + * 当前项目名称(取自 package.json) + * The current project name + */ + export const name: string; + /** + * 当前项目临时文件夹 + * Temporary folder for current project + */ + export const tmpDir: string; + /** + * 当前项目类型 + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export const type: '2d' | '3d'; + } + export namespace Selection { + /** + * 选中一个或者一组元素 + * Select one or a group of elements + * + * @param type + * @param uuid + */ + export function select(type: string, uuid: string | string[]): any; + /** + * 取消一个或者一组元素的选中状态 + * To deselect one or a group of elements + * + * @param type + * @param uuid + */ + export function unselect(type: string, uuid: string | string[]): any; + /** + * 清空一个类型的所有选中元素 + * Clears all selected elements of a type + * + * @param type + */ + export function clear(type: string): any; + /** + * 更新当前选中的类型数据 + * Updates the currently selected type data + * + * @param type + * @param uuids + */ + export function update(type: string, uuids: string[]): any; + /** + * 悬停触碰了某个元素 + * Hover touches an element + * 会发出 selection:hover 的广播消息 + * A broadcast message for selection:hover is issued + * + * @param type + * @param uuid + */ + export function hover(type: string, uuid?: string): any; + /** + * 获取最后选中的元素的类型 + * Gets the type of the last selected element + */ + export function getLastSelectedType(): string; + /** + * 获取某个类型内,最后选中的元素 + * Gets the last selected element of a type + * + * @param type + */ + export function getLastSelected(type: string): string; + /** + * 获取一个类型选中的所有元素数组 + * Gets an array of all elements selected for a type + * + * @param type + */ + export function getSelected(type: string): string[]; + } + export namespace Task { + export interface NoticeOptions { + title: string; + message?: string; + type?: 'error' | 'warn' | 'log' | 'success'; + source?: string; + timeout?: number; + } + /** + * 添加一个同步任务 + * Add a synchronous task + * 会在主窗口显示一个遮罩层 + * A mask layer is displayed in the main window + * + * @param title 任务名字 The task name + * @param describe 任务描述 Task description + * @param message 任务内容 Content of the task + */ + export function addSyncTask(title: string, describe?: string, message?: string): any; + /** + * 更新某一个同步任务显示的数据 + * Update the data displayed by a synchronous task + * + * @param title 任务名字 The task name + * @param describe 任务描述 Task description + * @param message 任务内容 Content of the task + */ + export function updateSyncTask(title: string, describe?: string, message?: string): any; + /** + * 删除一个同步任务 + * Delete a synchronous task + * + * @param title 任务的名字 The name of the task + */ + export function removeSyncTask(title: string): any; + /** + * 添加一个通知 + * Add a notification + * + * @param options 消息配置 Message configuration + */ + export function addNotice(options: NoticeOptions): any; + /** + * 删除一个通知 + * Delete a notification + * + * @param id 通知 id Notification ID + */ + export function removeNotice(id: number): any; + /** + * 修改 notice 自动移除的时间 + * Modify notice automatic removal time + * + * @param id 通知 id Notification ID + * @param time 超时时间 timeout + */ + export function changeNoticeTimeout(id: number, time: number): any; + /** + * 查询所有通知 + * Query all notifications + */ + export function queryNotices(): any; + /** + * 页面进程立即同步一次主进程数据 + * The page process synchronizes the master process data immediately + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export function sync(): any; + } + export namespace Theme { + /** + * 获取所有主题的名字 + * Gets the names of all topics + */ + export function getList(): any; + /** + * 使用某个皮肤 + * Use a certain skin + * + * @param name + */ + export function use(name?: string): any; + } + export namespace UI { + /** + * 在当前页面上注册一个自定义节点 + * Registers a custom node on the current page + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * + * @param tagName 元素名字 + * @param element 元素的定义函数 + */ + export function register(tagName: string, element: any): void; + export const Base: any; + export const Button: any; + export const Input: any; + export const NumInput: any; + export const Loading: any; + export const Checkbox: any; + export const Section: any; + export const Select: any; + export const Bit: any; + export const Slider: any; + export const ColorPicker: any; + export const Color: any; + export const DragItem: any; + export const DragArea: any; + export const DragObject: any; + export const Prop: any; + export const Tooltip: any; + export const TextArea: any; + export const Progress: any; + export const Label: any; + export const Code: any; + export const Tab: any; + export const Gradient: any; + export const GradientPicker: any; + export const Icon: any; + export const File: any; + export const Link: any; + export const Image: any; + export const QRCode: any; + export const Markdown: any; + export const Curve: any; + export const CurveEditor: any; + export const NodeGraph: any; + } + export namespace User { + export interface UserData { + session_id: string; + session_key: string; + cocos_uid: string; + email: string; + nickname: string; + } + /** + * 跳过 User + * Skip the User + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export function skip(): any; + /** + * 获取 user 数据 + * Get user data + */ + export function getData(): Promise; + /** + * 检查用户是否登陆 + * Check if the user is logged in + */ + export function isLoggedIn(): Promise; + /** + * 用户登陆 + * The user login + * 失败会抛出异常 + * Failure throws an exception + * + * @param username + * @param password + */ + export function login(username: string, password: string): Promise; + /** + * 退出登陆 + * Logged out + * 失败会抛出异常 + * Failure throws an exception + */ + export function logout(): void; + /** + * 获取用户 token + * Get user token + * 失败会抛出异常 + * Failure throws an exception + */ + export function getUserToken(): Promise; + /** + * 根据插件 id 返回 session code + * Returns the session code based on the plug-in ID + * + * @param extensionId + */ + export function getSessionCode(extensionId: number): Promise; + /** + * 显示用户登陆遮罩层 + * Shows user login mask layer + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export function showMask(): void; + /** + * 隐藏用户登陆遮罩层 + * Hide user login mask layer + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + */ + export function hideMask(): void; + /** + * 监听事件 + * Listen for an event + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * @param action + * @param handle + */ + export function on(action: string, handle: Function): any; + /** + * 监听一次事件 + * Listening for one event + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * @param action + * @param handle + */ + export function once(action: string, handle: Function): any; + /** + * 取消已经监听的事件 + * Cancels the event you are listening for + * 谨慎使用,之后会被移除 + * Use with caution and it will be removed later + * @param action + * @param handle + */ + export function removeListener(action: string, handle: Function): any; + } + export namespace Utils { + export namespace File { + /** + * 初始化一个可用的文件名 + * Initializes a available filename + * 返回可用名称的文件路径 + * Returns the file path with the available name + * + * @param file 初始文件路径 Initial file path + */ + export function getName(file: string): string; + interface UnzipOptions { + peel?: boolean; + } + /** + * 解压文件夹 + * Unzip folder + * + * @param zip + * @param target + * @param options + */ + export function unzip(zip: string, target: string, options?: UnzipOptions): Promise; + /** + * 复制一个文件到另一个位置 + * Copy a file to another location + * + * @param source + * @param target + */ + export function copy(source: string, target: string): void; + } + export namespace Path { + /** + * 返回一个不含扩展名的文件名 + * @param path + */ + export function basenameNoExt(path: string): string; + /** + * 将 \ 统一换成 / + * @param path + */ + export function slash(path: string): string; + /** + * 去除路径最后的斜杆,返回一个不带斜杆的路径 + * @param path + */ + export function stripSep(path: string): string; + /** + * 删除一个路径的扩展名 + * @param path + */ + export function stripExt(path: string): string; + /** + * 判断路径 pathA 是否包含 pathB + * pathA = foo/bar, pathB = foo/bar/foobar, return true + * pathA = foo/bar, pathB = foo/bar, return true + * pathA = foo/bar/foobar, pathB = foo/bar, return false + * pathA = foo/bar/foobar, pathB = foobar/bar/foo, return false + * @param pathA + * @param pathB + */ + export function contains(pathA: string, pathB: string): boolean; + /** + * 格式化路径 + * 如果是 Windows 平台,需要将盘符转成小写进行判断 + * @param path + */ + export function normalize(path: string): string; + export const join: typeof NodeJSPath.join; + export const resolve: typeof NodeJSPath.resolve; + export const isAbsolute: typeof NodeJSPath.isAbsolute; + export const relative: typeof NodeJSPath.relative; + export const dirname: typeof NodeJSPath.dirname; + export const basename: typeof NodeJSPath.basename; + export const extname: typeof NodeJSPath.extname; + export const sep: '\\' | '/'; + export const delimiter: ';' | ':'; + export const parse: typeof NodeJSPath.parse; + export const format: typeof NodeJSPath.format; + } + export namespace Math { + /** + * 取给定边界范围的值 + * Take the value of the given boundary range + * @param {number} val + * @param {number} min + * @param {number} max + */ + export function clamp(val: number, min: number, max: number): number; + /** + * @function clamp01 + * @param {number} val + * @returns {number} + * + * Clamps a value between 0 and 1. + */ + export function clamp01(val: number): number; + /** + * 加法函数 + * 入参:函数内部转化时会先转字符串再转数值,因而传入字符串或 number 均可 + * 返回值:arg1 加上 arg2 的精确结果 + * @param {number|string} arg1 + * @param {number|string} arg2 + */ + export function add(arg1: number | string, arg2: number | string): number; + /** + * 减法函数 + * 入参:函数内部转化时会先转字符串再转数值,因而传入字符串或number均可 + * 返回值:arg1 减 arg2的精确结果 + * @param {number|string} arg1 + * @param {number|string} arg2 + */ + export function sub(arg1: number | string, arg2: number | string): number; + /** + * 保留小数点 + * @param val + * @param num + */ + export function toFixed(val: number, num: number): number; + } + export namespace Parse { + interface WhenParam { + PanelName?: string; + EditMode?: string; + ProjectType?: string; + } + /** + * 解析 when 参数 + * when 的格式: + * PanelName === '' && EditMode === '' + * 整理后的数据格式: + * { + * PanelName: '', + * EditMode: '', + * } + */ + export function when(when: string): WhenParam; + /** + * 判断一个 when 数据是否符合当前条件 + * @param when + */ + export function checkWhen(when: string): boolean; + } + export namespace Url { + /** + * 快捷获取文档路径 + * @param relativeUrl + * @param type + */ + export function getDocUrl(relativeUrl: string, type?: 'manual' | 'api'): string; + } + + export namespace UUID { + /** + * 压缩 UUID + * compress UUID + * @param uuid + * @param min + */ + export function compressUUID(uuid: string, min: boolean): string; + /** + * 解压 UUID + * decompress the UUID + * @param str + */ + export function decompressUUID(str: string): string; + /** + * 检查输入字符串是否是 UUID + * Check whether the input string is a UUID + * @param str + */ + export function isUUID(str: string): string; + /** + * 生成一个新的 uuid + */ + export function generate(): string; + } + } + export namespace Module { + /** + * 导入一个项目模块。 + * @param url 项目模块的 Database URL。 + * @experimental 实验性质。 + */ + export function importProjectModule(url: string): Promise; + } + } +} diff --git a/extensions/app/engine/@types/electron.d.ts b/extensions/app/engine/@types/electron.d.ts new file mode 100644 index 0000000..7aff6b9 --- /dev/null +++ b/extensions/app/engine/@types/electron.d.ts @@ -0,0 +1,16090 @@ +// Type definitions for Electron 13.1.4 +// Project: http://electronjs.org/ +// Definitions by: The Electron Team +// Definitions: https://github.com/electron/electron-typescript-definitions + +/// + +type GlobalEvent = Event & { returnValue: any }; + +declare namespace Electron { + const NodeEventEmitter: typeof import('events').EventEmitter; + + class Accelerator extends String { + + } + interface App extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/app + + /** + * Emitted when Chrome's accessibility support changes. This event fires when + * assistive technologies, such as screen readers, are enabled or disabled. See + * https://www.chromium.org/developers/design-documents/accessibility for more + * details. + * + * @platform darwin,win32 + */ + on(event: 'accessibility-support-changed', listener: (event: Event, + /** + * `true` when Chrome's accessibility support is enabled, `false` otherwise. + */ + accessibilitySupportEnabled: boolean) => void): this; + once(event: 'accessibility-support-changed', listener: (event: Event, + /** + * `true` when Chrome's accessibility support is enabled, `false` otherwise. + */ + accessibilitySupportEnabled: boolean) => void): this; + addListener(event: 'accessibility-support-changed', listener: (event: Event, + /** + * `true` when Chrome's accessibility support is enabled, `false` otherwise. + */ + accessibilitySupportEnabled: boolean) => void): this; + removeListener(event: 'accessibility-support-changed', listener: (event: Event, + /** + * `true` when Chrome's accessibility support is enabled, `false` otherwise. + */ + accessibilitySupportEnabled: boolean) => void): this; + /** + * Emitted when the application is activated. Various actions can trigger this + * event, such as launching the application for the first time, attempting to + * re-launch the application when it's already running, or clicking on the + * application's dock or taskbar icon. + * + * @platform darwin + */ + on(event: 'activate', listener: (event: Event, + hasVisibleWindows: boolean) => void): this; + once(event: 'activate', listener: (event: Event, + hasVisibleWindows: boolean) => void): this; + addListener(event: 'activate', listener: (event: Event, + hasVisibleWindows: boolean) => void): this; + removeListener(event: 'activate', listener: (event: Event, + hasVisibleWindows: boolean) => void): this; + /** + * Emitted during Handoff after an activity from this device was successfully + * resumed on another one. + * + * @platform darwin + */ + on(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + once(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + addListener(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + removeListener(event: 'activity-was-continued', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + /** + * Emitted before the application starts closing its windows. Calling + * `event.preventDefault()` will prevent the default behavior, which is terminating + * the application. + * + * **Note:** If application quit was initiated by `autoUpdater.quitAndInstall()`, + * then `before-quit` is emitted *after* emitting `close` event on all windows and + * closing them. + * + * **Note:** On Windows, this event will not be emitted if the app is closed due to + * a shutdown/restart of the system or a user logout. + */ + on(event: 'before-quit', listener: (event: Event) => void): this; + once(event: 'before-quit', listener: (event: Event) => void): this; + addListener(event: 'before-quit', listener: (event: Event) => void): this; + removeListener(event: 'before-quit', listener: (event: Event) => void): this; + /** + * Emitted when a browserWindow gets blurred. + */ + on(event: 'browser-window-blur', listener: (event: Event, + window: BrowserWindow) => void): this; + once(event: 'browser-window-blur', listener: (event: Event, + window: BrowserWindow) => void): this; + addListener(event: 'browser-window-blur', listener: (event: Event, + window: BrowserWindow) => void): this; + removeListener(event: 'browser-window-blur', listener: (event: Event, + window: BrowserWindow) => void): this; + /** + * Emitted when a new browserWindow is created. + */ + on(event: 'browser-window-created', listener: (event: Event, + window: BrowserWindow) => void): this; + once(event: 'browser-window-created', listener: (event: Event, + window: BrowserWindow) => void): this; + addListener(event: 'browser-window-created', listener: (event: Event, + window: BrowserWindow) => void): this; + removeListener(event: 'browser-window-created', listener: (event: Event, + window: BrowserWindow) => void): this; + /** + * Emitted when a browserWindow gets focused. + */ + on(event: 'browser-window-focus', listener: (event: Event, + window: BrowserWindow) => void): this; + once(event: 'browser-window-focus', listener: (event: Event, + window: BrowserWindow) => void): this; + addListener(event: 'browser-window-focus', listener: (event: Event, + window: BrowserWindow) => void): this; + removeListener(event: 'browser-window-focus', listener: (event: Event, + window: BrowserWindow) => void): this; + /** + * Emitted when failed to verify the `certificate` for `url`, to trust the + * certificate you should prevent the default behavior with + * `event.preventDefault()` and call `callback(true)`. + */ + on(event: 'certificate-error', listener: (event: Event, + webContents: WebContents, + url: string, + /** + * The error code + */ + error: string, + certificate: Certificate, + callback: (isTrusted: boolean) => void) => void): this; + once(event: 'certificate-error', listener: (event: Event, + webContents: WebContents, + url: string, + /** + * The error code + */ + error: string, + certificate: Certificate, + callback: (isTrusted: boolean) => void) => void): this; + addListener(event: 'certificate-error', listener: (event: Event, + webContents: WebContents, + url: string, + /** + * The error code + */ + error: string, + certificate: Certificate, + callback: (isTrusted: boolean) => void) => void): this; + removeListener(event: 'certificate-error', listener: (event: Event, + webContents: WebContents, + url: string, + /** + * The error code + */ + error: string, + certificate: Certificate, + callback: (isTrusted: boolean) => void) => void): this; + /** + * Emitted when the child process unexpectedly disappears. This is normally because + * it was crashed or killed. It does not include renderer processes. + */ + on(event: 'child-process-gone', listener: (event: Event, + details: Details) => void): this; + once(event: 'child-process-gone', listener: (event: Event, + details: Details) => void): this; + addListener(event: 'child-process-gone', listener: (event: Event, + details: Details) => void): this; + removeListener(event: 'child-process-gone', listener: (event: Event, + details: Details) => void): this; + /** + * Emitted during Handoff when an activity from a different device wants to be + * resumed. You should call `event.preventDefault()` if you want to handle this + * event. + * + * A user activity can be continued only in an app that has the same developer Team + * ID as the activity's source app and that supports the activity's type. Supported + * activity types are specified in the app's `Info.plist` under the + * `NSUserActivityTypes` key. + * + * @platform darwin + */ + on(event: 'continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity on another device. + */ + userInfo: unknown) => void): this; + once(event: 'continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity on another device. + */ + userInfo: unknown) => void): this; + addListener(event: 'continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity on another device. + */ + userInfo: unknown) => void): this; + removeListener(event: 'continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity on another device. + */ + userInfo: unknown) => void): this; + /** + * Emitted during Handoff when an activity from a different device fails to be + * resumed. + * + * @platform darwin + */ + on(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + once(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + addListener(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + removeListener(event: 'continue-activity-error', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * A string with the error's localized description. + */ + error: string) => void): this; + /** + * Emitted when `desktopCapturer.getSources()` is called in the renderer process of + * `webContents`. Calling `event.preventDefault()` will make it return empty + * sources. + */ + on(event: 'desktop-capturer-get-sources', listener: (event: Event, + webContents: WebContents) => void): this; + once(event: 'desktop-capturer-get-sources', listener: (event: Event, + webContents: WebContents) => void): this; + addListener(event: 'desktop-capturer-get-sources', listener: (event: Event, + webContents: WebContents) => void): this; + removeListener(event: 'desktop-capturer-get-sources', listener: (event: Event, + webContents: WebContents) => void): this; + /** + * Emitted when mac application become active. Difference from `activate` event is + * that `did-become-active` is emitted every time the app becomes active, not only + * when Dock icon is clicked or application is re-launched. + * + * @platform darwin + */ + on(event: 'did-become-active', listener: (event: Event) => void): this; + once(event: 'did-become-active', listener: (event: Event) => void): this; + addListener(event: 'did-become-active', listener: (event: Event) => void): this; + removeListener(event: 'did-become-active', listener: (event: Event) => void): this; + /** + * Emitted whenever there is a GPU info update. + */ + on(event: 'gpu-info-update', listener: Function): this; + once(event: 'gpu-info-update', listener: Function): this; + addListener(event: 'gpu-info-update', listener: Function): this; + removeListener(event: 'gpu-info-update', listener: Function): this; + /** + * Emitted when the GPU process crashes or is killed. + * + * **Deprecated:** This event is superceded by the `child-process-gone` event which + * contains more information about why the child process disappeared. It isn't + * always because it crashed. The `killed` boolean can be replaced by checking + * `reason === 'killed'` when you switch to that event. + * + * @deprecated + */ + on(event: 'gpu-process-crashed', listener: (event: Event, + killed: boolean) => void): this; + once(event: 'gpu-process-crashed', listener: (event: Event, + killed: boolean) => void): this; + addListener(event: 'gpu-process-crashed', listener: (event: Event, + killed: boolean) => void): this; + removeListener(event: 'gpu-process-crashed', listener: (event: Event, + killed: boolean) => void): this; + /** + * Emitted when `webContents` wants to do basic auth. + * + * The default behavior is to cancel all authentications. To override this you + * should prevent the default behavior with `event.preventDefault()` and call + * `callback(username, password)` with the credentials. + * + * If `callback` is called without a username or password, the authentication + * request will be cancelled and the authentication error will be returned to the + * page. + */ + on(event: 'login', listener: (event: Event, + webContents: WebContents, + authenticationResponseDetails: AuthenticationResponseDetails, + authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + once(event: 'login', listener: (event: Event, + webContents: WebContents, + authenticationResponseDetails: AuthenticationResponseDetails, + authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + addListener(event: 'login', listener: (event: Event, + webContents: WebContents, + authenticationResponseDetails: AuthenticationResponseDetails, + authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + removeListener(event: 'login', listener: (event: Event, + webContents: WebContents, + authenticationResponseDetails: AuthenticationResponseDetails, + authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + /** + * Emitted when the user clicks the native macOS new tab button. The new tab button + * is only visible if the current `BrowserWindow` has a `tabbingIdentifier` + * + * @platform darwin + */ + on(event: 'new-window-for-tab', listener: (event: Event) => void): this; + once(event: 'new-window-for-tab', listener: (event: Event) => void): this; + addListener(event: 'new-window-for-tab', listener: (event: Event) => void): this; + removeListener(event: 'new-window-for-tab', listener: (event: Event) => void): this; + /** + * Emitted when the user wants to open a file with the application. The `open-file` + * event is usually emitted when the application is already open and the OS wants + * to reuse the application to open the file. `open-file` is also emitted when a + * file is dropped onto the dock and the application is not yet running. Make sure + * to listen for the `open-file` event very early in your application startup to + * handle this case (even before the `ready` event is emitted). + * + * You should call `event.preventDefault()` if you want to handle this event. + * + * On Windows, you have to parse `process.argv` (in the main process) to get the + * filepath. + * + * @platform darwin + */ + on(event: 'open-file', listener: (event: Event, + path: string) => void): this; + once(event: 'open-file', listener: (event: Event, + path: string) => void): this; + addListener(event: 'open-file', listener: (event: Event, + path: string) => void): this; + removeListener(event: 'open-file', listener: (event: Event, + path: string) => void): this; + /** + * Emitted when the user wants to open a URL with the application. Your + * application's `Info.plist` file must define the URL scheme within the + * `CFBundleURLTypes` key, and set `NSPrincipalClass` to `AtomApplication`. + * +You should call `event.preventDefault()` if you want to handle this event. + * + * @platform darwin + */ + on(event: 'open-url', listener: (event: Event, + url: string) => void): this; + once(event: 'open-url', listener: (event: Event, + url: string) => void): this; + addListener(event: 'open-url', listener: (event: Event, + url: string) => void): this; + removeListener(event: 'open-url', listener: (event: Event, + url: string) => void): this; + /** + * Emitted when the application is quitting. + * + * **Note:** On Windows, this event will not be emitted if the app is closed due to + * a shutdown/restart of the system or a user logout. + */ + on(event: 'quit', listener: (event: Event, + exitCode: number) => void): this; + once(event: 'quit', listener: (event: Event, + exitCode: number) => void): this; + addListener(event: 'quit', listener: (event: Event, + exitCode: number) => void): this; + removeListener(event: 'quit', listener: (event: Event, + exitCode: number) => void): this; + /** + * Emitted once, when Electron has finished initializing. On macOS, `launchInfo` + * holds the `userInfo` of the `NSUserNotification` or information from + * `UNNotificationResponse` that was used to open the application, if it was + * launched from Notification Center. You can also call `app.isReady()` to check if + * this event has already fired and `app.whenReady()` to get a Promise that is + * fulfilled when Electron is initialized. + */ + on(event: 'ready', listener: (event: Event, + launchInfo: (Record) | (NotificationResponse)) => void): this; + once(event: 'ready', listener: (event: Event, + launchInfo: (Record) | (NotificationResponse)) => void): this; + addListener(event: 'ready', listener: (event: Event, + launchInfo: (Record) | (NotificationResponse)) => void): this; + removeListener(event: 'ready', listener: (event: Event, + launchInfo: (Record) | (NotificationResponse)) => void): this; + /** + * Emitted when `remote.getBuiltin()` is called in the renderer process of + * `webContents`. Calling `event.preventDefault()` will prevent the module from + * being returned. Custom value can be returned by setting `event.returnValue`. + * + * @deprecated + */ + on(event: 'remote-get-builtin', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + once(event: 'remote-get-builtin', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + addListener(event: 'remote-get-builtin', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + removeListener(event: 'remote-get-builtin', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + /** + * Emitted when `remote.getCurrentWebContents()` is called in the renderer process + * of `webContents`. Calling `event.preventDefault()` will prevent the object from + * being returned. Custom value can be returned by setting `event.returnValue`. + * + * @deprecated + */ + on(event: 'remote-get-current-web-contents', listener: (event: Event, + webContents: WebContents) => void): this; + once(event: 'remote-get-current-web-contents', listener: (event: Event, + webContents: WebContents) => void): this; + addListener(event: 'remote-get-current-web-contents', listener: (event: Event, + webContents: WebContents) => void): this; + removeListener(event: 'remote-get-current-web-contents', listener: (event: Event, + webContents: WebContents) => void): this; + /** + * Emitted when `remote.getCurrentWindow()` is called in the renderer process of + * `webContents`. Calling `event.preventDefault()` will prevent the object from + * being returned. Custom value can be returned by setting `event.returnValue`. + * + * @deprecated + */ + on(event: 'remote-get-current-window', listener: (event: Event, + webContents: WebContents) => void): this; + once(event: 'remote-get-current-window', listener: (event: Event, + webContents: WebContents) => void): this; + addListener(event: 'remote-get-current-window', listener: (event: Event, + webContents: WebContents) => void): this; + removeListener(event: 'remote-get-current-window', listener: (event: Event, + webContents: WebContents) => void): this; + /** + * Emitted when `remote.getGlobal()` is called in the renderer process of + * `webContents`. Calling `event.preventDefault()` will prevent the global from + * being returned. Custom value can be returned by setting `event.returnValue`. + * + * @deprecated + */ + on(event: 'remote-get-global', listener: (event: Event, + webContents: WebContents, + globalName: string) => void): this; + once(event: 'remote-get-global', listener: (event: Event, + webContents: WebContents, + globalName: string) => void): this; + addListener(event: 'remote-get-global', listener: (event: Event, + webContents: WebContents, + globalName: string) => void): this; + removeListener(event: 'remote-get-global', listener: (event: Event, + webContents: WebContents, + globalName: string) => void): this; + /** + * Emitted when `remote.require()` is called in the renderer process of + * `webContents`. Calling `event.preventDefault()` will prevent the module from + * being returned. Custom value can be returned by setting `event.returnValue`. + * + * @deprecated + */ + on(event: 'remote-require', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + once(event: 'remote-require', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + addListener(event: 'remote-require', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + removeListener(event: 'remote-require', listener: (event: Event, + webContents: WebContents, + moduleName: string) => void): this; + /** + * Emitted when the renderer process unexpectedly disappears. This is normally + * because it was crashed or killed. + */ + on(event: 'render-process-gone', listener: (event: Event, + webContents: WebContents, + details: RenderProcessGoneDetails) => void): this; + once(event: 'render-process-gone', listener: (event: Event, + webContents: WebContents, + details: RenderProcessGoneDetails) => void): this; + addListener(event: 'render-process-gone', listener: (event: Event, + webContents: WebContents, + details: RenderProcessGoneDetails) => void): this; + removeListener(event: 'render-process-gone', listener: (event: Event, + webContents: WebContents, + details: RenderProcessGoneDetails) => void): this; + /** + * Emitted when the renderer process of `webContents` crashes or is killed. + * + * **Deprecated:** This event is superceded by the `render-process-gone` event + * which contains more information about why the render process disappeared. It + * isn't always because it crashed. The `killed` boolean can be replaced by + * checking `reason === 'killed'` when you switch to that event. + * + * @deprecated + */ + on(event: 'renderer-process-crashed', listener: (event: Event, + webContents: WebContents, + killed: boolean) => void): this; + once(event: 'renderer-process-crashed', listener: (event: Event, + webContents: WebContents, + killed: boolean) => void): this; + addListener(event: 'renderer-process-crashed', listener: (event: Event, + webContents: WebContents, + killed: boolean) => void): this; + removeListener(event: 'renderer-process-crashed', listener: (event: Event, + webContents: WebContents, + killed: boolean) => void): this; + /** + * This event will be emitted inside the primary instance of your application when + * a second instance has been executed and calls `app.requestSingleInstanceLock()`. + * + * `argv` is an Array of the second instance's command line arguments, and + * `workingDirectory` is its current working directory. Usually applications + * respond to this by making their primary window focused and non-minimized. + * + * **Note:** If the second instance is started by a different user than the first, + * the `argv` array will not include the arguments. + * + * This event is guaranteed to be emitted after the `ready` event of `app` gets + * emitted. + * + * **Note:** Extra command line arguments might be added by Chromium, such as + * `--original-process-start-time`. + */ + on(event: 'second-instance', listener: (event: Event, + /** + * An array of the second instance's command line arguments + */ + argv: string[], + /** + * The second instance's working directory + */ + workingDirectory: string) => void): this; + once(event: 'second-instance', listener: (event: Event, + /** + * An array of the second instance's command line arguments + */ + argv: string[], + /** + * The second instance's working directory + */ + workingDirectory: string) => void): this; + addListener(event: 'second-instance', listener: (event: Event, + /** + * An array of the second instance's command line arguments + */ + argv: string[], + /** + * The second instance's working directory + */ + workingDirectory: string) => void): this; + removeListener(event: 'second-instance', listener: (event: Event, + /** + * An array of the second instance's command line arguments + */ + argv: string[], + /** + * The second instance's working directory + */ + workingDirectory: string) => void): this; + /** + * Emitted when a client certificate is requested. + * + * The `url` corresponds to the navigation entry requesting the client certificate + * and `callback` can be called with an entry filtered from the list. Using + * `event.preventDefault()` prevents the application from using the first + * certificate from the store. + */ + on(event: 'select-client-certificate', listener: (event: Event, + webContents: WebContents, + url: string, + certificateList: Certificate[], + callback: (certificate?: Certificate) => void) => void): this; + once(event: 'select-client-certificate', listener: (event: Event, + webContents: WebContents, + url: string, + certificateList: Certificate[], + callback: (certificate?: Certificate) => void) => void): this; + addListener(event: 'select-client-certificate', listener: (event: Event, + webContents: WebContents, + url: string, + certificateList: Certificate[], + callback: (certificate?: Certificate) => void) => void): this; + removeListener(event: 'select-client-certificate', listener: (event: Event, + webContents: WebContents, + url: string, + certificateList: Certificate[], + callback: (certificate?: Certificate) => void) => void): this; + /** + * Emitted when Electron has created a new `session`. + */ + on(event: 'session-created', listener: (session: Session) => void): this; + once(event: 'session-created', listener: (session: Session) => void): this; + addListener(event: 'session-created', listener: (session: Session) => void): this; + removeListener(event: 'session-created', listener: (session: Session) => void): this; + /** + * Emitted when Handoff is about to be resumed on another device. If you need to + * update the state to be transferred, you should call `event.preventDefault()` + * immediately, construct a new `userInfo` dictionary and call + * `app.updateCurrentActivity()` in a timely manner. Otherwise, the operation will + * fail and `continue-activity-error` will be called. + * + * @platform darwin + */ + on(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + once(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + addListener(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + removeListener(event: 'update-activity-state', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string, + /** + * Contains app-specific state stored by the activity. + */ + userInfo: unknown) => void): this; + /** + * Emitted when a new webContents is created. + */ + on(event: 'web-contents-created', listener: (event: Event, + webContents: WebContents) => void): this; + once(event: 'web-contents-created', listener: (event: Event, + webContents: WebContents) => void): this; + addListener(event: 'web-contents-created', listener: (event: Event, + webContents: WebContents) => void): this; + removeListener(event: 'web-contents-created', listener: (event: Event, + webContents: WebContents) => void): this; + /** + * Emitted during Handoff before an activity from a different device wants to be + * resumed. You should call `event.preventDefault()` if you want to handle this + * event. + * + * @platform darwin + */ + on(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string) => void): this; + once(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string) => void): this; + addListener(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string) => void): this; + removeListener(event: 'will-continue-activity', listener: (event: Event, + /** + * A string identifying the activity. Maps to `NSUserActivity.activityType`. + */ + type: string) => void): this; + /** + * Emitted when the application has finished basic startup. On Windows and Linux, + * the `will-finish-launching` event is the same as the `ready` event; on macOS, + * this event represents the `applicationWillFinishLaunching` notification of + * `NSApplication`. You would usually set up listeners for the `open-file` and + * `open-url` events here, and start the crash reporter and auto updater. + * +In most cases, you should do everything in the `ready` event handler. + */ + on(event: 'will-finish-launching', listener: Function): this; + once(event: 'will-finish-launching', listener: Function): this; + addListener(event: 'will-finish-launching', listener: Function): this; + removeListener(event: 'will-finish-launching', listener: Function): this; + /** + * Emitted when all windows have been closed and the application will quit. Calling + * `event.preventDefault()` will prevent the default behavior, which is terminating + * the application. + * + * See the description of the `window-all-closed` event for the differences between + * the `will-quit` and `window-all-closed` events. + * + * **Note:** On Windows, this event will not be emitted if the app is closed due to + * a shutdown/restart of the system or a user logout. + */ + on(event: 'will-quit', listener: (event: Event) => void): this; + once(event: 'will-quit', listener: (event: Event) => void): this; + addListener(event: 'will-quit', listener: (event: Event) => void): this; + removeListener(event: 'will-quit', listener: (event: Event) => void): this; + /** + * Emitted when all windows have been closed. + * + * If you do not subscribe to this event and all windows are closed, the default + * behavior is to quit the app; however, if you subscribe, you control whether the + * app quits or not. If the user pressed `Cmd + Q`, or the developer called + * `app.quit()`, Electron will first try to close all the windows and then emit the + * `will-quit` event, and in this case the `window-all-closed` event would not be + * emitted. + */ + on(event: 'window-all-closed', listener: Function): this; + once(event: 'window-all-closed', listener: Function): this; + addListener(event: 'window-all-closed', listener: Function): this; + removeListener(event: 'window-all-closed', listener: Function): this; + /** + * Adds `path` to the recent documents list. + * + * This list is managed by the OS. On Windows, you can visit the list from the task + * bar, and on macOS, you can visit it from dock menu. + * + * @platform darwin,win32 + */ + addRecentDocument(path: string): void; + /** + * Clears the recent documents list. + * + * @platform darwin,win32 + */ + clearRecentDocuments(): void; + /** + * By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per domain + * basis if the GPU processes crashes too frequently. This function disables that + * behavior. + +This method can only be called before app is ready. + */ + disableDomainBlockingFor3DAPIs(): void; + /** + * Disables hardware acceleration for current app. + * +This method can only be called before app is ready. + */ + disableHardwareAcceleration(): void; + /** + * Enables full sandbox mode on the app. This means that all renderers will be + * launched sandboxed, regardless of the value of the `sandbox` flag in + * WebPreferences. + +This method can only be called before app is ready. + */ + enableSandbox(): void; + /** + * Exits immediately with `exitCode`. `exitCode` defaults to 0. + * + * All windows will be closed immediately without asking the user, and the + * `before-quit` and `will-quit` events will not be emitted. + */ + exit(exitCode?: number): void; + /** + * On Linux, focuses on the first visible window. On macOS, makes the application + * the active app. On Windows, focuses on the application's first window. + * +You should seek to use the `steal` option as sparingly as possible. + */ + focus(options?: FocusOptions): void; + /** + * Resolve with an object containing the following: + * + * * `icon` NativeImage - the display icon of the app handling the protocol. + * * `path` String - installation path of the app handling the protocol. + * * `name` String - display name of the app handling the protocol. + * + * This method returns a promise that contains the application name, icon and path + * of the default handler for the protocol (aka URI scheme) of a URL. + * + * @platform darwin,win32 + */ + getApplicationInfoForProtocol(url: string): Promise; + /** + * Name of the application handling the protocol, or an empty string if there is no + * handler. For instance, if Electron is the default handler of the URL, this could + * be `Electron` on Windows and Mac. However, don't rely on the precise format + * which is not guaranteed to remain unchanged. Expect a different format on Linux, + * possibly with a `.desktop` suffix. + * + * This method returns the application name of the default handler for the protocol + * (aka URI scheme) of a URL. + */ + getApplicationNameForProtocol(url: string): string; + /** + * Array of `ProcessMetric` objects that correspond to memory and CPU usage + * statistics of all the processes associated with the app. + */ + getAppMetrics(): ProcessMetric[]; + /** + * The current application directory. + */ + getAppPath(): string; + /** + * The current value displayed in the counter badge. + * + * @platform linux,darwin + */ + getBadgeCount(): number; + /** + * The type of the currently running activity. + * + * @platform darwin + */ + getCurrentActivityType(): string; + /** + * fulfilled with the app's icon, which is a NativeImage. + * + * Fetches a path's associated icon. + * + * On _Windows_, there a 2 kinds of icons: + * + * * Icons associated with certain file extensions, like `.mp3`, `.png`, etc. + * * Icons inside the file itself, like `.exe`, `.dll`, `.ico`. + * + * On _Linux_ and _macOS_, icons depend on the application associated with file + * mime type. + */ + getFileIcon(path: string, options?: FileIconOptions): Promise; + /** + * The Graphics Feature Status from `chrome://gpu/`. + * + * **Note:** This information is only usable after the `gpu-info-update` event is + * emitted. + */ + getGPUFeatureStatus(): GPUFeatureStatus; + /** + * For `infoType` equal to `complete`: Promise is fulfilled with `Object` + * containing all the GPU Information as in chromium's GPUInfo object. This + * includes the version and driver information that's shown on `chrome://gpu` page. + * + * For `infoType` equal to `basic`: Promise is fulfilled with `Object` containing + * fewer attributes than when requested with `complete`. Here's an example of basic + * response: + * + * Using `basic` should be preferred if only basic information like `vendorId` or + * `driverId` is needed. + */ + getGPUInfo(infoType: 'basic' | 'complete'): Promise; + /** + * * `minItems` Integer - The minimum number of items that will be shown in the + * Jump List (for a more detailed description of this value see the MSDN docs). + * * `removedItems` JumpListItem[] - Array of `JumpListItem` objects that + * correspond to items that the user has explicitly removed from custom categories + * in the Jump List. These items must not be re-added to the Jump List in the + * **next** call to `app.setJumpList()`, Windows will not display any custom + * category that contains any of the removed items. + * + * @platform win32 + */ + getJumpListSettings(): JumpListSettings; + /** + * The current application locale, fetched using Chromium's `l10n_util` library. + * Possible return values are documented here. + * + * To set the locale, you'll want to use a command line switch at app startup, + * which may be found here. + * + * **Note:** When distributing your packaged app, you have to also ship the + * `locales` folder. + * + * **Note:** On Windows, you have to call it after the `ready` events gets emitted. + */ + getLocale(): string; + /** + * User operating system's locale two-letter ISO 3166 country code. The value is + * taken from native OS APIs. + * +**Note:** When unable to detect locale country code, it returns empty string. + */ + getLocaleCountryCode(): string; + /** + * If you provided `path` and `args` options to `app.setLoginItemSettings`, then + * you need to pass the same arguments here for `openAtLogin` to be set correctly. + * + * + * * `openAtLogin` Boolean - `true` if the app is set to open at login. + * * `openAsHidden` Boolean _macOS_ - `true` if the app is set to open as hidden at + * login. This setting is not available on MAS builds. + * * `wasOpenedAtLogin` Boolean _macOS_ - `true` if the app was opened at login + * automatically. This setting is not available on MAS builds. + * * `wasOpenedAsHidden` Boolean _macOS_ - `true` if the app was opened as a hidden + * login item. This indicates that the app should not open any windows at startup. + * This setting is not available on MAS builds. + * * `restoreState` Boolean _macOS_ - `true` if the app was opened as a login item + * that should restore the state from the previous session. This indicates that the + * app should restore the windows that were open the last time the app was closed. + * This setting is not available on MAS builds. + * * `executableWillLaunchAtLogin` Boolean _Windows_ - `true` if app is set to open + * at login and its run key is not deactivated. This differs from `openAtLogin` as + * it ignores the `args` option, this property will be true if the given executable + * would be launched at login with **any** arguments. + * * `launchItems` Object[] _Windows_ + * * `name` String _Windows_ - name value of a registry entry. + * * `path` String _Windows_ - The executable to an app that corresponds to a + * registry entry. + * * `args` String[] _Windows_ - the command-line arguments to pass to the + * executable. + * * `scope` String _Windows_ - one of `user` or `machine`. Indicates whether the + * registry entry is under `HKEY_CURRENT USER` or `HKEY_LOCAL_MACHINE`. + * * `enabled` Boolean _Windows_ - `true` if the app registry key is startup + * approved and therefore shows as `enabled` in Task Manager and Windows settings. + * + * @platform darwin,win32 + */ + getLoginItemSettings(options?: LoginItemSettingsOptions): LoginItemSettings; + /** + * The current application's name, which is the name in the application's + * `package.json` file. + * + * Usually the `name` field of `package.json` is a short lowercase name, according + * to the npm modules spec. You should usually also specify a `productName` field, + * which is your application's full capitalized name, and which will be preferred + * over `name` by Electron. + */ + getName(): string; + /** + * A path to a special directory or file associated with `name`. On failure, an + * `Error` is thrown. + * + * If `app.getPath('logs')` is called without called `app.setAppLogsPath()` being + * called first, a default log directory will be created equivalent to calling + * `app.setAppLogsPath()` without a `path` parameter. + */ + getPath(name: 'home' | 'appData' | 'userData' | 'cache' | 'temp' | 'exe' | 'module' | 'desktop' | 'documents' | 'downloads' | 'music' | 'pictures' | 'videos' | 'recent' | 'logs' | 'crashDumps'): string; + /** + * The version of the loaded application. If no version is found in the + * application's `package.json` file, the version of the current bundle or + * executable is returned. + */ + getVersion(): string; + /** + * This method returns whether or not this instance of your app is currently + * holding the single instance lock. You can request the lock with + * `app.requestSingleInstanceLock()` and release with + * `app.releaseSingleInstanceLock()` + */ + hasSingleInstanceLock(): boolean; + /** + * Hides all application windows without minimizing them. + * + * @platform darwin + */ + hide(): void; + /** + * Imports the certificate in pkcs12 format into the platform certificate store. + * `callback` is called with the `result` of import operation, a value of `0` + * indicates success while any other value indicates failure according to Chromium + * net_error_list. + * + * @platform linux + */ + importCertificate(options: ImportCertificateOptions, callback: (result: number) => void): void; + /** + * Invalidates the current Handoff user activity. + * + * @platform darwin + */ + invalidateCurrentActivity(): void; + /** + * `true` if Chrome's accessibility support is enabled, `false` otherwise. This API + * will return `true` if the use of assistive technologies, such as screen readers, + * has been detected. See + * https://www.chromium.org/developers/design-documents/accessibility for more + * details. + * + * @platform darwin,win32 + */ + isAccessibilitySupportEnabled(): boolean; + /** + * Whether the current executable is the default handler for a protocol (aka URI + * scheme). + * + * **Note:** On macOS, you can use this method to check if the app has been + * registered as the default protocol handler for a protocol. You can also verify + * this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the + * macOS machine. Please refer to Apple's documentation for details. + * + * The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` + * internally. + */ + isDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean; + /** + * whether or not the current OS version allows for native emoji pickers. + */ + isEmojiPanelSupported(): boolean; + /** + * Whether the application is currently running from the systems Application + * folder. Use in combination with `app.moveToApplicationsFolder()` + * + * @platform darwin + */ + isInApplicationsFolder(): boolean; + /** + * `true` if Electron has finished initializing, `false` otherwise. See also + * `app.whenReady()`. + */ + isReady(): boolean; + /** + * whether `Secure Keyboard Entry` is enabled. + * +By default this API will return `false`. + * + * @platform darwin + */ + isSecureKeyboardEntryEnabled(): boolean; + /** + * Whether the current desktop environment is Unity launcher. + * + * @platform linux + */ + isUnityRunning(): boolean; + /** + * Whether the move was successful. Please note that if the move is successful, + * your application will quit and relaunch. + * + * No confirmation dialog will be presented by default. If you wish to allow the + * user to confirm the operation, you may do so using the `dialog` API. + * + * **NOTE:** This method throws errors if anything other than the user causes the + * move to fail. For instance if the user cancels the authorization dialog, this + * method returns false. If we fail to perform the copy, then this method will + * throw an error. The message in the error should be informative and tell you + * exactly what went wrong. + * + * By default, if an app of the same name as the one being moved exists in the + * Applications directory and is _not_ running, the existing app will be trashed + * and the active app moved into its place. If it _is_ running, the pre-existing + * running app will assume focus and the previously active app will quit itself. + * This behavior can be changed by providing the optional conflict handler, where + * the boolean returned by the handler determines whether or not the move conflict + * is resolved with default behavior. i.e. returning `false` will ensure no + * further action is taken, returning `true` will result in the default behavior + * and the method continuing. + * + * For example: + * + * Would mean that if an app already exists in the user directory, if the user + * chooses to 'Continue Move' then the function would continue with its default + * behavior and the existing app will be trashed and the active app moved into its + * place. + * + * @platform darwin + */ + moveToApplicationsFolder(options?: MoveToApplicationsFolderOptions): boolean; + /** + * Try to close all windows. The `before-quit` event will be emitted first. If all + * windows are successfully closed, the `will-quit` event will be emitted and by + * default the application will terminate. + * + * This method guarantees that all `beforeunload` and `unload` event handlers are + * correctly executed. It is possible that a window cancels the quitting by + * returning `false` in the `beforeunload` event handler. + */ + quit(): void; + /** + * Relaunches the app when current instance exits. + * + * By default, the new instance will use the same working directory and command + * line arguments with current instance. When `args` is specified, the `args` will + * be passed as command line arguments instead. When `execPath` is specified, the + * `execPath` will be executed for relaunch instead of current app. + * + * Note that this method does not quit the app when executed, you have to call + * `app.quit` or `app.exit` after calling `app.relaunch` to make the app restart. + * + * When `app.relaunch` is called for multiple times, multiple instances will be + * started after current instance exited. + * + * An example of restarting current instance immediately and adding a new command + * line argument to the new instance: + */ + relaunch(options?: RelaunchOptions): void; + /** + * Releases all locks that were created by `requestSingleInstanceLock`. This will + * allow multiple instances of the application to once again run side by side. + */ + releaseSingleInstanceLock(): void; + /** + * Whether the call succeeded. + * + * This method checks if the current executable as the default handler for a + * protocol (aka URI scheme). If so, it will remove the app as the default handler. + * + * @platform darwin,win32 + */ + removeAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean; + /** + * The return value of this method indicates whether or not this instance of your + * application successfully obtained the lock. If it failed to obtain the lock, + * you can assume that another instance of your application is already running with + * the lock and exit immediately. + * + * I.e. This method returns `true` if your process is the primary instance of your + * application and your app should continue loading. It returns `false` if your + * process should immediately quit as it has sent its parameters to another + * instance that has already acquired the lock. + * + * On macOS, the system enforces single instance automatically when users try to + * open a second instance of your app in Finder, and the `open-file` and `open-url` + * events will be emitted for that. However when users start your app in command + * line, the system's single instance mechanism will be bypassed, and you have to + * use this method to ensure single instance. + * + * An example of activating the window of primary instance when a second instance + * starts: + */ + requestSingleInstanceLock(): boolean; + /** + * Marks the current Handoff user activity as inactive without invalidating it. + * + * @platform darwin + */ + resignCurrentActivity(): void; + /** + * Set the about panel options. This will override the values defined in the app's + * `.plist` file on macOS. See the Apple docs for more details. On Linux, values + * must be set in order to be shown; there are no defaults. + * + * If you do not set `credits` but still wish to surface them in your app, AppKit + * will look for a file named "Credits.html", "Credits.rtf", and "Credits.rtfd", in + * that order, in the bundle returned by the NSBundle class method main. The first + * file found is used, and if none is found, the info area is left blank. See Apple + * documentation for more information. + */ + setAboutPanelOptions(options: AboutPanelOptionsOptions): void; + /** + * Manually enables Chrome's accessibility support, allowing to expose + * accessibility switch to users in application settings. See Chromium's + * accessibility docs for more details. Disabled by default. + * + * This API must be called after the `ready` event is emitted. + * + * **Note:** Rendering accessibility tree can significantly affect the performance + * of your app. It should not be enabled by default. + * + * @platform darwin,win32 + */ + setAccessibilitySupportEnabled(enabled: boolean): void; + /** + * Sets the activation policy for a given app. + * + * Activation policy types: + * + * * 'regular' - The application is an ordinary app that appears in the Dock and + * may have a user interface. + * * 'accessory' - The application doesn’t appear in the Dock and doesn’t have a + * menu bar, but it may be activated programmatically or by clicking on one of its + * windows. + * * 'prohibited' - The application doesn’t appear in the Dock and may not create + * windows or be activated. + * + * @platform darwin + */ + setActivationPolicy(policy: 'regular' | 'accessory' | 'prohibited'): void; + /** + * Sets or creates a directory your app's logs which can then be manipulated with + * `app.getPath()` or `app.setPath(pathName, newPath)`. + * + * Calling `app.setAppLogsPath()` without a `path` parameter will result in this + * directory being set to `~/Library/Logs/YourAppName` on _macOS_, and inside the + * `userData` directory on _Linux_ and _Windows_. + */ + setAppLogsPath(path?: string): void; + /** + * Changes the Application User Model ID to `id`. + * + * @platform win32 + */ + setAppUserModelId(id: string): void; + /** + * Whether the call succeeded. + * + * Sets the current executable as the default handler for a protocol (aka URI + * scheme). It allows you to integrate your app deeper into the operating system. + * Once registered, all links with `your-protocol://` will be opened with the + * current executable. The whole link, including protocol, will be passed to your + * application as a parameter. + * + * **Note:** On macOS, you can only register protocols that have been added to your + * app's `info.plist`, which cannot be modified at runtime. However, you can change + * the file during build time via Electron Forge, Electron Packager, or by editing + * `info.plist` with a text editor. Please refer to Apple's documentation for + * details. + * + * **Note:** In a Windows Store environment (when packaged as an `appx`) this API + * will return `true` for all calls but the registry key it sets won't be + * accessible by other applications. In order to register your Windows Store + * application as a default protocol handler you must declare the protocol in your + * manifest. + * + * The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` + * internally. + */ + setAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean; + /** + * Whether the call succeeded. + * + * Sets the counter badge for current app. Setting the count to `0` will hide the + * badge. + * + * On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher. + * + * **Note:** Unity launcher requires the existence of a `.desktop` file to work, + * for more information please read Desktop Environment Integration. + * + * @platform linux,darwin + */ + setBadgeCount(count?: number): boolean; + /** + * Sets or removes a custom Jump List for the application, and returns one of the + * following strings: + * + * * `ok` - Nothing went wrong. + * * `error` - One or more errors occurred, enable runtime logging to figure out + * the likely cause. + * * `invalidSeparatorError` - An attempt was made to add a separator to a custom + * category in the Jump List. Separators are only allowed in the standard `Tasks` + * category. + * * `fileTypeRegistrationError` - An attempt was made to add a file link to the + * Jump List for a file type the app isn't registered to handle. + * * `customCategoryAccessDeniedError` - Custom categories can't be added to the + * Jump List due to user privacy or group policy settings. + * + * If `categories` is `null` the previously set custom Jump List (if any) will be + * replaced by the standard Jump List for the app (managed by Windows). + * + * **Note:** If a `JumpListCategory` object has neither the `type` nor the `name` + * property set then its `type` is assumed to be `tasks`. If the `name` property is + * set but the `type` property is omitted then the `type` is assumed to be + * `custom`. + * + * **Note:** Users can remove items from custom categories, and Windows will not + * allow a removed item to be added back into a custom category until **after** the + * next successful call to `app.setJumpList(categories)`. Any attempt to re-add a + * removed item to a custom category earlier than that will result in the entire + * custom category being omitted from the Jump List. The list of removed items can + * be obtained using `app.getJumpListSettings()`. + * + * **Note:** The maximum length of a Jump List item's `description` property is 260 + * characters. Beyond this limit, the item will not be added to the Jump List, nor + * will it be displayed. + * +Here's a very simple example of creating a custom Jump List: + * + * @platform win32 + */ + setJumpList(categories: (JumpListCategory[]) | (null)): void; + /** + * To work with Electron's `autoUpdater` on Windows, which uses Squirrel, you'll + * want to set the launch path to Update.exe, and pass arguments that specify your + * application name. For example: + * + * @platform darwin,win32 + */ + setLoginItemSettings(settings: Settings): void; + /** + * Overrides the current application's name. + * + * **Note:** This function overrides the name used internally by Electron; it does + * not affect the name that the OS uses. + */ + setName(name: string): void; + /** + * Overrides the `path` to a special directory or file associated with `name`. If + * the path specifies a directory that does not exist, an `Error` is thrown. In + * that case, the directory should be created with `fs.mkdirSync` or similar. + * + * You can only override paths of a `name` defined in `app.getPath`. + * + * By default, web pages' cookies and caches will be stored under the `userData` + * directory. If you want to change this location, you have to override the + * `userData` path before the `ready` event of the `app` module is emitted. + */ + setPath(name: string, path: string): void; + /** + * Set the `Secure Keyboard Entry` is enabled in your application. + * + * By using this API, important information such as password and other sensitive + * information can be prevented from being intercepted by other processes. + * + * See Apple's documentation for more details. + * + * **Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it + * when it is no longer needed. + * + * @platform darwin + */ + setSecureKeyboardEntryEnabled(enabled: boolean): void; + /** + * Creates an `NSUserActivity` and sets it as the current activity. The activity is + * eligible for Handoff to another device afterward. + * + * @platform darwin + */ + setUserActivity(type: string, userInfo: any, webpageURL?: string): void; + /** + * Adds `tasks` to the Tasks category of the Jump List on Windows. + * + * `tasks` is an array of `Task` objects. + * + * Whether the call succeeded. + * + * **Note:** If you'd like to customize the Jump List even more use + * `app.setJumpList(categories)` instead. + * + * @platform win32 + */ + setUserTasks(tasks: Task[]): boolean; + /** + * Shows application windows after they were hidden. Does not automatically focus + * them. + * + * @platform darwin + */ + show(): void; + /** + * Show the app's about panel options. These options can be overridden with + * `app.setAboutPanelOptions(options)`. + */ + showAboutPanel(): void; + /** + * Show the platform's native emoji picker. + * + * @platform darwin,win32 + */ + showEmojiPanel(): void; + /** + * This function **must** be called once you have finished accessing the security + * scoped file. If you do not remember to stop accessing the bookmark, kernel + * resources will be leaked and your app will lose its ability to reach outside the + * sandbox completely, until your app is restarted. + * + * Start accessing a security scoped resource. With this method Electron + * applications that are packaged for the Mac App Store may reach outside their + * sandbox to access files chosen by the user. See Apple's documentation for a + * description of how this system works. + * + * @platform mas + */ + startAccessingSecurityScopedResource(bookmarkData: string): Function; + /** + * Updates the current activity if its type matches `type`, merging the entries + * from `userInfo` into its current `userInfo` dictionary. + * + * @platform darwin + */ + updateCurrentActivity(type: string, userInfo: any): void; + /** + * fulfilled when Electron is initialized. May be used as a convenient alternative + * to checking `app.isReady()` and subscribing to the `ready` event if the app is + * not ready yet. + */ + whenReady(): Promise; + /** + * A `Boolean` property that's `true` if Chrome's accessibility support is enabled, + * `false` otherwise. This property will be `true` if the use of assistive + * technologies, such as screen readers, has been detected. Setting this property + * to `true` manually enables Chrome's accessibility support, allowing developers + * to expose accessibility switch to users in application settings. + * + * See Chromium's accessibility docs for more details. Disabled by default. + * + * This API must be called after the `ready` event is emitted. + * + * **Note:** Rendering accessibility tree can significantly affect the performance + * of your app. It should not be enabled by default. + * + * @platform darwin,win32 + */ + accessibilitySupportEnabled: boolean; + /** + * A `Boolean` which when `true` disables the overrides that Electron has in place + * to ensure renderer processes are restarted on every navigation. The current + * default value for this property is `true`. + * + * The intention is for these overrides to become disabled by default and then at + * some point in the future this property will be removed. This property impacts + * which native modules you can use in the renderer process. For more information + * on the direction Electron is going with renderer process restarts and usage of + * native modules in the renderer process please check out this Tracking Issue. + */ + allowRendererProcessReuse: boolean; + /** + * A `Menu | null` property that returns `Menu` if one has been set and `null` + * otherwise. Users can pass a Menu to set this property. + */ + applicationMenu: (Menu) | (null); + /** + * An `Integer` property that returns the badge count for current app. Setting the + * count to `0` will hide the badge. + * + * On macOS, setting this with any nonzero integer shows on the dock icon. On + * Linux, this property only works for Unity launcher. + * + * **Note:** Unity launcher requires the existence of a `.desktop` file to work, + * for more information please read Desktop Environment Integration. + * + * **Note:** On macOS, you need to ensure that your application has the permission + * to display notifications for this property to take effect. + * + * @platform linux,darwin + */ + badgeCount: number; + /** + * A `CommandLine` object that allows you to read and manipulate the command line + * arguments that Chromium uses. + * + */ + readonly commandLine: CommandLine; + /** + * A `Dock` `| undefined` object that allows you to perform actions on your app + * icon in the user's dock on macOS. + * + * @platform darwin + */ + readonly dock: Dock; + /** + * A `Boolean` property that returns `true` if the app is packaged, `false` + * otherwise. For many apps, this property can be used to distinguish development + * and production environments. + * + */ + readonly isPackaged: boolean; + /** + * A `String` property that indicates the current application's name, which is the + * name in the application's `package.json` file. + * + * Usually the `name` field of `package.json` is a short lowercase name, according + * to the npm modules spec. You should usually also specify a `productName` field, + * which is your application's full capitalized name, and which will be preferred + * over `name` by Electron. + */ + name: string; + /** + * A `Boolean` which when `true` indicates that the app is currently running under + * the Rosetta Translator Environment. + * + * You can use this property to prompt users to download the arm64 version of your + * application when they are running the x64 version under Rosetta incorrectly. + * + * @platform darwin + */ + readonly runningUnderRosettaTranslation: boolean; + /** + * A `String` which is the user agent string Electron will use as a global + * fallback. + * + * This is the user agent that will be used when no user agent is set at the + * `webContents` or `session` level. It is useful for ensuring that your entire + * app has the same user agent. Set to a custom value as early as possible in your + * app's initialization to ensure that your overridden value is used. + */ + userAgentFallback: string; + } + + interface AutoUpdater extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/auto-updater + + /** + * This event is emitted after a user calls `quitAndInstall()`. + * + * When this API is called, the `before-quit` event is not emitted before all + * windows are closed. As a result you should listen to this event if you wish to + * perform actions before the windows are closed while a process is quitting, as + * well as listening to `before-quit`. + */ + on(event: 'before-quit-for-update', listener: Function): this; + once(event: 'before-quit-for-update', listener: Function): this; + addListener(event: 'before-quit-for-update', listener: Function): this; + removeListener(event: 'before-quit-for-update', listener: Function): this; + /** + * Emitted when checking if an update has started. + */ + on(event: 'checking-for-update', listener: Function): this; + once(event: 'checking-for-update', listener: Function): this; + addListener(event: 'checking-for-update', listener: Function): this; + removeListener(event: 'checking-for-update', listener: Function): this; + /** + * Emitted when there is an error while updating. + */ + on(event: 'error', listener: (error: Error) => void): this; + once(event: 'error', listener: (error: Error) => void): this; + addListener(event: 'error', listener: (error: Error) => void): this; + removeListener(event: 'error', listener: (error: Error) => void): this; + /** + * Emitted when there is an available update. The update is downloaded + * automatically. + */ + on(event: 'update-available', listener: Function): this; + once(event: 'update-available', listener: Function): this; + addListener(event: 'update-available', listener: Function): this; + removeListener(event: 'update-available', listener: Function): this; + /** + * Emitted when an update has been downloaded. + * + * On Windows only `releaseName` is available. + * + * **Note:** It is not strictly necessary to handle this event. A successfully + * downloaded update will still be applied the next time the application starts. + */ + on(event: 'update-downloaded', listener: (event: Event, + releaseNotes: string, + releaseName: string, + releaseDate: Date, + updateURL: string) => void): this; + once(event: 'update-downloaded', listener: (event: Event, + releaseNotes: string, + releaseName: string, + releaseDate: Date, + updateURL: string) => void): this; + addListener(event: 'update-downloaded', listener: (event: Event, + releaseNotes: string, + releaseName: string, + releaseDate: Date, + updateURL: string) => void): this; + removeListener(event: 'update-downloaded', listener: (event: Event, + releaseNotes: string, + releaseName: string, + releaseDate: Date, + updateURL: string) => void): this; + /** + * Emitted when there is no available update. + */ + on(event: 'update-not-available', listener: Function): this; + once(event: 'update-not-available', listener: Function): this; + addListener(event: 'update-not-available', listener: Function): this; + removeListener(event: 'update-not-available', listener: Function): this; + /** + * Asks the server whether there is an update. You must call `setFeedURL` before + * using this API. + */ + checkForUpdates(): void; + /** + * The current update feed URL. + */ + getFeedURL(): string; + /** + * Restarts the app and installs the update after it has been downloaded. It should + * only be called after `update-downloaded` has been emitted. + * + * Under the hood calling `autoUpdater.quitAndInstall()` will close all application + * windows first, and automatically call `app.quit()` after all windows have been + * closed. + * + * **Note:** It is not strictly necessary to call this function to apply an update, + * as a successfully downloaded update will always be applied the next time the + * application starts. + */ + quitAndInstall(): void; + /** + * Sets the `url` and initialize the auto updater. + */ + setFeedURL(options: FeedURLOptions): void; + } + + interface BluetoothDevice { + + // Docs: https://electronjs.org/docs/api/structures/bluetooth-device + + deviceId: string; + deviceName: string; + } + + class BrowserView { + + // Docs: https://electronjs.org/docs/api/browser-view + + /** + * BrowserView + */ + constructor(options?: BrowserViewConstructorOptions); + /** + * The `bounds` of this BrowserView instance as `Object`. + * + * @experimental + */ + getBounds(): Rectangle; + setAutoResize(options: AutoResizeOptions): void; + setBackgroundColor(color: string): void; + /** + * Resizes and moves the view to the supplied bounds relative to the window. + * + * @experimental + */ + setBounds(bounds: Rectangle): void; + webContents: WebContents; + } + + class BrowserWindow extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/browser-window + + /** + * Emitted when the window is set or unset to show always on top of other windows. + */ + on(event: 'always-on-top-changed', listener: (event: Event, + isAlwaysOnTop: boolean) => void): this; + once(event: 'always-on-top-changed', listener: (event: Event, + isAlwaysOnTop: boolean) => void): this; + addListener(event: 'always-on-top-changed', listener: (event: Event, + isAlwaysOnTop: boolean) => void): this; + removeListener(event: 'always-on-top-changed', listener: (event: Event, + isAlwaysOnTop: boolean) => void): this; + /** + * Emitted when an App Command is invoked. These are typically related to keyboard + * media keys or browser commands, as well as the "Back" button built into some + * mice on Windows. + * + * Commands are lowercased, underscores are replaced with hyphens, and the + * `APPCOMMAND_` prefix is stripped off. e.g. `APPCOMMAND_BROWSER_BACKWARD` is + * emitted as `browser-backward`. + * + * The following app commands are explicitly supported on Linux: + * +* `browser-backward` +* `browser-forward` + * + * @platform win32,linux + */ + on(event: 'app-command', listener: (event: Event, + command: string) => void): this; + once(event: 'app-command', listener: (event: Event, + command: string) => void): this; + addListener(event: 'app-command', listener: (event: Event, + command: string) => void): this; + removeListener(event: 'app-command', listener: (event: Event, + command: string) => void): this; + /** + * Emitted when the window loses focus. + */ + on(event: 'blur', listener: Function): this; + once(event: 'blur', listener: Function): this; + addListener(event: 'blur', listener: Function): this; + removeListener(event: 'blur', listener: Function): this; + /** + * Emitted when the window is going to be closed. It's emitted before the + * `beforeunload` and `unload` event of the DOM. Calling `event.preventDefault()` + * will cancel the close. + * + * Usually you would want to use the `beforeunload` handler to decide whether the + * window should be closed, which will also be called when the window is reloaded. + * In Electron, returning any value other than `undefined` would cancel the close. + * For example: + * + * _**Note**: There is a subtle difference between the behaviors of + * `window.onbeforeunload = handler` and `window.addEventListener('beforeunload', + * handler)`. It is recommended to always set the `event.returnValue` explicitly, + * instead of only returning a value, as the former works more consistently within + * Electron._ + */ + on(event: 'close', listener: (event: Event) => void): this; + once(event: 'close', listener: (event: Event) => void): this; + addListener(event: 'close', listener: (event: Event) => void): this; + removeListener(event: 'close', listener: (event: Event) => void): this; + /** + * Emitted when the window is closed. After you have received this event you should + * remove the reference to the window and avoid using it any more. + */ + on(event: 'closed', listener: Function): this; + once(event: 'closed', listener: Function): this; + addListener(event: 'closed', listener: Function): this; + removeListener(event: 'closed', listener: Function): this; + /** + * Emitted when the window enters a full-screen state. + */ + on(event: 'enter-full-screen', listener: Function): this; + once(event: 'enter-full-screen', listener: Function): this; + addListener(event: 'enter-full-screen', listener: Function): this; + removeListener(event: 'enter-full-screen', listener: Function): this; + /** + * Emitted when the window enters a full-screen state triggered by HTML API. + */ + on(event: 'enter-html-full-screen', listener: Function): this; + once(event: 'enter-html-full-screen', listener: Function): this; + addListener(event: 'enter-html-full-screen', listener: Function): this; + removeListener(event: 'enter-html-full-screen', listener: Function): this; + /** + * Emitted when the window gains focus. + */ + on(event: 'focus', listener: Function): this; + once(event: 'focus', listener: Function): this; + addListener(event: 'focus', listener: Function): this; + removeListener(event: 'focus', listener: Function): this; + /** + * Emitted when the window is hidden. + */ + on(event: 'hide', listener: Function): this; + once(event: 'hide', listener: Function): this; + addListener(event: 'hide', listener: Function): this; + removeListener(event: 'hide', listener: Function): this; + /** + * Emitted when the window leaves a full-screen state. + */ + on(event: 'leave-full-screen', listener: Function): this; + once(event: 'leave-full-screen', listener: Function): this; + addListener(event: 'leave-full-screen', listener: Function): this; + removeListener(event: 'leave-full-screen', listener: Function): this; + /** + * Emitted when the window leaves a full-screen state triggered by HTML API. + */ + on(event: 'leave-html-full-screen', listener: Function): this; + once(event: 'leave-html-full-screen', listener: Function): this; + addListener(event: 'leave-html-full-screen', listener: Function): this; + removeListener(event: 'leave-html-full-screen', listener: Function): this; + /** + * Emitted when window is maximized. + */ + on(event: 'maximize', listener: Function): this; + once(event: 'maximize', listener: Function): this; + addListener(event: 'maximize', listener: Function): this; + removeListener(event: 'maximize', listener: Function): this; + /** + * Emitted when the window is minimized. + */ + on(event: 'minimize', listener: Function): this; + once(event: 'minimize', listener: Function): this; + addListener(event: 'minimize', listener: Function): this; + removeListener(event: 'minimize', listener: Function): this; + /** + * Emitted when the window is being moved to a new position. + */ + on(event: 'move', listener: Function): this; + once(event: 'move', listener: Function): this; + addListener(event: 'move', listener: Function): this; + removeListener(event: 'move', listener: Function): this; + /** + * Emitted once when the window is moved to a new position. + * +__Note__: On macOS this event is an alias of `move`. + * + * @platform darwin,win32 + */ + on(event: 'moved', listener: Function): this; + once(event: 'moved', listener: Function): this; + addListener(event: 'moved', listener: Function): this; + removeListener(event: 'moved', listener: Function): this; + /** + * Emitted when the native new tab button is clicked. + * + * @platform darwin + */ + on(event: 'new-window-for-tab', listener: Function): this; + once(event: 'new-window-for-tab', listener: Function): this; + addListener(event: 'new-window-for-tab', listener: Function): this; + removeListener(event: 'new-window-for-tab', listener: Function): this; + /** + * Emitted when the document changed its title, calling `event.preventDefault()` + * will prevent the native window's title from changing. `explicitSet` is false + * when title is synthesized from file URL. + */ + on(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + once(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + addListener(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + removeListener(event: 'page-title-updated', listener: (event: Event, + title: string, + explicitSet: boolean) => void): this; + /** + * Emitted when the web page has been rendered (while not being shown) and window + * can be displayed without a visual flash. + * + * Please note that using this event implies that the renderer will be considered + * "visible" and paint even though `show` is false. This event will never fire if + * you use `paintWhenInitiallyHidden: false` + */ + on(event: 'ready-to-show', listener: Function): this; + once(event: 'ready-to-show', listener: Function): this; + addListener(event: 'ready-to-show', listener: Function): this; + removeListener(event: 'ready-to-show', listener: Function): this; + /** + * Emitted after the window has been resized. + */ + on(event: 'resize', listener: Function): this; + once(event: 'resize', listener: Function): this; + addListener(event: 'resize', listener: Function): this; + removeListener(event: 'resize', listener: Function): this; + /** + * Emitted once when the window has finished being resized. + * + * This is usually emitted when the window has been resized manually. On macOS, + * resizing the window with `setBounds`/`setSize` and setting the `animate` + * parameter to `true` will also emit this event once resizing has finished. + * + * @platform darwin,win32 + */ + on(event: 'resized', listener: Function): this; + once(event: 'resized', listener: Function): this; + addListener(event: 'resized', listener: Function): this; + removeListener(event: 'resized', listener: Function): this; + /** + * Emitted when the unresponsive web page becomes responsive again. + */ + on(event: 'responsive', listener: Function): this; + once(event: 'responsive', listener: Function): this; + addListener(event: 'responsive', listener: Function): this; + removeListener(event: 'responsive', listener: Function): this; + /** + * Emitted when the window is restored from a minimized state. + */ + on(event: 'restore', listener: Function): this; + once(event: 'restore', listener: Function): this; + addListener(event: 'restore', listener: Function): this; + removeListener(event: 'restore', listener: Function): this; + /** + * Emitted on trackpad rotation gesture. Continually emitted until rotation gesture + * is ended. The `rotation` value on each emission is the angle in degrees rotated + * since the last emission. The last emitted event upon a rotation gesture will + * always be of value `0`. Counter-clockwise rotation values are positive, while + * clockwise ones are negative. + * + * @platform darwin + */ + on(event: 'rotate-gesture', listener: (event: Event, + rotation: number) => void): this; + once(event: 'rotate-gesture', listener: (event: Event, + rotation: number) => void): this; + addListener(event: 'rotate-gesture', listener: (event: Event, + rotation: number) => void): this; + removeListener(event: 'rotate-gesture', listener: (event: Event, + rotation: number) => void): this; + /** + * Emitted when scroll wheel event phase has begun. + * + * @platform darwin + */ + on(event: 'scroll-touch-begin', listener: Function): this; + once(event: 'scroll-touch-begin', listener: Function): this; + addListener(event: 'scroll-touch-begin', listener: Function): this; + removeListener(event: 'scroll-touch-begin', listener: Function): this; + /** + * Emitted when scroll wheel event phase filed upon reaching the edge of element. + * + * @platform darwin + */ + on(event: 'scroll-touch-edge', listener: Function): this; + once(event: 'scroll-touch-edge', listener: Function): this; + addListener(event: 'scroll-touch-edge', listener: Function): this; + removeListener(event: 'scroll-touch-edge', listener: Function): this; + /** + * Emitted when scroll wheel event phase has ended. + * + * @platform darwin + */ + on(event: 'scroll-touch-end', listener: Function): this; + once(event: 'scroll-touch-end', listener: Function): this; + addListener(event: 'scroll-touch-end', listener: Function): this; + removeListener(event: 'scroll-touch-end', listener: Function): this; + /** + * Emitted when window session is going to end due to force shutdown or machine + * restart or session log off. + * + * @platform win32 + */ + on(event: 'session-end', listener: Function): this; + once(event: 'session-end', listener: Function): this; + addListener(event: 'session-end', listener: Function): this; + removeListener(event: 'session-end', listener: Function): this; + /** + * Emitted when the window opens a sheet. + * + * @platform darwin + */ + on(event: 'sheet-begin', listener: Function): this; + once(event: 'sheet-begin', listener: Function): this; + addListener(event: 'sheet-begin', listener: Function): this; + removeListener(event: 'sheet-begin', listener: Function): this; + /** + * Emitted when the window has closed a sheet. + * + * @platform darwin + */ + on(event: 'sheet-end', listener: Function): this; + once(event: 'sheet-end', listener: Function): this; + addListener(event: 'sheet-end', listener: Function): this; + removeListener(event: 'sheet-end', listener: Function): this; + /** + * Emitted when the window is shown. + */ + on(event: 'show', listener: Function): this; + once(event: 'show', listener: Function): this; + addListener(event: 'show', listener: Function): this; + removeListener(event: 'show', listener: Function): this; + /** + * Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, + * `left`. + * + * The method underlying this event is built to handle older macOS-style trackpad + * swiping, where the content on the screen doesn't move with the swipe. Most macOS + * trackpads are not configured to allow this kind of swiping anymore, so in order + * for it to emit properly the 'Swipe between pages' preference in `System + * Preferences > Trackpad > More Gestures` must be set to 'Swipe with two or three + * fingers'. + * + * @platform darwin + */ + on(event: 'swipe', listener: (event: Event, + direction: string) => void): this; + once(event: 'swipe', listener: (event: Event, + direction: string) => void): this; + addListener(event: 'swipe', listener: (event: Event, + direction: string) => void): this; + removeListener(event: 'swipe', listener: (event: Event, + direction: string) => void): this; + /** + * Emitted when the system context menu is triggered on the window, this is + * normally only triggered when the user right clicks on the non-client area of + * your window. This is the window titlebar or any area you have declared as + * `-webkit-app-region: drag` in a frameless window. + * +Calling `event.preventDefault()` will prevent the menu from being displayed. + * + * @platform win32 + */ + on(event: 'system-context-menu', listener: (event: Event, + /** + * The screen coordinates the context menu was triggered at + */ + point: Point) => void): this; + once(event: 'system-context-menu', listener: (event: Event, + /** + * The screen coordinates the context menu was triggered at + */ + point: Point) => void): this; + addListener(event: 'system-context-menu', listener: (event: Event, + /** + * The screen coordinates the context menu was triggered at + */ + point: Point) => void): this; + removeListener(event: 'system-context-menu', listener: (event: Event, + /** + * The screen coordinates the context menu was triggered at + */ + point: Point) => void): this; + /** + * Emitted when the window exits from a maximized state. + */ + on(event: 'unmaximize', listener: Function): this; + once(event: 'unmaximize', listener: Function): this; + addListener(event: 'unmaximize', listener: Function): this; + removeListener(event: 'unmaximize', listener: Function): this; + /** + * Emitted when the web page becomes unresponsive. + */ + on(event: 'unresponsive', listener: Function): this; + once(event: 'unresponsive', listener: Function): this; + addListener(event: 'unresponsive', listener: Function): this; + removeListener(event: 'unresponsive', listener: Function): this; + /** + * Emitted before the window is moved. On Windows, calling `event.preventDefault()` + * will prevent the window from being moved. + * + * Note that this is only emitted when the window is being resized manually. + * Resizing the window with `setBounds`/`setSize` will not emit this event. + * + * @platform darwin,win32 + */ + on(event: 'will-move', listener: (event: Event, + /** + * Location the window is being moved to. + */ + newBounds: Rectangle) => void): this; + once(event: 'will-move', listener: (event: Event, + /** + * Location the window is being moved to. + */ + newBounds: Rectangle) => void): this; + addListener(event: 'will-move', listener: (event: Event, + /** + * Location the window is being moved to. + */ + newBounds: Rectangle) => void): this; + removeListener(event: 'will-move', listener: (event: Event, + /** + * Location the window is being moved to. + */ + newBounds: Rectangle) => void): this; + /** + * Emitted before the window is resized. Calling `event.preventDefault()` will + * prevent the window from being resized. + * + * Note that this is only emitted when the window is being resized manually. + * Resizing the window with `setBounds`/`setSize` will not emit this event. + * + * @platform darwin,win32 + */ + on(event: 'will-resize', listener: (event: Event, + /** + * Size the window is being resized to. + */ + newBounds: Rectangle) => void): this; + once(event: 'will-resize', listener: (event: Event, + /** + * Size the window is being resized to. + */ + newBounds: Rectangle) => void): this; + addListener(event: 'will-resize', listener: (event: Event, + /** + * Size the window is being resized to. + */ + newBounds: Rectangle) => void): this; + removeListener(event: 'will-resize', listener: (event: Event, + /** + * Size the window is being resized to. + */ + newBounds: Rectangle) => void): this; + /** + * BrowserWindow + */ + constructor(options?: BrowserWindowConstructorOptions); + /** + * The window that owns the given `browserView`. If the given view is not attached + * to any window, returns `null`. + */ + static fromBrowserView(browserView: BrowserView): (BrowserWindow) | (null); + /** + * The window with the given `id`. + */ + static fromId(id: number): (BrowserWindow) | (null); + /** + * The window that owns the given `webContents` or `null` if the contents are not + * owned by a window. + */ + static fromWebContents(webContents: WebContents): (BrowserWindow) | (null); + /** + * An array of all opened browser windows. + */ + static getAllWindows(): BrowserWindow[]; + /** + * The window that is focused in this application, otherwise returns `null`. + */ + static getFocusedWindow(): (BrowserWindow) | (null); + /** + * Replacement API for setBrowserView supporting work with multi browser views. + * + * @experimental + */ + addBrowserView(browserView: BrowserView): void; + /** + * Adds a window as a tab on this window, after the tab for the window instance. + * + * @platform darwin + */ + addTabbedWindow(browserWindow: BrowserWindow): void; + /** + * Removes focus from the window. + */ + blur(): void; + blurWebView(): void; + /** + * Resolves with a NativeImage + * + * Captures a snapshot of the page within `rect`. Omitting `rect` will capture the + * whole visible page. If the page is not visible, `rect` may be empty. + */ + capturePage(rect?: Rectangle): Promise; + /** + * Moves window to the center of the screen. + */ + center(): void; + /** + * Try to close the window. This has the same effect as a user manually clicking + * the close button of the window. The web page may cancel the close though. See + * the close event. + */ + close(): void; + /** + * Closes the currently open Quick Look panel. + * + * @platform darwin + */ + closeFilePreview(): void; + /** + * Force closing the window, the `unload` and `beforeunload` event won't be emitted + * for the web page, and `close` event will also not be emitted for this window, + * but it guarantees the `closed` event will be emitted. + */ + destroy(): void; + /** + * Starts or stops flashing the window to attract user's attention. + */ + flashFrame(flag: boolean): void; + /** + * Focuses on the window. + */ + focus(): void; + focusOnWebView(): void; + /** + * Gets the background color of the window. See Setting `backgroundColor`. + */ + getBackgroundColor(): string; + /** + * The `bounds` of the window as `Object`. + */ + getBounds(): Rectangle; + /** + * The `BrowserView` attached to `win`. Returns `null` if one is not attached. + * Throws an error if multiple `BrowserView`s are attached. + * + * @experimental + */ + getBrowserView(): (BrowserView) | (null); + /** + * an array of all BrowserViews that have been attached with `addBrowserView` or + * `setBrowserView`. + * + * **Note:** The BrowserView API is currently experimental and may change or be + * removed in future Electron releases. + * + * @experimental + */ + getBrowserViews(): BrowserView[]; + /** + * All child windows. + */ + getChildWindows(): BrowserWindow[]; + /** + * The `bounds` of the window's client area as `Object`. + */ + getContentBounds(): Rectangle; + /** + * Contains the window's client area's width and height. + */ + getContentSize(): number[]; + /** + * Contains the window's maximum width and height. + */ + getMaximumSize(): number[]; + /** + * Window id in the format of DesktopCapturerSource's id. For example + * "window:1324:0". + * + * More precisely the format is `window:id:other_id` where `id` is `HWND` on + * Windows, `CGWindowID` (`uint64_t`) on macOS and `Window` (`unsigned long`) on + * Linux. `other_id` is used to identify web contents (tabs) so within the same top + * level window. + */ + getMediaSourceId(): string; + /** + * Contains the window's minimum width and height. + */ + getMinimumSize(): number[]; + /** + * The platform-specific handle of the window. + * + * The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and + * `Window` (`unsigned long`) on Linux. + */ + getNativeWindowHandle(): Buffer; + /** + * Contains the window bounds of the normal state + * + * **Note:** whatever the current state of the window : maximized, minimized or in + * fullscreen, this function always returns the position and size of the window in + * normal state. In normal state, getBounds and getNormalBounds returns the same + * `Rectangle`. + */ + getNormalBounds(): Rectangle; + /** + * between 0.0 (fully transparent) and 1.0 (fully opaque). On Linux, always returns + * 1. + */ + getOpacity(): number; + /** + * The parent window. + */ + getParentWindow(): BrowserWindow; + /** + * Contains the window's current position. + */ + getPosition(): number[]; + /** + * The pathname of the file the window represents. + * + * @platform darwin + */ + getRepresentedFilename(): string; + /** + * Contains the window's width and height. + */ + getSize(): number[]; + /** + * The title of the native window. + * + * **Note:** The title of the web page can be different from the title of the + * native window. + */ + getTitle(): string; + /** + * The custom position for the traffic light buttons in frameless window. + * + * @platform darwin + */ + getTrafficLightPosition(): Point; + /** + * Whether the window has a shadow. + */ + hasShadow(): boolean; + /** + * Hides the window. + */ + hide(): void; + /** + * Hooks a windows message. The `callback` is called when the message is received + * in the WndProc. + * + * @platform win32 + */ + hookWindowMessage(message: number, callback: (wParam: any, lParam: any) => void): void; + /** + * Whether the window is always on top of other windows. + */ + isAlwaysOnTop(): boolean; + /** + * Whether the window can be manually closed by user. + * +On Linux always returns `true`. + * + * @platform darwin,win32 + */ + isClosable(): boolean; + /** + * Whether the window is destroyed. + */ + isDestroyed(): boolean; + /** + * Whether the window's document has been edited. + * + * @platform darwin + */ + isDocumentEdited(): boolean; + /** + * whether the window is enabled. + */ + isEnabled(): boolean; + /** + * Whether the window is focused. + */ + isFocused(): boolean; + /** + * Whether the window is in fullscreen mode. + */ + isFullScreen(): boolean; + /** + * Whether the maximize/zoom window button toggles fullscreen mode or maximizes the + * window. + */ + isFullScreenable(): boolean; + /** + * Whether the window is in kiosk mode. + */ + isKiosk(): boolean; + /** + * Whether the window can be manually maximized by user. + * +On Linux always returns `true`. + * + * @platform darwin,win32 + */ + isMaximizable(): boolean; + /** + * Whether the window is maximized. + */ + isMaximized(): boolean; + /** + * Whether menu bar automatically hides itself. + */ + isMenuBarAutoHide(): boolean; + /** + * Whether the menu bar is visible. + */ + isMenuBarVisible(): boolean; + /** + * Whether the window can be manually minimized by the user. + * +On Linux always returns `true`. + * + * @platform darwin,win32 + */ + isMinimizable(): boolean; + /** + * Whether the window is minimized. + */ + isMinimized(): boolean; + /** + * Whether current window is a modal window. + */ + isModal(): boolean; + /** + * Whether the window can be moved by user. + +On Linux always returns `true`. + * + * @platform darwin,win32 + */ + isMovable(): boolean; + /** + * Whether the window is in normal state (not maximized, not minimized, not in + * fullscreen mode). + */ + isNormal(): boolean; + /** + * Whether the window can be manually resized by the user. + */ + isResizable(): boolean; + /** + * Whether the window is in simple (pre-Lion) fullscreen mode. + * + * @platform darwin + */ + isSimpleFullScreen(): boolean; + /** + * Whether the window is in Windows 10 tablet mode. + * + * Since Windows 10 users can use their PC as tablet, under this mode apps can + * choose to optimize their UI for tablets, such as enlarging the titlebar and + * hiding titlebar buttons. + * + * This API returns whether the window is in tablet mode, and the `resize` event + * can be be used to listen to changes to tablet mode. + * + * @platform win32 + */ + isTabletMode(): boolean; + /** + * Whether the window is visible to the user. + */ + isVisible(): boolean; + /** + * Whether the window is visible on all workspaces. + * +**Note:** This API always returns false on Windows. + */ + isVisibleOnAllWorkspaces(): boolean; + /** + * `true` or `false` depending on whether the message is hooked. + * + * @platform win32 + */ + isWindowMessageHooked(message: number): boolean; + /** + * the promise will resolve when the page has finished loading (see + * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`). + * + * Same as `webContents.loadFile`, `filePath` should be a path to an HTML file + * relative to the root of your application. See the `webContents` docs for more + * information. + */ + loadFile(filePath: string, options?: LoadFileOptions): Promise; + /** + * the promise will resolve when the page has finished loading (see + * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`). + * + * Same as `webContents.loadURL(url[, options])`. + * + * The `url` can be a remote address (e.g. `http://`) or a path to a local HTML + * file using the `file://` protocol. + * + * To ensure that file URLs are properly formatted, it is recommended to use Node's + * `url.format` method: + * + * You can load a URL using a `POST` request with URL-encoded data by doing the + * following: + */ + loadURL(url: string, options?: LoadURLOptions): Promise; + /** + * Maximizes the window. This will also show (but not focus) the window if it isn't + * being displayed already. + */ + maximize(): void; + /** + * Merges all windows into one window with multiple tabs when native tabs are + * enabled and there is more than one open window. + * + * @platform darwin + */ + mergeAllWindows(): void; + /** + * Minimizes the window. On some platforms the minimized window will be shown in + * the Dock. + */ + minimize(): void; + /** + * Moves window above the source window in the sense of z-order. If the + * `mediaSourceId` is not of type window or if the window does not exist then this + * method throws an error. + */ + moveAbove(mediaSourceId: string): void; + /** + * Moves the current tab into a new window if native tabs are enabled and there is + * more than one tab in the current window. + * + * @platform darwin + */ + moveTabToNewWindow(): void; + /** + * Moves window to top(z-order) regardless of focus + */ + moveTop(): void; + /** + * Uses Quick Look to preview a file at a given path. + * + * @platform darwin + */ + previewFile(path: string, displayName?: string): void; + /** + * Same as `webContents.reload`. + */ + reload(): void; + removeBrowserView(browserView: BrowserView): void; + /** + * Remove the window's menu bar. + * + * @platform linux,win32 + */ + removeMenu(): void; + /** + * Restores the window from minimized state to its previous state. + */ + restore(): void; + /** + * Selects the next tab when native tabs are enabled and there are other tabs in + * the window. + * + * @platform darwin + */ + selectNextTab(): void; + /** + * Selects the previous tab when native tabs are enabled and there are other tabs + * in the window. + * + * @platform darwin + */ + selectPreviousTab(): void; + /** + * Sets whether the window should show always on top of other windows. After + * setting this, the window is still a normal window, not a toolbox window which + * can not be focused on. + */ + setAlwaysOnTop(flag: boolean, level?: 'normal' | 'floating' | 'torn-off-menu' | 'modal-panel' | 'main-menu' | 'status' | 'pop-up-menu' | 'screen-saver', relativeLevel?: number): void; + /** + * Sets the properties for the window's taskbar button. + * + * **Note:** `relaunchCommand` and `relaunchDisplayName` must always be set + * together. If one of those properties is not set, then neither will be used. + * + * @platform win32 + */ + setAppDetails(options: AppDetailsOptions): void; + /** + * This will make a window maintain an aspect ratio. The extra size allows a + * developer to have space, specified in pixels, not included within the aspect + * ratio calculations. This API already takes into account the difference between a + * window's size and its content size. + * + * Consider a normal window with an HD video player and associated controls. + * Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls + * on the right edge and 50 pixels of controls below the player. In order to + * maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within + * the player itself we would call this function with arguments of 16/9 and { + * width: 40, height: 50 }. The second argument doesn't care where the extra width + * and height are within the content view--only that they exist. Sum any extra + * width and height areas you have within the overall content view. + * + * The aspect ratio is not respected when window is resized programmingly with APIs + * like `win.setSize`. + */ + setAspectRatio(aspectRatio: number, extraSize?: Size): void; + /** + * Controls whether to hide cursor when typing. + * + * @platform darwin + */ + setAutoHideCursor(autoHide: boolean): void; + /** + * Sets whether the window menu bar should hide itself automatically. Once set the + * menu bar will only show when users press the single `Alt` key. + * + * If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't + * hide it immediately. + */ + setAutoHideMenuBar(hide: boolean): void; + /** + * Sets the background color of the window. See Setting `backgroundColor`. + */ + setBackgroundColor(backgroundColor: string): void; + /** + * Resizes and moves the window to the supplied bounds. Any properties that are not + * supplied will default to their current values. + */ + setBounds(bounds: Partial, animate?: boolean): void; + setBrowserView(browserView: (BrowserView) | (null)): void; + /** + * Sets whether the window can be manually closed by user. On Linux does nothing. + * + * @platform darwin,win32 + */ + setClosable(closable: boolean): void; + /** + * Resizes and moves the window's client area (e.g. the web page) to the supplied + * bounds. + */ + setContentBounds(bounds: Rectangle, animate?: boolean): void; + /** + * Prevents the window contents from being captured by other apps. + * + * On macOS it sets the NSWindow's sharingType to NSWindowSharingNone. On Windows + * it calls SetWindowDisplayAffinity with `WDA_EXCLUDEFROMCAPTURE`. For Windows 10 + * version 2004 and up the window will be removed from capture entirely, older + * Windows versions behave as if `WDA_MONITOR` is applied capturing a black window. + * + * @platform darwin,win32 + */ + setContentProtection(enable: boolean): void; + /** + * Resizes the window's client area (e.g. the web page) to `width` and `height`. + */ + setContentSize(width: number, height: number, animate?: boolean): void; + /** + * Specifies whether the window’s document has been edited, and the icon in title + * bar will become gray when set to `true`. + * + * @platform darwin + */ + setDocumentEdited(edited: boolean): void; + /** + * Disable or enable the window. + */ + setEnabled(enable: boolean): void; + /** + * Changes whether the window can be focused. + * +On macOS it does not remove the focus from the window. + * + * @platform darwin,win32 + */ + setFocusable(focusable: boolean): void; + /** + * Sets whether the window should be in fullscreen mode. + */ + setFullScreen(flag: boolean): void; + /** + * Sets whether the maximize/zoom window button toggles fullscreen mode or + * maximizes the window. + */ + setFullScreenable(fullscreenable: boolean): void; + /** + * Sets whether the window should have a shadow. + */ + setHasShadow(hasShadow: boolean): void; + /** + * Changes window icon. + * + * @platform win32,linux + */ + setIcon(icon: (NativeImage) | (string)): void; + /** + * Makes the window ignore all mouse events. + * + * All mouse events happened in this window will be passed to the window below this + * window, but if this window has focus, it will still receive keyboard events. + */ + setIgnoreMouseEvents(ignore: boolean, options?: IgnoreMouseEventsOptions): void; + /** + * Enters or leaves kiosk mode. + */ + setKiosk(flag: boolean): void; + /** + * Sets whether the window can be manually maximized by user. On Linux does + * nothing. + * + * @platform darwin,win32 + */ + setMaximizable(maximizable: boolean): void; + /** + * Sets the maximum size of window to `width` and `height`. + */ + setMaximumSize(width: number, height: number): void; + /** + * Sets the `menu` as the window's menu bar. + * + * @platform linux,win32 + */ + setMenu(menu: (Menu) | (null)): void; + /** + * Sets whether the menu bar should be visible. If the menu bar is auto-hide, users + * can still bring up the menu bar by pressing the single `Alt` key. + * + * @platform win32,linux + */ + setMenuBarVisibility(visible: boolean): void; + /** + * Sets whether the window can be manually minimized by user. On Linux does + * nothing. + * + * @platform darwin,win32 + */ + setMinimizable(minimizable: boolean): void; + /** + * Sets the minimum size of window to `width` and `height`. + */ + setMinimumSize(width: number, height: number): void; + /** + * Sets whether the window can be moved by user. On Linux does nothing. + * + * @platform darwin,win32 + */ + setMovable(movable: boolean): void; + /** + * Sets the opacity of the window. On Linux, does nothing. Out of bound number + * values are clamped to the [0, 1] range. + * + * @platform win32,darwin + */ + setOpacity(opacity: number): void; + /** + * Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to + * convey some sort of application status or to passively notify the user. + * + * @platform win32 + */ + setOverlayIcon(overlay: (NativeImage) | (null), description: string): void; + /** + * Sets `parent` as current window's parent window, passing `null` will turn + * current window into a top-level window. + */ + setParentWindow(parent: (BrowserWindow) | (null)): void; + /** + * Moves window to `x` and `y`. + */ + setPosition(x: number, y: number, animate?: boolean): void; + /** + * Sets progress value in progress bar. Valid range is [0, 1.0]. + * + * Remove progress bar when progress < 0; Change to indeterminate mode when + * progress > 1. + * + * On Linux platform, only supports Unity desktop environment, you need to specify + * the `*.desktop` file name to `desktopName` field in `package.json`. By default, + * it will assume `{app.name}.desktop`. + * + * On Windows, a mode can be passed. Accepted values are `none`, `normal`, + * `indeterminate`, `error`, and `paused`. If you call `setProgressBar` without a + * mode set (but with a value within the valid range), `normal` will be assumed. + */ + setProgressBar(progress: number, options?: ProgressBarOptions): void; + /** + * Sets the pathname of the file the window represents, and the icon of the file + * will show in window's title bar. + * + * @platform darwin + */ + setRepresentedFilename(filename: string): void; + /** + * Sets whether the window can be manually resized by the user. + */ + setResizable(resizable: boolean): void; + /** + * Setting a window shape determines the area within the window where the system + * permits drawing and user interaction. Outside of the given region, no pixels + * will be drawn and no mouse events will be registered. Mouse events outside of + * the region will not be received by that window, but will fall through to + * whatever is behind the window. + * + * @experimental + * @platform win32,linux + */ + setShape(rects: Rectangle[]): void; + /** + * Changes the attachment point for sheets on macOS. By default, sheets are + * attached just below the window frame, but you may want to display them beneath a + * HTML-rendered toolbar. For example: + * + * @platform darwin + */ + setSheetOffset(offsetY: number, offsetX?: number): void; + /** + * Enters or leaves simple fullscreen mode. + * + * Simple fullscreen mode emulates the native fullscreen behavior found in versions + * of macOS prior to Lion (10.7). + * + * @platform darwin + */ + setSimpleFullScreen(flag: boolean): void; + /** + * Resizes the window to `width` and `height`. If `width` or `height` are below any + * set minimum size constraints the window will snap to its minimum size. + */ + setSize(width: number, height: number, animate?: boolean): void; + /** + * Makes the window not show in the taskbar. + */ + setSkipTaskbar(skip: boolean): void; + /** + * Whether the buttons were added successfully + * + * Add a thumbnail toolbar with a specified set of buttons to the thumbnail image + * of a window in a taskbar button layout. Returns a `Boolean` object indicates + * whether the thumbnail has been added successfully. + * + * The number of buttons in thumbnail toolbar should be no greater than 7 due to + * the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be + * removed due to the platform's limitation. But you can call the API with an empty + * array to clean the buttons. + * + * The `buttons` is an array of `Button` objects: + * + * * `Button` Object + * * `icon` NativeImage - The icon showing in thumbnail toolbar. + * * `click` Function + * * `tooltip` String (optional) - The text of the button's tooltip. + * * `flags` String[] (optional) - Control specific states and behaviors of the + * button. By default, it is `['enabled']`. + * + * The `flags` is an array that can include following `String`s: + * + * * `enabled` - The button is active and available to the user. + * * `disabled` - The button is disabled. It is present, but has a visual state + * indicating it will not respond to user action. + * * `dismissonclick` - When the button is clicked, the thumbnail window closes + * immediately. + * * `nobackground` - Do not draw a button border, use only the image. + * * `hidden` - The button is not shown to the user. + * * `noninteractive` - The button is enabled but not interactive; no pressed + * button state is drawn. This value is intended for instances where the button is + * used in a notification. + * + * @platform win32 + */ + setThumbarButtons(buttons: ThumbarButton[]): boolean; + /** + * Sets the region of the window to show as the thumbnail image displayed when + * hovering over the window in the taskbar. You can reset the thumbnail to be the + * entire window by specifying an empty region: `{ x: 0, y: 0, width: 0, height: 0 + * }`. + * + * @platform win32 + */ + setThumbnailClip(region: Rectangle): void; + /** + * Sets the toolTip that is displayed when hovering over the window thumbnail in + * the taskbar. + * + * @platform win32 + */ + setThumbnailToolTip(toolTip: string): void; + /** + * Changes the title of native window to `title`. + */ + setTitle(title: string): void; + /** + * Raises `browserView` above other `BrowserView`s attached to `win`. Throws an + * error if `browserView` is not attached to `win`. + * + * @experimental + */ + setTopBrowserView(browserView: BrowserView): void; + /** + * Sets the touchBar layout for the current window. Specifying `null` or + * `undefined` clears the touch bar. This method only has an effect if the machine + * has a touch bar and is running on macOS 10.12.1+. + * + * **Note:** The TouchBar API is currently experimental and may change or be + * removed in future Electron releases. + * + * @platform darwin + */ + setTouchBar(touchBar: (TouchBar) | (null)): void; + /** + * Set a custom position for the traffic light buttons in frameless window. + * + * @platform darwin + */ + setTrafficLightPosition(position: Point): void; + /** + * Adds a vibrancy effect to the browser window. Passing `null` or an empty string + * will remove the vibrancy effect on the window. + * + * Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` + * have been deprecated and will be removed in an upcoming version of macOS. + * + * @platform darwin + */ + setVibrancy(type: (('appearance-based' | 'light' | 'dark' | 'titlebar' | 'selection' | 'menu' | 'popover' | 'sidebar' | 'medium-light' | 'ultra-dark' | 'header' | 'sheet' | 'window' | 'hud' | 'fullscreen-ui' | 'tooltip' | 'content' | 'under-window' | 'under-page')) | (null)): void; + /** + * Sets whether the window should be visible on all workspaces. + * +**Note:** This API does nothing on Windows. + */ + setVisibleOnAllWorkspaces(visible: boolean, options?: VisibleOnAllWorkspacesOptions): void; + /** + * Sets whether the window traffic light buttons should be visible. + * + * @platform darwin + */ + setWindowButtonVisibility(visible: boolean): void; + /** + * Shows and gives focus to the window. + */ + show(): void; + /** + * Same as `webContents.showDefinitionForSelection()`. + * + * @platform darwin + */ + showDefinitionForSelection(): void; + /** + * Shows the window but doesn't focus on it. + */ + showInactive(): void; + /** + * Toggles the visibility of the tab bar if native tabs are enabled and there is + * only one tab in the current window. + * + * @platform darwin + */ + toggleTabBar(): void; + /** + * Unhooks all of the window messages. + * + * @platform win32 + */ + unhookAllWindowMessages(): void; + /** + * Unhook the window message. + * + * @platform win32 + */ + unhookWindowMessage(message: number): void; + /** + * Unmaximizes the window. + */ + unmaximize(): void; + accessibleTitle: string; + autoHideMenuBar: boolean; + closable: boolean; + documentEdited: boolean; + excludedFromShownWindowsMenu: boolean; + fullScreen: boolean; + fullScreenable: boolean; + readonly id: number; + kiosk: boolean; + maximizable: boolean; + menuBarVisible: boolean; + minimizable: boolean; + movable: boolean; + representedFilename: string; + resizable: boolean; + shadow: boolean; + simpleFullScreen: boolean; + title: string; + visibleOnAllWorkspaces: boolean; + readonly webContents: WebContents; + } + + class BrowserWindowProxy { + + // Docs: https://electronjs.org/docs/api/browser-window-proxy + + /** + * Removes focus from the child window. + */ + blur(): void; + /** + * Forcefully closes the child window without calling its unload event. + */ + close(): void; + /** + * Evaluates the code in the child window. + */ + eval(code: string): void; + /** + * Focuses the child window (brings the window to front). + */ + focus(): void; + /** + * Sends a message to the child window with the specified origin or `*` for no + * origin preference. + * + * In addition to these methods, the child window implements `window.opener` object + * with no properties and a single method. + */ + postMessage(message: any, targetOrigin: string): void; + /** + * Invokes the print dialog on the child window. + */ + print(): void; + closed: boolean; + } + + interface Certificate { + + // Docs: https://electronjs.org/docs/api/structures/certificate + + /** + * PEM encoded data + */ + data: string; + /** + * Fingerprint of the certificate + */ + fingerprint: string; + /** + * Issuer principal + */ + issuer: CertificatePrincipal; + /** + * Issuer certificate (if not self-signed) + */ + issuerCert: Certificate; + /** + * Issuer's Common Name + */ + issuerName: string; + /** + * Hex value represented string + */ + serialNumber: string; + /** + * Subject principal + */ + subject: CertificatePrincipal; + /** + * Subject's Common Name + */ + subjectName: string; + /** + * End date of the certificate being valid in seconds + */ + validExpiry: number; + /** + * Start date of the certificate being valid in seconds + */ + validStart: number; + } + + interface CertificatePrincipal { + + // Docs: https://electronjs.org/docs/api/structures/certificate-principal + + /** + * Common Name. + */ + commonName: string; + /** + * Country or region. + */ + country: string; + /** + * Locality. + */ + locality: string; + /** + * Organization names. + */ + organizations: string[]; + /** + * Organization Unit names. + */ + organizationUnits: string[]; + /** + * State or province. + */ + state: string; + } + + class ClientRequest extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/client-request + + /** + * Emitted when the `request` is aborted. The `abort` event will not be fired if + * the `request` is already closed. + */ + on(event: 'abort', listener: Function): this; + once(event: 'abort', listener: Function): this; + addListener(event: 'abort', listener: Function): this; + removeListener(event: 'abort', listener: Function): this; + /** + * Emitted as the last event in the HTTP request-response transaction. The `close` + * event indicates that no more events will be emitted on either the `request` or + * `response` objects. + */ + on(event: 'close', listener: Function): this; + once(event: 'close', listener: Function): this; + addListener(event: 'close', listener: Function): this; + removeListener(event: 'close', listener: Function): this; + /** + * Emitted when the `net` module fails to issue a network request. Typically when + * the `request` object emits an `error` event, a `close` event will subsequently + * follow and no response object will be provided. + */ + on(event: 'error', listener: ( + /** + * an error object providing some information about the failure. + */ + error: Error) => void): this; + once(event: 'error', listener: ( + /** + * an error object providing some information about the failure. + */ + error: Error) => void): this; + addListener(event: 'error', listener: ( + /** + * an error object providing some information about the failure. + */ + error: Error) => void): this; + removeListener(event: 'error', listener: ( + /** + * an error object providing some information about the failure. + */ + error: Error) => void): this; + /** + * Emitted just after the last chunk of the `request`'s data has been written into + * the `request` object. + */ + on(event: 'finish', listener: Function): this; + once(event: 'finish', listener: Function): this; + addListener(event: 'finish', listener: Function): this; + removeListener(event: 'finish', listener: Function): this; + /** + * Emitted when an authenticating proxy is asking for user credentials. + * + * The `callback` function is expected to be called back with user credentials: + * + * * `username` String + * * `password` String + * + * Providing empty credentials will cancel the request and report an authentication + * error on the response object: + */ + on(event: 'login', listener: (authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + once(event: 'login', listener: (authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + addListener(event: 'login', listener: (authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + removeListener(event: 'login', listener: (authInfo: AuthInfo, + callback: (username?: string, password?: string) => void) => void): this; + /** + * Emitted when the server returns a redirect response (e.g. 301 Moved + * Permanently). Calling `request.followRedirect` will continue with the + * redirection. If this event is handled, `request.followRedirect` must be called + * **synchronously**, otherwise the request will be cancelled. + */ + on(event: 'redirect', listener: (statusCode: number, + method: string, + redirectUrl: string, + responseHeaders: Record) => void): this; + once(event: 'redirect', listener: (statusCode: number, + method: string, + redirectUrl: string, + responseHeaders: Record) => void): this; + addListener(event: 'redirect', listener: (statusCode: number, + method: string, + redirectUrl: string, + responseHeaders: Record) => void): this; + removeListener(event: 'redirect', listener: (statusCode: number, + method: string, + redirectUrl: string, + responseHeaders: Record) => void): this; + on(event: 'response', listener: ( + /** + * An object representing the HTTP response message. + */ + response: IncomingMessage) => void): this; + once(event: 'response', listener: ( + /** + * An object representing the HTTP response message. + */ + response: IncomingMessage) => void): this; + addListener(event: 'response', listener: ( + /** + * An object representing the HTTP response message. + */ + response: IncomingMessage) => void): this; + removeListener(event: 'response', listener: ( + /** + * An object representing the HTTP response message. + */ + response: IncomingMessage) => void): this; + /** + * ClientRequest + */ + constructor(options: (ClientRequestConstructorOptions) | (string)); + /** + * Cancels an ongoing HTTP transaction. If the request has already emitted the + * `close` event, the abort operation will have no effect. Otherwise an ongoing + * event will emit `abort` and `close` events. Additionally, if there is an ongoing + * response object,it will emit the `aborted` event. + */ + abort(): void; + /** + * Sends the last chunk of the request data. Subsequent write or end operations + * will not be allowed. The `finish` event is emitted just after the end operation. + */ + end(chunk?: (string) | (Buffer), encoding?: string, callback?: () => void): void; + /** + * Continues any pending redirection. Can only be called during a `'redirect'` + * event. + */ + followRedirect(): void; + /** + * The value of a previously set extra header name. + */ + getHeader(name: string): string; + /** + * * `active` Boolean - Whether the request is currently active. If this is false + * no other properties will be set + * * `started` Boolean - Whether the upload has started. If this is false both + * `current` and `total` will be set to 0. + * * `current` Integer - The number of bytes that have been uploaded so far + * * `total` Integer - The number of bytes that will be uploaded this request + * + * You can use this method in conjunction with `POST` requests to get the progress + * of a file upload or other data transfer. + */ + getUploadProgress(): UploadProgress; + /** + * Removes a previously set extra header name. This method can be called only + * before first write. Trying to call it after the first write will throw an error. + */ + removeHeader(name: string): void; + /** + * Adds an extra HTTP header. The header name will be issued as-is without + * lowercasing. It can be called only before first write. Calling this method after + * the first write will throw an error. If the passed value is not a `String`, its + * `toString()` method will be called to obtain the final value. + * + * Certain headers are restricted from being set by apps. These headers are listed + * below. More information on restricted headers can be found in Chromium's header + * utils. + * + * * `Content-Length` + * * `Host` + * * `Trailer` or `Te` + * * `Upgrade` + * * `Cookie2` + * * `Keep-Alive` + * * `Transfer-Encoding` + * + * Additionally, setting the `Connection` header to the value `upgrade` is also + * disallowed. + */ + setHeader(name: string, value: string): void; + /** + * `callback` is essentially a dummy function introduced in the purpose of keeping + * similarity with the Node.js API. It is called asynchronously in the next tick + * after `chunk` content have been delivered to the Chromium networking layer. + * Contrary to the Node.js implementation, it is not guaranteed that `chunk` + * content have been flushed on the wire before `callback` is called. + * + * Adds a chunk of data to the request body. The first write operation may cause + * the request headers to be issued on the wire. After the first write operation, + * it is not allowed to add or remove a custom header. + */ + write(chunk: (string) | (Buffer), encoding?: string, callback?: () => void): void; + chunkedEncoding: boolean; + } + + interface Clipboard { + + // Docs: https://electronjs.org/docs/api/clipboard + + /** + * An array of supported formats for the clipboard `type`. + */ + availableFormats(type?: 'selection' | 'clipboard'): string[]; + /** + * Clears the clipboard content. + */ + clear(type?: 'selection' | 'clipboard'): void; + /** + * Whether the clipboard supports the specified `format`. + * + * @experimental + */ + has(format: string, type?: 'selection' | 'clipboard'): boolean; + /** + * Reads `format` type from the clipboard. + * + * @experimental + */ + read(format: string): string; + /** + * * `title` String + * * `url` String + * + * Returns an Object containing `title` and `url` keys representing the bookmark in + * the clipboard. The `title` and `url` values will be empty strings when the + * bookmark is unavailable. + * + * @platform darwin,win32 + */ + readBookmark(): ReadBookmark; + /** + * Reads `format` type from the clipboard. + * + * @experimental + */ + readBuffer(format: string): Buffer; + /** + * The text on the find pasteboard, which is the pasteboard that holds information + * about the current state of the active application’s find panel. + * + * This method uses synchronous IPC when called from the renderer process. The + * cached value is reread from the find pasteboard whenever the application is + * activated. + * + * @platform darwin + */ + readFindText(): string; + /** + * The content in the clipboard as markup. + */ + readHTML(type?: 'selection' | 'clipboard'): string; + /** + * The image content in the clipboard. + */ + readImage(type?: 'selection' | 'clipboard'): NativeImage; + /** + * The content in the clipboard as RTF. + */ + readRTF(type?: 'selection' | 'clipboard'): string; + /** + * The content in the clipboard as plain text. + */ + readText(type?: 'selection' | 'clipboard'): string; + /** + * Writes `data` to the clipboard. + */ + write(data: Data, type?: 'selection' | 'clipboard'): void; + /** + * Writes the `title` and `url` into the clipboard as a bookmark. + * + * **Note:** Most apps on Windows don't support pasting bookmarks into them so you + * can use `clipboard.write` to write both a bookmark and fallback text to the + * clipboard. + * + * @platform darwin,win32 + */ + writeBookmark(title: string, url: string, type?: 'selection' | 'clipboard'): void; + /** + * Writes the `buffer` into the clipboard as `format`. + * + * @experimental + */ + writeBuffer(format: string, buffer: Buffer, type?: 'selection' | 'clipboard'): void; + /** + * Writes the `text` into the find pasteboard (the pasteboard that holds + * information about the current state of the active application’s find panel) as + * plain text. This method uses synchronous IPC when called from the renderer + * process. + * + * @platform darwin + */ + writeFindText(text: string): void; + /** + * Writes `markup` to the clipboard. + */ + writeHTML(markup: string, type?: 'selection' | 'clipboard'): void; + /** + * Writes `image` to the clipboard. + */ + writeImage(image: NativeImage, type?: 'selection' | 'clipboard'): void; + /** + * Writes the `text` into the clipboard in RTF. + */ + writeRTF(text: string, type?: 'selection' | 'clipboard'): void; + /** + * Writes the `text` into the clipboard as plain text. + */ + writeText(text: string, type?: 'selection' | 'clipboard'): void; + } + + class CommandLine { + + // Docs: https://electronjs.org/docs/api/command-line + + /** + * Append an argument to Chromium's command line. The argument will be quoted + * correctly. Switches will precede arguments regardless of appending order. + * + * If you're appending an argument like `--switch=value`, consider using + * `appendSwitch('switch', 'value')` instead. + * + * **Note:** This will not affect `process.argv`. The intended usage of this + * function is to control Chromium's behavior. + */ + appendArgument(value: string): void; + /** + * Append a switch (with optional `value`) to Chromium's command line. + * + * **Note:** This will not affect `process.argv`. The intended usage of this + * function is to control Chromium's behavior. + */ + appendSwitch(the_switch: string, value?: string): void; + /** + * The command-line switch value. + * + * **Note:** When the switch is not present or has no value, it returns empty + * string. + */ + getSwitchValue(the_switch: string): string; + /** + * Whether the command-line switch is present. + */ + hasSwitch(the_switch: string): boolean; + } + + interface ContentTracing { + + // Docs: https://electronjs.org/docs/api/content-tracing + + /** + * resolves with an array of category groups once all child processes have + * acknowledged the `getCategories` request + * + * Get a set of category groups. The category groups can change as new code paths + * are reached. See also the list of built-in tracing categories. + * + * > **NOTE:** Electron adds a non-default tracing category called `"electron"`. + * This category can be used to capture Electron-specific tracing events. + */ + getCategories(): Promise; + /** + * Resolves with an object containing the `value` and `percentage` of trace buffer + * maximum usage + * + * * `value` Number + * * `percentage` Number + * + * Get the maximum usage across processes of trace buffer as a percentage of the + * full state. + */ + getTraceBufferUsage(): Promise; + /** + * resolved once all child processes have acknowledged the `startRecording` + * request. + * + * Start recording on all processes. + * + * Recording begins immediately locally and asynchronously on child processes as + * soon as they receive the EnableRecording request. + * + * If a recording is already running, the promise will be immediately resolved, as + * only one trace operation can be in progress at a time. + */ + startRecording(options: (TraceConfig) | (TraceCategoriesAndOptions)): Promise; + /** + * resolves with a path to a file that contains the traced data once all child + * processes have acknowledged the `stopRecording` request + * + * Stop recording on all processes. + * + * Child processes typically cache trace data and only rarely flush and send trace + * data back to the main process. This helps to minimize the runtime overhead of + * tracing since sending trace data over IPC can be an expensive operation. So, to + * end tracing, Chromium asynchronously asks all child processes to flush any + * pending trace data. + * + * Trace data will be written into `resultFilePath`. If `resultFilePath` is empty + * or not provided, trace data will be written to a temporary file, and the path + * will be returned in the promise. + */ + stopRecording(resultFilePath?: string): Promise; + } + + interface ContextBridge { + + // Docs: https://electronjs.org/docs/api/context-bridge + + exposeInMainWorld(apiKey: string, api: any): void; + } + + interface Cookie { + + // Docs: https://electronjs.org/docs/api/structures/cookie + + /** + * The domain of the cookie; this will be normalized with a preceding dot so that + * it's also valid for subdomains. + */ + domain?: string; + /** + * The expiration date of the cookie as the number of seconds since the UNIX epoch. + * Not provided for session cookies. + */ + expirationDate?: number; + /** + * Whether the cookie is a host-only cookie; this will only be `true` if no domain + * was passed. + */ + hostOnly?: boolean; + /** + * Whether the cookie is marked as HTTP only. + */ + httpOnly?: boolean; + /** + * The name of the cookie. + */ + name: string; + /** + * The path of the cookie. + */ + path?: string; + /** + * The Same Site policy applied to this cookie. Can be `unspecified`, + * `no_restriction`, `lax` or `strict`. + */ + sameSite: ('unspecified' | 'no_restriction' | 'lax' | 'strict'); + /** + * Whether the cookie is marked as secure. + */ + secure?: boolean; + /** + * Whether the cookie is a session cookie or a persistent cookie with an expiration + * date. + */ + session?: boolean; + /** + * The value of the cookie. + */ + value: string; + } + + class Cookies extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/cookies + + /** + * Emitted when a cookie is changed because it was added, edited, removed, or + * expired. + */ + on(event: 'changed', listener: (event: Event, + /** + * The cookie that was changed. + */ + cookie: Cookie, + /** + * The cause of the change with one of the following values: + */ + cause: ('explicit' | 'overwrite' | 'expired' | 'evicted' | 'expired-overwrite'), + /** + * `true` if the cookie was removed, `false` otherwise. + */ + removed: boolean) => void): this; + once(event: 'changed', listener: (event: Event, + /** + * The cookie that was changed. + */ + cookie: Cookie, + /** + * The cause of the change with one of the following values: + */ + cause: ('explicit' | 'overwrite' | 'expired' | 'evicted' | 'expired-overwrite'), + /** + * `true` if the cookie was removed, `false` otherwise. + */ + removed: boolean) => void): this; + addListener(event: 'changed', listener: (event: Event, + /** + * The cookie that was changed. + */ + cookie: Cookie, + /** + * The cause of the change with one of the following values: + */ + cause: ('explicit' | 'overwrite' | 'expired' | 'evicted' | 'expired-overwrite'), + /** + * `true` if the cookie was removed, `false` otherwise. + */ + removed: boolean) => void): this; + removeListener(event: 'changed', listener: (event: Event, + /** + * The cookie that was changed. + */ + cookie: Cookie, + /** + * The cause of the change with one of the following values: + */ + cause: ('explicit' | 'overwrite' | 'expired' | 'evicted' | 'expired-overwrite'), + /** + * `true` if the cookie was removed, `false` otherwise. + */ + removed: boolean) => void): this; + /** + * A promise which resolves when the cookie store has been flushed + * +Writes any unwritten cookies data to disk. + */ + flushStore(): Promise; + /** + * A promise which resolves an array of cookie objects. + * + * Sends a request to get all cookies matching `filter`, and resolves a promise + * with the response. + */ + get(filter: CookiesGetFilter): Promise; + /** + * A promise which resolves when the cookie has been removed + * +Removes the cookies matching `url` and `name` + */ + remove(url: string, name: string): Promise; + /** + * A promise which resolves when the cookie has been set + * +Sets a cookie with `details`. + */ + set(details: CookiesSetDetails): Promise; + } + + interface CPUUsage { + + // Docs: https://electronjs.org/docs/api/structures/cpu-usage + + /** + * The number of average idle CPU wakeups per second since the last call to + * getCPUUsage. First call returns 0. Will always return 0 on Windows. + */ + idleWakeupsPerSecond: number; + /** + * Percentage of CPU used since the last call to getCPUUsage. First call returns 0. + */ + percentCPUUsage: number; + } + + interface CrashReport { + + // Docs: https://electronjs.org/docs/api/structures/crash-report + + date: Date; + id: string; + } + + interface CrashReporter { + + // Docs: https://electronjs.org/docs/api/crash-reporter + + /** + * Set an extra parameter to be sent with the crash report. The values specified + * here will be sent in addition to any values set via the `extra` option when + * `start` was called. + * + * Parameters added in this fashion (or via the `extra` parameter to + * `crashReporter.start`) are specific to the calling process. Adding extra + * parameters in the main process will not cause those parameters to be sent along + * with crashes from renderer or other child processes. Similarly, adding extra + * parameters in a renderer process will not result in those parameters being sent + * with crashes that occur in other renderer processes or in the main process. + * + * **Note:** Parameters have limits on the length of the keys and values. Key names + * must be no longer than 39 bytes, and values must be no longer than 20320 bytes. + * Keys with names longer than the maximum will be silently ignored. Key values + * longer than the maximum length will be truncated. + * + * **Note:** On linux values that are longer than 127 bytes will be chunked into + * multiple keys, each 127 bytes in length. E.g. `addExtraParameter('foo', + * 'a'.repeat(130))` will result in two chunked keys `foo__1` and `foo__2`, the + * first will contain the first 127 bytes and the second will contain the remaining + * 3 bytes. On your crash reporting backend you should stitch together keys in + * this format. + */ + addExtraParameter(key: string, value: string): void; + /** + * The date and ID of the last crash report. Only crash reports that have been + * uploaded will be returned; even if a crash report is present on disk it will not + * be returned until it is uploaded. In the case that there are no uploaded + * reports, `null` is returned. + * +**Note:** This method is only available in the main process. + */ + getLastCrashReport(): CrashReport; + /** + * The current 'extra' parameters of the crash reporter. + */ + getParameters(): Record; + /** + * Returns all uploaded crash reports. Each report contains the date and uploaded + * ID. + +**Note:** This method is only available in the main process. + */ + getUploadedReports(): CrashReport[]; + /** + * Whether reports should be submitted to the server. Set through the `start` + * method or `setUploadToServer`. + * +**Note:** This method is only available in the main process. + */ + getUploadToServer(): boolean; + /** + * Remove an extra parameter from the current set of parameters. Future crashes + * will not include this parameter. + */ + removeExtraParameter(key: string): void; + /** + * This would normally be controlled by user preferences. This has no effect if + * called before `start` is called. + * +**Note:** This method is only available in the main process. + */ + setUploadToServer(uploadToServer: boolean): void; + /** + * This method must be called before using any other `crashReporter` APIs. Once + * initialized this way, the crashpad handler collects crashes from all + * subsequently created processes. The crash reporter cannot be disabled once + * started. + * + * This method should be called as early as possible in app startup, preferably + * before `app.on('ready')`. If the crash reporter is not initialized at the time a + * renderer process is created, then that renderer process will not be monitored by + * the crash reporter. + * + * **Note:** You can test out the crash reporter by generating a crash using + * `process.crash()`. + * + * **Note:** If you need to send additional/updated `extra` parameters after your + * first call `start` you can call `addExtraParameter`. + * + * **Note:** Parameters passed in `extra`, `globalExtra` or set with + * `addExtraParameter` have limits on the length of the keys and values. Key names + * must be at most 39 bytes long, and values must be no longer than 127 bytes. Keys + * with names longer than the maximum will be silently ignored. Key values longer + * than the maximum length will be truncated. + * +**Note:** This method is only available in the main process. + */ + start(options: CrashReporterStartOptions): void; + } + + interface CustomScheme { + + // Docs: https://electronjs.org/docs/api/structures/custom-scheme + + privileges?: Privileges; + /** + * Custom schemes to be registered with options. + */ + scheme: string; + } + + class Debugger extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/debugger + + /** + * Emitted when the debugging session is terminated. This happens either when + * `webContents` is closed or devtools is invoked for the attached `webContents`. + */ + on(event: 'detach', listener: (event: Event, + /** + * Reason for detaching debugger. + */ + reason: string) => void): this; + once(event: 'detach', listener: (event: Event, + /** + * Reason for detaching debugger. + */ + reason: string) => void): this; + addListener(event: 'detach', listener: (event: Event, + /** + * Reason for detaching debugger. + */ + reason: string) => void): this; + removeListener(event: 'detach', listener: (event: Event, + /** + * Reason for detaching debugger. + */ + reason: string) => void): this; + /** + * Emitted whenever the debugging target issues an instrumentation event. + */ + on(event: 'message', listener: (event: Event, + /** + * Method name. + */ + method: string, + /** + * Event parameters defined by the 'parameters' attribute in the remote debugging + * protocol. + */ + params: any, + /** + * Unique identifier of attached debugging session, will match the value sent from + * `debugger.sendCommand`. + */ + sessionId: string) => void): this; + once(event: 'message', listener: (event: Event, + /** + * Method name. + */ + method: string, + /** + * Event parameters defined by the 'parameters' attribute in the remote debugging + * protocol. + */ + params: any, + /** + * Unique identifier of attached debugging session, will match the value sent from + * `debugger.sendCommand`. + */ + sessionId: string) => void): this; + addListener(event: 'message', listener: (event: Event, + /** + * Method name. + */ + method: string, + /** + * Event parameters defined by the 'parameters' attribute in the remote debugging + * protocol. + */ + params: any, + /** + * Unique identifier of attached debugging session, will match the value sent from + * `debugger.sendCommand`. + */ + sessionId: string) => void): this; + removeListener(event: 'message', listener: (event: Event, + /** + * Method name. + */ + method: string, + /** + * Event parameters defined by the 'parameters' attribute in the remote debugging + * protocol. + */ + params: any, + /** + * Unique identifier of attached debugging session, will match the value sent from + * `debugger.sendCommand`. + */ + sessionId: string) => void): this; + /** + * Attaches the debugger to the `webContents`. + */ + attach(protocolVersion?: string): void; + /** + * Detaches the debugger from the `webContents`. + */ + detach(): void; + /** + * Whether a debugger is attached to the `webContents`. + */ + isAttached(): boolean; + /** + * A promise that resolves with the response defined by the 'returns' attribute of + * the command description in the remote debugging protocol or is rejected + * indicating the failure of the command. + * +Send given command to the debugging target. + */ + sendCommand(method: string, commandParams?: any, sessionId?: string): Promise; + } + + interface DesktopCapturer { + + // Docs: https://electronjs.org/docs/api/desktop-capturer + + /** + * Resolves with an array of `DesktopCapturerSource` objects, each + * `DesktopCapturerSource` represents a screen or an individual window that can be + * captured. + * + * **Note** Capturing the screen contents requires user consent on macOS 10.15 + * Catalina or higher, which can detected by + * `systemPreferences.getMediaAccessStatus`. + */ + getSources(options: SourcesOptions): Promise; + } + + interface DesktopCapturerSource { + + // Docs: https://electronjs.org/docs/api/structures/desktop-capturer-source + + /** + * An icon image of the application that owns the window or null if the source has + * a type screen. The size of the icon is not known in advance and depends on what + * the application provides. + */ + appIcon: NativeImage; + /** + * A unique identifier that will correspond to the `id` of the matching Display + * returned by the Screen API. On some platforms, this is equivalent to the `XX` + * portion of the `id` field above and on others it will differ. It will be an + * empty string if not available. + */ + display_id: string; + /** + * The identifier of a window or screen that can be used as a `chromeMediaSourceId` + * constraint when calling [`navigator.webkitGetUserMedia`]. The format of the + * identifier will be `window:XX:YY` or `screen:ZZ:0`. XX is the windowID/handle. + * YY is 1 for the current process, and 0 for all others. ZZ is a sequential number + * that represents the screen, and it does not equal to the index in the source's + * name. + */ + id: string; + /** + * A screen source will be named either `Entire Screen` or `Screen `, while + * the name of a window source will match the window title. + */ + name: string; + /** + * A thumbnail image. **Note:** There is no guarantee that the size of the + * thumbnail is the same as the `thumbnailSize` specified in the `options` passed + * to `desktopCapturer.getSources`. The actual size depends on the scale of the + * screen or window. + */ + thumbnail: NativeImage; + } + + interface Dialog { + + // Docs: https://electronjs.org/docs/api/dialog + + /** + * resolves when the certificate trust dialog is shown. + * + * On macOS, this displays a modal dialog that shows a message and certificate + * information, and gives the user the option of trusting/importing the + * certificate. If you provide a `browserWindow` argument the dialog will be + * attached to the parent window, making it modal. + * + * On Windows the options are more limited, due to the Win32 APIs used: + * + * * The `message` argument is not used, as the OS provides its own confirmation + * dialog. + * * The `browserWindow` argument is ignored since it is not possible to make this + * confirmation dialog modal. + * + * @platform darwin,win32 + */ + showCertificateTrustDialog(browserWindow: BrowserWindow, options: CertificateTrustDialogOptions): Promise; + /** + * resolves when the certificate trust dialog is shown. + * + * On macOS, this displays a modal dialog that shows a message and certificate + * information, and gives the user the option of trusting/importing the + * certificate. If you provide a `browserWindow` argument the dialog will be + * attached to the parent window, making it modal. + * + * On Windows the options are more limited, due to the Win32 APIs used: + * + * * The `message` argument is not used, as the OS provides its own confirmation + * dialog. + * * The `browserWindow` argument is ignored since it is not possible to make this + * confirmation dialog modal. + * + * @platform darwin,win32 + */ + showCertificateTrustDialog(options: CertificateTrustDialogOptions): Promise; + /** + * Displays a modal dialog that shows an error message. + * + * This API can be called safely before the `ready` event the `app` module emits, + * it is usually used to report errors in early stage of startup. If called before + * the app `ready`event on Linux, the message will be emitted to stderr, and no GUI + * dialog will appear. + */ + showErrorBox(title: string, content: string): void; + /** + * resolves with a promise containing the following properties: + * + * * `response` Number - The index of the clicked button. + * * `checkboxChecked` Boolean - The checked state of the checkbox if + * `checkboxLabel` was set. Otherwise `false`. + * + * Shows a message box. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + */ + showMessageBox(browserWindow: BrowserWindow, options: MessageBoxOptions): Promise; + /** + * resolves with a promise containing the following properties: + * + * * `response` Number - The index of the clicked button. + * * `checkboxChecked` Boolean - The checked state of the checkbox if + * `checkboxLabel` was set. Otherwise `false`. + * + * Shows a message box. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + */ + showMessageBox(options: MessageBoxOptions): Promise; + /** + * the index of the clicked button. + * + * Shows a message box, it will block the process until the message box is closed. + * It returns the index of the clicked button. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. If `browserWindow` is not shown dialog will not be + * attached to it. In such case it will be displayed as an independent window. + */ + showMessageBoxSync(browserWindow: BrowserWindow, options: MessageBoxSyncOptions): number; + /** + * the index of the clicked button. + * + * Shows a message box, it will block the process until the message box is closed. + * It returns the index of the clicked button. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. If `browserWindow` is not shown dialog will not be + * attached to it. In such case it will be displayed as an independent window. + */ + showMessageBoxSync(options: MessageBoxSyncOptions): number; + /** + * Resolve with an object containing the following: + * + * * `canceled` Boolean - whether or not the dialog was canceled. + * * `filePaths` String[] - An array of file paths chosen by the user. If the + * dialog is cancelled this will be an empty array. + * * `bookmarks` String[] (optional) _macOS_ _mas_ - An array matching the + * `filePaths` array of base64 encoded strings which contains security scoped + * bookmark data. `securityScopedBookmarks` must be enabled for this to be + * populated. (For return values, see table here.) + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed or selected + * when you want to limit the user to a specific type. For example: + * + * The `extensions` array should contain extensions without wildcards or dots (e.g. + * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the + * `'*'` wildcard (no other wildcard is supported). + * + * **Note:** On Windows and Linux an open dialog can not be both a file selector + * and a directory selector, so if you set `properties` to `['openFile', + * 'openDirectory']` on these platforms, a directory selector will be shown. + */ + showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions): Promise; + /** + * Resolve with an object containing the following: + * + * * `canceled` Boolean - whether or not the dialog was canceled. + * * `filePaths` String[] - An array of file paths chosen by the user. If the + * dialog is cancelled this will be an empty array. + * * `bookmarks` String[] (optional) _macOS_ _mas_ - An array matching the + * `filePaths` array of base64 encoded strings which contains security scoped + * bookmark data. `securityScopedBookmarks` must be enabled for this to be + * populated. (For return values, see table here.) + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed or selected + * when you want to limit the user to a specific type. For example: + * + * The `extensions` array should contain extensions without wildcards or dots (e.g. + * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the + * `'*'` wildcard (no other wildcard is supported). + * + * **Note:** On Windows and Linux an open dialog can not be both a file selector + * and a directory selector, so if you set `properties` to `['openFile', + * 'openDirectory']` on these platforms, a directory selector will be shown. + */ + showOpenDialog(options: OpenDialogOptions): Promise; + /** + * the file paths chosen by the user; if the dialog is cancelled it returns + * `undefined`. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed or selected + * when you want to limit the user to a specific type. For example: + * + * The `extensions` array should contain extensions without wildcards or dots (e.g. + * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the + * `'*'` wildcard (no other wildcard is supported). + * + * **Note:** On Windows and Linux an open dialog can not be both a file selector + * and a directory selector, so if you set `properties` to `['openFile', + * 'openDirectory']` on these platforms, a directory selector will be shown. + */ + showOpenDialogSync(browserWindow: BrowserWindow, options: OpenDialogSyncOptions): (string[]) | (undefined); + /** + * the file paths chosen by the user; if the dialog is cancelled it returns + * `undefined`. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed or selected + * when you want to limit the user to a specific type. For example: + * + * The `extensions` array should contain extensions without wildcards or dots (e.g. + * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the + * `'*'` wildcard (no other wildcard is supported). + * + * **Note:** On Windows and Linux an open dialog can not be both a file selector + * and a directory selector, so if you set `properties` to `['openFile', + * 'openDirectory']` on these platforms, a directory selector will be shown. + */ + showOpenDialogSync(options: OpenDialogSyncOptions): (string[]) | (undefined); + /** + * Resolve with an object containing the following: + * + * * `canceled` Boolean - whether or not the dialog was canceled. + * * `filePath` String (optional) - If the dialog is canceled, this will be + * `undefined`. + * * `bookmark` String (optional) _macOS_ _mas_ - Base64 encoded string which + * contains the security scoped bookmark data for the saved file. + * `securityScopedBookmarks` must be enabled for this to be present. (For return + * values, see table here.) + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed, see + * `dialog.showOpenDialog` for an example. + * + * **Note:** On macOS, using the asynchronous version is recommended to avoid + * issues when expanding and collapsing the dialog. + */ + showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions): Promise; + /** + * Resolve with an object containing the following: + * + * * `canceled` Boolean - whether or not the dialog was canceled. + * * `filePath` String (optional) - If the dialog is canceled, this will be + * `undefined`. + * * `bookmark` String (optional) _macOS_ _mas_ - Base64 encoded string which + * contains the security scoped bookmark data for the saved file. + * `securityScopedBookmarks` must be enabled for this to be present. (For return + * values, see table here.) + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed, see + * `dialog.showOpenDialog` for an example. + * + * **Note:** On macOS, using the asynchronous version is recommended to avoid + * issues when expanding and collapsing the dialog. + */ + showSaveDialog(options: SaveDialogOptions): Promise; + /** + * the path of the file chosen by the user; if the dialog is cancelled it returns + * `undefined`. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed, see + * `dialog.showOpenDialog` for an example. + */ + showSaveDialogSync(browserWindow: BrowserWindow, options: SaveDialogSyncOptions): (string) | (undefined); + /** + * the path of the file chosen by the user; if the dialog is cancelled it returns + * `undefined`. + * + * The `browserWindow` argument allows the dialog to attach itself to a parent + * window, making it modal. + * + * The `filters` specifies an array of file types that can be displayed, see + * `dialog.showOpenDialog` for an example. + */ + showSaveDialogSync(options: SaveDialogSyncOptions): (string) | (undefined); + } + + interface Display { + + // Docs: https://electronjs.org/docs/api/structures/display + + /** + * Can be `available`, `unavailable`, `unknown`. + */ + accelerometerSupport: ('available' | 'unavailable' | 'unknown'); + /** + * the bounds of the display in DIP points. + */ + bounds: Rectangle; + /** + * The number of bits per pixel. + */ + colorDepth: number; + /** + * represent a color space (three-dimensional object which contains all realizable + * color combinations) for the purpose of color conversions + */ + colorSpace: string; + /** + * The number of bits per color component. + */ + depthPerComponent: number; + /** + * The display refresh rate. + */ + displayFrequency: number; + /** + * Unique identifier associated with the display. + */ + id: number; + /** + * `true` for an internal display and `false` for an external display + */ + internal: boolean; + /** + * Whether or not the display is a monochrome display. + */ + monochrome: boolean; + /** + * Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees. + */ + rotation: number; + /** + * Output device's pixel scale factor. + */ + scaleFactor: number; + size: Size; + /** + * Can be `available`, `unavailable`, `unknown`. + */ + touchSupport: ('available' | 'unavailable' | 'unknown'); + /** + * the work area of the display in DIP points. + */ + workArea: Rectangle; + workAreaSize: Size; + } + + class Dock { + + // Docs: https://electronjs.org/docs/api/dock + + /** + * an ID representing the request. + * + * When `critical` is passed, the dock icon will bounce until either the + * application becomes active or the request is canceled. + * + * When `informational` is passed, the dock icon will bounce for one second. + * However, the request remains active until either the application becomes active + * or the request is canceled. + * + * **Nota Bene:** This method can only be used while the app is not focused; when + * the app is focused it will return -1. + * + * @platform darwin + */ + bounce(type?: 'critical' | 'informational'): number; + /** + * Cancel the bounce of `id`. + * + * @platform darwin + */ + cancelBounce(id: number): void; + /** + * Bounces the Downloads stack if the filePath is inside the Downloads folder. + * + * @platform darwin + */ + downloadFinished(filePath: string): void; + /** + * The badge string of the dock. + * + * @platform darwin + */ + getBadge(): string; + /** + * The application's [dock menu][dock-menu]. + * + * @platform darwin + */ + getMenu(): (Menu) | (null); + /** + * Hides the dock icon. + * + * @platform darwin + */ + hide(): void; + /** + * Whether the dock icon is visible. + * + * @platform darwin + */ + isVisible(): boolean; + /** + * Sets the string to be displayed in the dock’s badging area. + * + * @platform darwin + */ + setBadge(text: string): void; + /** + * Sets the `image` associated with this dock icon. + * + * @platform darwin + */ + setIcon(image: (NativeImage) | (string)): void; + /** + * Sets the application's [dock menu][dock-menu]. + * + * @platform darwin + */ + setMenu(menu: Menu): void; + /** + * Resolves when the dock icon is shown. + * + * @platform darwin + */ + show(): Promise; + } + + class DownloadItem extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/download-item + + /** + * Emitted when the download is in a terminal state. This includes a completed + * download, a cancelled download (via `downloadItem.cancel()`), and interrupted + * download that can't be resumed. + * + * The `state` can be one of following: + * + * * `completed` - The download completed successfully. + * * `cancelled` - The download has been cancelled. + * * `interrupted` - The download has interrupted and can not resume. + */ + on(event: 'done', listener: (event: Event, + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + once(event: 'done', listener: (event: Event, + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + addListener(event: 'done', listener: (event: Event, + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + removeListener(event: 'done', listener: (event: Event, + /** + * Can be `completed`, `cancelled` or `interrupted`. + */ + state: ('completed' | 'cancelled' | 'interrupted')) => void): this; + /** + * Emitted when the download has been updated and is not done. + * + * The `state` can be one of following: + * + * * `progressing` - The download is in-progress. + * * `interrupted` - The download has interrupted and can be resumed. + */ + on(event: 'updated', listener: (event: Event, + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; + once(event: 'updated', listener: (event: Event, + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; + addListener(event: 'updated', listener: (event: Event, + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; + removeListener(event: 'updated', listener: (event: Event, + /** + * Can be `progressing` or `interrupted`. + */ + state: ('progressing' | 'interrupted')) => void): this; + /** + * Cancels the download operation. + */ + cancel(): void; + /** + * Whether the download can resume. + */ + canResume(): boolean; + /** + * The Content-Disposition field from the response header. + */ + getContentDisposition(): string; + /** + * ETag header value. + */ + getETag(): string; + /** + * The file name of the download item. + * + * **Note:** The file name is not always the same as the actual one saved in local + * disk. If user changes the file name in a prompted download saving dialog, the + * actual name of saved file will be different. + */ + getFilename(): string; + /** + * Last-Modified header value. + */ + getLastModifiedTime(): string; + /** + * The files mime type. + */ + getMimeType(): string; + /** + * The received bytes of the download item. + */ + getReceivedBytes(): number; + /** + * Returns the object previously set by + * `downloadItem.setSaveDialogOptions(options)`. + */ + getSaveDialogOptions(): SaveDialogOptions; + /** + * The save path of the download item. This will be either the path set via + * `downloadItem.setSavePath(path)` or the path selected from the shown save + * dialog. + */ + getSavePath(): string; + /** + * Number of seconds since the UNIX epoch when the download was started. + */ + getStartTime(): number; + /** + * The current state. Can be `progressing`, `completed`, `cancelled` or + * `interrupted`. + * + * **Note:** The following methods are useful specifically to resume a `cancelled` + * item when session is restarted. + */ + getState(): ('progressing' | 'completed' | 'cancelled' | 'interrupted'); + /** + * The total size in bytes of the download item. + * +If the size is unknown, it returns 0. + */ + getTotalBytes(): number; + /** + * The origin URL where the item is downloaded from. + */ + getURL(): string; + /** + * The complete URL chain of the item including any redirects. + */ + getURLChain(): string[]; + /** + * Whether the download has user gesture. + */ + hasUserGesture(): boolean; + /** + * Whether the download is paused. + */ + isPaused(): boolean; + /** + * Pauses the download. + */ + pause(): void; + /** + * Resumes the download that has been paused. + * + * **Note:** To enable resumable downloads the server you are downloading from must + * support range requests and provide both `Last-Modified` and `ETag` header + * values. Otherwise `resume()` will dismiss previously received bytes and restart + * the download from the beginning. + */ + resume(): void; + /** + * This API allows the user to set custom options for the save dialog that opens + * for the download item by default. The API is only available in session's + * `will-download` callback function. + */ + setSaveDialogOptions(options: SaveDialogOptions): void; + /** + * The API is only available in session's `will-download` callback function. If + * `path` doesn't exist, Electron will try to make the directory recursively. If + * user doesn't set the save path via the API, Electron will use the original + * routine to determine the save path; this usually prompts a save dialog. + */ + setSavePath(path: string): void; + savePath: string; + } + + interface Event extends GlobalEvent { + + // Docs: https://electronjs.org/docs/api/structures/event + + preventDefault: (() => void); + } + + interface Extension { + + // Docs: https://electronjs.org/docs/api/structures/extension + + id: string; + /** + * Copy of the extension's manifest data. + */ + manifest: any; + name: string; + /** + * The extension's file path. + */ + path: string; + /** + * The extension's `chrome-extension://` URL. + */ + url: string; + version: string; + } + + interface ExtensionInfo { + + // Docs: https://electronjs.org/docs/api/structures/extension-info + + name: string; + version: string; + } + + interface FileFilter { + + // Docs: https://electronjs.org/docs/api/structures/file-filter + + extensions: string[]; + name: string; + } + + interface FilePathWithHeaders { + + // Docs: https://electronjs.org/docs/api/structures/file-path-with-headers + + /** + * Additional headers to be sent. + */ + headers?: Record; + /** + * The path to the file to send. + */ + path: string; + } + + interface GlobalShortcut { + + // Docs: https://electronjs.org/docs/api/global-shortcut + + /** + * Whether this application has registered `accelerator`. + * + * When the accelerator is already taken by other applications, this call will + * still return `false`. This behavior is intended by operating systems, since they + * don't want applications to fight for global shortcuts. + */ + isRegistered(accelerator: Accelerator): boolean; + /** + * Whether or not the shortcut was registered successfully. + * + * Registers a global shortcut of `accelerator`. The `callback` is called when the + * registered shortcut is pressed by the user. + * + * When the accelerator is already taken by other applications, this call will + * silently fail. This behavior is intended by operating systems, since they don't + * want applications to fight for global shortcuts. + * + * The following accelerators will not be registered successfully on macOS 10.14 + * Mojave unless the app has been authorized as a trusted accessibility client: + * + * * "Media Play/Pause" + * * "Media Next Track" +* "Media Previous Track" +* "Media Stop" + */ + register(accelerator: Accelerator, callback: () => void): boolean; + /** + * Registers a global shortcut of all `accelerator` items in `accelerators`. The + * `callback` is called when any of the registered shortcuts are pressed by the + * user. + * + * When a given accelerator is already taken by other applications, this call will + * silently fail. This behavior is intended by operating systems, since they don't + * want applications to fight for global shortcuts. + * + * The following accelerators will not be registered successfully on macOS 10.14 + * Mojave unless the app has been authorized as a trusted accessibility client: + * + * * "Media Play/Pause" + * * "Media Next Track" +* "Media Previous Track" +* "Media Stop" + */ + registerAll(accelerators: string[], callback: () => void): void; + /** + * Unregisters the global shortcut of `accelerator`. + */ + unregister(accelerator: Accelerator): void; + /** + * Unregisters all of the global shortcuts. + */ + unregisterAll(): void; + } + + interface GPUFeatureStatus { + + // Docs: https://electronjs.org/docs/api/structures/gpu-feature-status + + /** + * Canvas. + */ + '2d_canvas': string; + /** + * Flash. + */ + flash_3d: string; + /** + * Flash Stage3D. + */ + flash_stage3d: string; + /** + * Flash Stage3D Baseline profile. + */ + flash_stage3d_baseline: string; + /** + * Compositing. + */ + gpu_compositing: string; + /** + * Multiple Raster Threads. + */ + multiple_raster_threads: string; + /** + * Native GpuMemoryBuffers. + */ + native_gpu_memory_buffers: string; + /** + * Rasterization. + */ + rasterization: string; + /** + * Video Decode. + */ + video_decode: string; + /** + * Video Encode. + */ + video_encode: string; + /** + * VPx Video Decode. + */ + vpx_decode: string; + /** + * WebGL. + */ + webgl: string; + /** + * WebGL2. + */ + webgl2: string; + } + + interface InAppPurchase extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/in-app-purchase + + on(event: 'transactions-updated', listener: Function): this; + once(event: 'transactions-updated', listener: Function): this; + addListener(event: 'transactions-updated', listener: Function): this; + removeListener(event: 'transactions-updated', listener: Function): this; + /** + * whether a user can make a payment. + */ + canMakePayments(): boolean; + /** + * Completes all pending transactions. + */ + finishAllTransactions(): void; + /** + * Completes the pending transactions corresponding to the date. + */ + finishTransactionByDate(date: string): void; + /** + * Resolves with an array of `Product` objects. + * +Retrieves the product descriptions. + */ + getProducts(productIDs: string[]): Promise; + /** + * the path to the receipt. + */ + getReceiptURL(): string; + /** + * Returns `true` if the product is valid and added to the payment queue. + * + * You should listen for the `transactions-updated` event as soon as possible and + * certainly before you call `purchaseProduct`. + */ + purchaseProduct(productID: string, quantity?: number): Promise; + /** + * Restores finished transactions. This method can be called either to install + * purchases on additional devices, or to restore purchases for an application that + * the user deleted and reinstalled. + * + * The payment queue delivers a new transaction for each previously completed + * transaction that can be restored. Each transaction includes a copy of the + * original transaction. + */ + restoreCompletedTransactions(): void; + } + + class IncomingMessage extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/incoming-message + + /** + * Emitted when a request has been canceled during an ongoing HTTP transaction. + */ + on(event: 'aborted', listener: Function): this; + once(event: 'aborted', listener: Function): this; + addListener(event: 'aborted', listener: Function): this; + removeListener(event: 'aborted', listener: Function): this; + /** + * The `data` event is the usual method of transferring response data into + * applicative code. + */ + on(event: 'data', listener: ( + /** + * A chunk of response body's data. + */ + chunk: Buffer) => void): this; + once(event: 'data', listener: ( + /** + * A chunk of response body's data. + */ + chunk: Buffer) => void): this; + addListener(event: 'data', listener: ( + /** + * A chunk of response body's data. + */ + chunk: Buffer) => void): this; + removeListener(event: 'data', listener: ( + /** + * A chunk of response body's data. + */ + chunk: Buffer) => void): this; + /** + * Indicates that response body has ended. Must be placed before 'data' event. + */ + on(event: 'end', listener: Function): this; + once(event: 'end', listener: Function): this; + addListener(event: 'end', listener: Function): this; + removeListener(event: 'end', listener: Function): this; + /** + * Returns: + * + * `error` Error - Typically holds an error string identifying failure root cause. + * + * Emitted when an error was encountered while streaming response data events. For + * instance, if the server closes the underlying while the response is still + * streaming, an `error` event will be emitted on the response object and a `close` + * event will subsequently follow on the request object. + */ + on(event: 'error', listener: Function): this; + once(event: 'error', listener: Function): this; + addListener(event: 'error', listener: Function): this; + removeListener(event: 'error', listener: Function): this; + headers: Record; + httpVersion: string; + httpVersionMajor: number; + httpVersionMinor: number; + statusCode: number; + statusMessage: string; + } + + interface InputEvent { + + // Docs: https://electronjs.org/docs/api/structures/input-event + + /** + * An array of modifiers of the event, can be `shift`, `control`, `ctrl`, `alt`, + * `meta`, `command`, `cmd`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, + * `middleButtonDown`, `rightButtonDown`, `capsLock`, `numLock`, `left`, `right`. + */ + modifiers?: Array<'shift' | 'control' | 'ctrl' | 'alt' | 'meta' | 'command' | 'cmd' | 'isKeypad' | 'isAutoRepeat' | 'leftButtonDown' | 'middleButtonDown' | 'rightButtonDown' | 'capsLock' | 'numLock' | 'left' | 'right'>; + } + + interface IOCounters { + + // Docs: https://electronjs.org/docs/api/structures/io-counters + + /** + * Then number of I/O other operations. + */ + otherOperationCount: number; + /** + * Then number of I/O other transfers. + */ + otherTransferCount: number; + /** + * The number of I/O read operations. + */ + readOperationCount: number; + /** + * The number of I/O read transfers. + */ + readTransferCount: number; + /** + * The number of I/O write operations. + */ + writeOperationCount: number; + /** + * The number of I/O write transfers. + */ + writeTransferCount: number; + } + + interface IpcMain extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/ipc-main + + /** + * Adds a handler for an `invoke`able IPC. This handler will be called whenever a + * renderer calls `ipcRenderer.invoke(channel, ...args)`. + * + * If `listener` returns a Promise, the eventual result of the promise will be + * returned as a reply to the remote caller. Otherwise, the return value of the + * listener will be used as the value of the reply. + * + * The `event` that is passed as the first argument to the handler is the same as + * that passed to a regular event listener. It includes information about which + * WebContents is the source of the invoke request. + * + * Errors thrown through `handle` in the main process are not transparent as they + * are serialized and only the `message` property from the original error is + * provided to the renderer process. Please refer to #24427 for details. + */ + handle(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => (Promise) | (any)): void; + /** + * Handles a single `invoke`able IPC message, then removes the listener. See + * `ipcMain.handle(channel, listener)`. + */ + handleOnce(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => (Promise) | (any)): void; + /** + * Listens to `channel`, when a new message arrives `listener` would be called with + * `listener(event, args...)`. + */ + on(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this; + /** + * Adds a one time `listener` function for the event. This `listener` is invoked + * only the next time a message is sent to `channel`, after which it is removed. + */ + once(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this; + /** + * Removes listeners of the specified `channel`. + */ + removeAllListeners(channel?: string): this; + /** + * Removes any handler for `channel`, if present. + */ + removeHandler(channel: string): void; + /** + * Removes the specified `listener` from the listener array for the specified + * `channel`. + */ + removeListener(channel: string, listener: (...args: any[]) => void): this; + } + + interface IpcMainEvent extends Event { + + // Docs: https://electronjs.org/docs/api/structures/ipc-main-event + + /** + * The ID of the renderer frame that sent this message + */ + frameId: number; + /** + * A list of MessagePorts that were transferred with this message + */ + ports: MessagePortMain[]; + /** + * The internal ID of the renderer process that sent this message + */ + processId: number; + /** + * A function that will send an IPC message to the renderer frame that sent the + * original message that you are currently handling. You should use this method to + * "reply" to the sent message in order to guarantee the reply will go to the + * correct process and frame. + */ + reply: Function; + /** + * Set this to the value to be returned in a synchronous message + */ + returnValue: any; + /** + * Returns the `webContents` that sent the message + */ + sender: WebContents; + /** + * The frame that sent this message + * + */ + readonly senderFrame: WebFrameMain; + } + + interface IpcMainInvokeEvent extends Event { + + // Docs: https://electronjs.org/docs/api/structures/ipc-main-invoke-event + + /** + * The ID of the renderer frame that sent this message + */ + frameId: number; + /** + * The internal ID of the renderer process that sent this message + */ + processId: number; + /** + * Returns the `webContents` that sent the message + */ + sender: WebContents; + /** + * The frame that sent this message + * + */ + readonly senderFrame: WebFrameMain; + } + + interface IpcRenderer extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/ipc-renderer + + /** + * Resolves with the response from the main process. + * + * Send a message to the main process via `channel` and expect a result + * asynchronously. Arguments will be serialized with the Structured Clone + * Algorithm, just like `window.postMessage`, so prototype chains will not be + * included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw + * an exception. + * + * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special + * Electron objects will throw an exception. + * + * Since the main process does not have support for DOM objects such as + * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over + * Electron's IPC to the main process, as the main process would have no way to + * decode them. Attempting to send such objects over IPC will result in an error. + * + * The main process should listen for `channel` with `ipcMain.handle()`. + * + * For example: + * + * If you need to transfer a `MessagePort` to the main process, use + * `ipcRenderer.postMessage`. + * + * If you do not need a response to the message, consider using `ipcRenderer.send`. + */ + invoke(channel: string, ...args: any[]): Promise; + /** + * Listens to `channel`, when a new message arrives `listener` would be called with + * `listener(event, args...)`. + */ + on(channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void): this; + /** + * Adds a one time `listener` function for the event. This `listener` is invoked + * only the next time a message is sent to `channel`, after which it is removed. + */ + once(channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void): this; + /** + * Send a message to the main process, optionally transferring ownership of zero or + * more `MessagePort` objects. + * + * The transferred `MessagePort` objects will be available in the main process as + * `MessagePortMain` objects by accessing the `ports` property of the emitted + * event. + * + * For example: + * + * For more information on using `MessagePort` and `MessageChannel`, see the MDN + * documentation. + */ + postMessage(channel: string, message: any, transfer?: MessagePort[]): void; + /** + * Removes all listeners, or those of the specified `channel`. + */ + removeAllListeners(channel: string): this; + /** + * Removes the specified `listener` from the listener array for the specified + * `channel`. + */ + removeListener(channel: string, listener: (...args: any[]) => void): this; + /** + * Send an asynchronous message to the main process via `channel`, along with + * arguments. Arguments will be serialized with the Structured Clone Algorithm, + * just like `window.postMessage`, so prototype chains will not be included. + * Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an + * exception. + * + * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special + * Electron objects will throw an exception. + * + * Since the main process does not have support for DOM objects such as + * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over + * Electron's IPC to the main process, as the main process would have no way to + * decode them. Attempting to send such objects over IPC will result in an error. + * + * The main process handles it by listening for `channel` with the `ipcMain` + * module. + * + * If you need to transfer a `MessagePort` to the main process, use + * `ipcRenderer.postMessage`. + * + * If you want to receive a single response from the main process, like the result + * of a method call, consider using `ipcRenderer.invoke`. + */ + send(channel: string, ...args: any[]): void; + /** + * The value sent back by the `ipcMain` handler. + * + * Send a message to the main process via `channel` and expect a result + * synchronously. Arguments will be serialized with the Structured Clone Algorithm, + * just like `window.postMessage`, so prototype chains will not be included. + * Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an + * exception. + * + * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special + * Electron objects will throw an exception. + * + * Since the main process does not have support for DOM objects such as + * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over + * Electron's IPC to the main process, as the main process would have no way to + * decode them. Attempting to send such objects over IPC will result in an error. + * + * The main process handles it by listening for `channel` with `ipcMain` module, + * and replies by setting `event.returnValue`. + * + * > :warning: **WARNING**: Sending a synchronous message will block the whole + * renderer process until the reply is received, so use this method only as a last + * resort. It's much better to use the asynchronous version, `invoke()`. + */ + sendSync(channel: string, ...args: any[]): any; + /** + * Sends a message to a window with `webContentsId` via `channel`. + */ + sendTo(webContentsId: number, channel: string, ...args: any[]): void; + /** + * Like `ipcRenderer.send` but the event will be sent to the `` element in + * the host page instead of the main process. + */ + sendToHost(channel: string, ...args: any[]): void; + } + + interface IpcRendererEvent extends Event { + + // Docs: https://electronjs.org/docs/api/structures/ipc-renderer-event + + /** + * A list of MessagePorts that were transferred with this message + */ + ports: MessagePort[]; + /** + * The `IpcRenderer` instance that emitted the event originally + */ + sender: IpcRenderer; + /** + * The `webContents.id` that sent the message, you can call + * `event.sender.sendTo(event.senderId, ...)` to reply to the message, see + * ipcRenderer.sendTo for more information. This only applies to messages sent from + * a different renderer. Messages sent directly from the main process set + * `event.senderId` to `0`. + */ + senderId: number; + } + + interface JumpListCategory { + + // Docs: https://electronjs.org/docs/api/structures/jump-list-category + + /** + * Array of `JumpListItem` objects if `type` is `tasks` or `custom`, otherwise it + * should be omitted. + */ + items?: JumpListItem[]; + /** + * Must be set if `type` is `custom`, otherwise it should be omitted. + */ + name?: string; + /** + * One of the following: + */ + type?: ('tasks' | 'frequent' | 'recent' | 'custom'); + } + + interface JumpListItem { + + // Docs: https://electronjs.org/docs/api/structures/jump-list-item + + /** + * The command line arguments when `program` is executed. Should only be set if + * `type` is `task`. + */ + args?: string; + /** + * Description of the task (displayed in a tooltip). Should only be set if `type` + * is `task`. Maximum length 260 characters. + */ + description?: string; + /** + * The index of the icon in the resource file. If a resource file contains multiple + * icons this value can be used to specify the zero-based index of the icon that + * should be displayed for this task. If a resource file contains only one icon, + * this property should be set to zero. + */ + iconIndex?: number; + /** + * The absolute path to an icon to be displayed in a Jump List, which can be an + * arbitrary resource file that contains an icon (e.g. `.ico`, `.exe`, `.dll`). You + * can usually specify `process.execPath` to show the program icon. + */ + iconPath?: string; + /** + * Path of the file to open, should only be set if `type` is `file`. + */ + path?: string; + /** + * Path of the program to execute, usually you should specify `process.execPath` + * which opens the current program. Should only be set if `type` is `task`. + */ + program?: string; + /** + * The text to be displayed for the item in the Jump List. Should only be set if + * `type` is `task`. + */ + title?: string; + /** + * One of the following: + */ + type?: ('task' | 'separator' | 'file'); + /** + * The working directory. Default is empty. + */ + workingDirectory?: string; + } + + interface KeyboardEvent { + + // Docs: https://electronjs.org/docs/api/structures/keyboard-event + + /** + * whether an Alt key was used in an accelerator to trigger the Event + */ + altKey?: boolean; + /** + * whether the Control key was used in an accelerator to trigger the Event + */ + ctrlKey?: boolean; + /** + * whether a meta key was used in an accelerator to trigger the Event + */ + metaKey?: boolean; + /** + * whether a Shift key was used in an accelerator to trigger the Event + */ + shiftKey?: boolean; + /** + * whether an accelerator was used to trigger the event as opposed to another user + * gesture like mouse click + */ + triggeredByAccelerator?: boolean; + } + + interface KeyboardInputEvent extends InputEvent { + + // Docs: https://electronjs.org/docs/api/structures/keyboard-input-event + + /** + * The character that will be sent as the keyboard event. Should only use the valid + * key codes in Accelerator. + */ + keyCode: string; + /** + * The type of the event, can be `keyDown`, `keyUp` or `char`. + */ + type: ('keyDown' | 'keyUp' | 'char'); + } + + interface MemoryInfo { + + // Docs: https://electronjs.org/docs/api/structures/memory-info + + /** + * The maximum amount of memory that has ever been pinned to actual physical RAM. + */ + peakWorkingSetSize: number; + /** + * The amount of memory not shared by other processes, such as JS heap or HTML + * content. + * + * @platform win32 + */ + privateBytes?: number; + /** + * The amount of memory currently pinned to actual physical RAM. + */ + workingSetSize: number; + } + + interface MemoryUsageDetails { + + // Docs: https://electronjs.org/docs/api/structures/memory-usage-details + + count: number; + liveSize: number; + size: number; + } + + class Menu { + + // Docs: https://electronjs.org/docs/api/menu + + /** + * Emitted when a popup is closed either manually or with `menu.closePopup()`. + */ + on(event: 'menu-will-close', listener: (event: Event) => void): this; + once(event: 'menu-will-close', listener: (event: Event) => void): this; + addListener(event: 'menu-will-close', listener: (event: Event) => void): this; + removeListener(event: 'menu-will-close', listener: (event: Event) => void): this; + /** + * Emitted when `menu.popup()` is called. + */ + on(event: 'menu-will-show', listener: (event: Event) => void): this; + once(event: 'menu-will-show', listener: (event: Event) => void): this; + addListener(event: 'menu-will-show', listener: (event: Event) => void): this; + removeListener(event: 'menu-will-show', listener: (event: Event) => void): this; + /** + * Menu + */ + constructor(); + /** + * Generally, the `template` is an array of `options` for constructing a MenuItem. + * The usage can be referenced above. + * + * You can also attach other fields to the element of the `template` and they will + * become properties of the constructed menu items. + */ + static buildFromTemplate(template: Array<(MenuItemConstructorOptions) | (MenuItem)>): Menu; + /** + * The application menu, if set, or `null`, if not set. + * + * **Note:** The returned `Menu` instance doesn't support dynamic addition or + * removal of menu items. Instance properties can still be dynamically modified. + */ + static getApplicationMenu(): (Menu) | (null); + /** + * Sends the `action` to the first responder of application. This is used for + * emulating default macOS menu behaviors. Usually you would use the `role` + * property of a `MenuItem`. + * + * See the macOS Cocoa Event Handling Guide for more information on macOS' native + * actions. + * + * @platform darwin + */ + static sendActionToFirstResponder(action: string): void; + /** + * Sets `menu` as the application menu on macOS. On Windows and Linux, the `menu` + * will be set as each window's top menu. + * + * Also on Windows and Linux, you can use a `&` in the top-level item name to + * indicate which letter should get a generated accelerator. For example, using + * `&File` for the file menu would result in a generated `Alt-F` accelerator that + * opens the associated menu. The indicated character in the button label then gets + * an underline, and the `&` character is not displayed on the button label. + * + * In order to escape the `&` character in an item name, add a proceeding `&`. For + * example, `&&File` would result in `&File` displayed on the button label. + * + * Passing `null` will suppress the default menu. On Windows and Linux, this has + * the additional effect of removing the menu bar from the window. + * + * **Note:** The default menu will be created automatically if the app does not set + * one. It contains standard items such as `File`, `Edit`, `View`, `Window` and + * `Help`. + */ + static setApplicationMenu(menu: (Menu) | (null)): void; + /** + * Appends the `menuItem` to the menu. + */ + append(menuItem: MenuItem): void; + /** + * Closes the context menu in the `browserWindow`. + */ + closePopup(browserWindow?: BrowserWindow): void; + /** + * the item with the specified `id` + */ + getMenuItemById(id: string): (MenuItem) | (null); + /** + * Inserts the `menuItem` to the `pos` position of the menu. + */ + insert(pos: number, menuItem: MenuItem): void; + /** + * Pops up this menu as a context menu in the `BrowserWindow`. + */ + popup(options?: PopupOptions): void; + items: MenuItem[]; + } + + class MenuItem { + + // Docs: https://electronjs.org/docs/api/menu-item + + /** + * MenuItem + */ + constructor(options: MenuItemConstructorOptions); + accelerator?: Accelerator; + checked: boolean; + click: Function; + commandId: number; + enabled: boolean; + icon?: (NativeImage) | (string); + id: string; + label: string; + menu: Menu; + registerAccelerator: boolean; + role?: ('undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteAndMatchStyle' | 'delete' | 'selectAll' | 'reload' | 'forceReload' | 'toggleDevTools' | 'resetZoom' | 'zoomIn' | 'zoomOut' | 'togglefullscreen' | 'window' | 'minimize' | 'close' | 'help' | 'about' | 'services' | 'hide' | 'hideOthers' | 'unhide' | 'quit' | 'startSpeaking' | 'stopSpeaking' | 'zoom' | 'front' | 'appMenu' | 'fileMenu' | 'editMenu' | 'viewMenu' | 'recentDocuments' | 'toggleTabBar' | 'selectNextTab' | 'selectPreviousTab' | 'mergeAllWindows' | 'clearRecentDocuments' | 'moveTabToNewWindow' | 'windowMenu'); + sharingItem: SharingItem; + sublabel: string; + submenu?: Menu; + toolTip: string; + type: ('normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'); + visible: boolean; + } + + class MessageChannelMain extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/message-channel-main + + port1: MessagePortMain; + port2: MessagePortMain; + } + + class MessagePortMain extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/message-port-main + + /** + * Emitted when the remote end of a MessagePortMain object becomes disconnected. + */ + on(event: 'close', listener: Function): this; + once(event: 'close', listener: Function): this; + addListener(event: 'close', listener: Function): this; + removeListener(event: 'close', listener: Function): this; + /** + * Emitted when a MessagePortMain object receives a message. + */ + on(event: 'message', listener: (messageEvent: MessageEvent) => void): this; + once(event: 'message', listener: (messageEvent: MessageEvent) => void): this; + addListener(event: 'message', listener: (messageEvent: MessageEvent) => void): this; + removeListener(event: 'message', listener: (messageEvent: MessageEvent) => void): this; + /** + * Disconnects the port, so it is no longer active. + */ + close(): void; + /** + * Sends a message from the port, and optionally, transfers ownership of objects to + * other browsing contexts. + */ + postMessage(message: any, transfer?: MessagePortMain[]): void; + /** + * Starts the sending of messages queued on the port. Messages will be queued until + * this method is called. + */ + start(): void; + } + + interface MimeTypedBuffer { + + // Docs: https://electronjs.org/docs/api/structures/mime-typed-buffer + + /** + * Charset of the buffer. + */ + charset?: string; + /** + * The actual Buffer content. + */ + data: Buffer; + /** + * MIME type of the buffer. + */ + mimeType?: string; + } + + interface MouseInputEvent extends InputEvent { + + // Docs: https://electronjs.org/docs/api/structures/mouse-input-event + + /** + * The button pressed, can be `left`, `middle`, `right`. + */ + button?: ('left' | 'middle' | 'right'); + clickCount?: number; + globalX?: number; + globalY?: number; + movementX?: number; + movementY?: number; + /** + * The type of the event, can be `mouseDown`, `mouseUp`, `mouseEnter`, + * `mouseLeave`, `contextMenu`, `mouseWheel` or `mouseMove`. + */ + type: ('mouseDown' | 'mouseUp' | 'mouseEnter' | 'mouseLeave' | 'contextMenu' | 'mouseWheel' | 'mouseMove'); + x: number; + y: number; + } + + interface MouseWheelInputEvent extends MouseInputEvent { + + // Docs: https://electronjs.org/docs/api/structures/mouse-wheel-input-event + + accelerationRatioX?: number; + accelerationRatioY?: number; + canScroll?: boolean; + deltaX?: number; + deltaY?: number; + hasPreciseScrollingDeltas?: boolean; + /** + * The type of the event, can be `mouseWheel`. + */ + type: ('mouseWheel'); + wheelTicksX?: number; + wheelTicksY?: number; + } + + class NativeImage { + + // Docs: https://electronjs.org/docs/api/native-image + + /** + * Creates an empty `NativeImage` instance. + */ + static createEmpty(): NativeImage; + /** + * Creates a new `NativeImage` instance from `buffer` that contains the raw bitmap + * pixel data returned by `toBitmap()`. The specific format is platform-dependent. + */ + static createFromBitmap(buffer: Buffer, options: CreateFromBitmapOptions): NativeImage; + /** + * Creates a new `NativeImage` instance from `buffer`. Tries to decode as PNG or + * JPEG first. + */ + static createFromBuffer(buffer: Buffer, options?: CreateFromBufferOptions): NativeImage; + /** + * Creates a new `NativeImage` instance from `dataURL`. + */ + static createFromDataURL(dataURL: string): NativeImage; + /** + * Creates a new `NativeImage` instance from the NSImage that maps to the given + * image name. See `System Icons` for a list of possible values. + * + * The `hslShift` is applied to the image with the following rules: + * + * * `hsl_shift[0]` (hue): The absolute hue value for the image - 0 and 1 map to 0 + * and 360 on the hue color wheel (red). + * * `hsl_shift[1]` (saturation): A saturation shift for the image, with the + * following key values: 0 = remove all color. 0.5 = leave unchanged. 1 = fully + * saturate the image. + * * `hsl_shift[2]` (lightness): A lightness shift for the image, with the + * following key values: 0 = remove all lightness (make all pixels black). 0.5 = + * leave unchanged. 1 = full lightness (make all pixels white). + * + * This means that `[-1, 0, 1]` will make the image completely white and `[-1, 1, + * 0]` will make the image completely black. + * + * In some cases, the `NSImageName` doesn't match its string representation; one + * example of this is `NSFolderImageName`, whose string representation would + * actually be `NSFolder`. Therefore, you'll need to determine the correct string + * representation for your image before passing it in. This can be done with the + * following: + * + * `echo -e '#import \nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); + * }' | clang -otest -x objective-c -framework Cocoa - && ./test` + * +where `SYSTEM_IMAGE_NAME` should be replaced with any value from this list. + * + * @platform darwin + */ + static createFromNamedImage(imageName: string, hslShift?: number[]): NativeImage; + /** + * Creates a new `NativeImage` instance from a file located at `path`. This method + * returns an empty image if the `path` does not exist, cannot be read, or is not a + * valid image. + */ + static createFromPath(path: string): NativeImage; + /** + * fulfilled with the file's thumbnail preview image, which is a NativeImage. + * + * @platform darwin,win32 + */ + static createThumbnailFromPath(path: string, maxSize: Size): Promise; + /** + * Add an image representation for a specific scale factor. This can be used to + * explicitly add different scale factor representations to an image. This can be + * called on empty images. + */ + addRepresentation(options: AddRepresentationOptions): void; + /** + * The cropped image. + */ + crop(rect: Rectangle): NativeImage; + /** + * The image's aspect ratio. + * + * If `scaleFactor` is passed, this will return the aspect ratio corresponding to + * the image representation most closely matching the passed value. + */ + getAspectRatio(scaleFactor?: number): number; + /** + * A Buffer that contains the image's raw bitmap pixel data. + * + * The difference between `getBitmap()` and `toBitmap()` is that `getBitmap()` does + * not copy the bitmap data, so you have to use the returned Buffer immediately in + * current event loop tick; otherwise the data might be changed or destroyed. + */ + getBitmap(options?: BitmapOptions): Buffer; + /** + * A Buffer that stores C pointer to underlying native handle of the image. On + * macOS, a pointer to `NSImage` instance would be returned. + * + * Notice that the returned pointer is a weak pointer to the underlying native + * image instead of a copy, so you _must_ ensure that the associated `nativeImage` + * instance is kept around. + * + * @platform darwin + */ + getNativeHandle(): Buffer; + /** + * An array of all scale factors corresponding to representations for a given + * nativeImage. + */ + getScaleFactors(): number[]; + /** + * If `scaleFactor` is passed, this will return the size corresponding to the image + * representation most closely matching the passed value. + */ + getSize(scaleFactor?: number): Size; + /** + * Whether the image is empty. + */ + isEmpty(): boolean; + /** + * Whether the image is a template image. + */ + isTemplateImage(): boolean; + /** + * The resized image. + * + * If only the `height` or the `width` are specified then the current aspect ratio + * will be preserved in the resized image. + */ + resize(options: ResizeOptions): NativeImage; + /** + * Marks the image as a template image. + */ + setTemplateImage(option: boolean): void; + /** + * A Buffer that contains a copy of the image's raw bitmap pixel data. + */ + toBitmap(options?: ToBitmapOptions): Buffer; + /** + * The data URL of the image. + */ + toDataURL(options?: ToDataURLOptions): string; + /** + * A Buffer that contains the image's `JPEG` encoded data. + */ + toJPEG(quality: number): Buffer; + /** + * A Buffer that contains the image's `PNG` encoded data. + */ + toPNG(options?: ToPNGOptions): Buffer; + isMacTemplateImage: boolean; + } + + interface NativeTheme extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/native-theme + + /** + * Emitted when something in the underlying NativeTheme has changed. This normally + * means that either the value of `shouldUseDarkColors`, + * `shouldUseHighContrastColors` or `shouldUseInvertedColorScheme` has changed. You + * will have to check them to determine which one has changed. + */ + on(event: 'updated', listener: Function): this; + once(event: 'updated', listener: Function): this; + addListener(event: 'updated', listener: Function): this; + removeListener(event: 'updated', listener: Function): this; + /** + * A `Boolean` for if the OS / Chromium currently has a dark mode enabled or is + * being instructed to show a dark-style UI. If you want to modify this value you + * should use `themeSource` below. + * + */ + readonly shouldUseDarkColors: boolean; + /** + * A `Boolean` for if the OS / Chromium currently has high-contrast mode enabled or + * is being instructed to show a high-contrast UI. + * + * @platform darwin,win32 + */ + readonly shouldUseHighContrastColors: boolean; + /** + * A `Boolean` for if the OS / Chromium currently has an inverted color scheme or + * is being instructed to use an inverted color scheme. + * + * @platform darwin,win32 + */ + readonly shouldUseInvertedColorScheme: boolean; + /** + * A `String` property that can be `system`, `light` or `dark`. It is used to + * override and supersede the value that Chromium has chosen to use internally. + * + * Setting this property to `system` will remove the override and everything will + * be reset to the OS default. By default `themeSource` is `system`. + * + * Settings this property to `dark` will have the following effects: + * + * * `nativeTheme.shouldUseDarkColors` will be `true` when accessed + * * Any UI Electron renders on Linux and Windows including context menus, + * devtools, etc. will use the dark UI. + * * Any UI the OS renders on macOS including menus, window frames, etc. will use + * the dark UI. + * * The `prefers-color-scheme` CSS query will match `dark` mode. + * * The `updated` event will be emitted + * + * Settings this property to `light` will have the following effects: + * + * * `nativeTheme.shouldUseDarkColors` will be `false` when accessed + * * Any UI Electron renders on Linux and Windows including context menus, + * devtools, etc. will use the light UI. + * * Any UI the OS renders on macOS including menus, window frames, etc. will use + * the light UI. + * * The `prefers-color-scheme` CSS query will match `light` mode. + * * The `updated` event will be emitted + * + * The usage of this property should align with a classic "dark mode" state machine + * in your application where the user has three options. + * + * * `Follow OS` --> `themeSource = 'system'` + * * `Dark Mode` --> `themeSource = 'dark'` + * * `Light Mode` --> `themeSource = 'light'` + * + * Your application should then always use `shouldUseDarkColors` to determine what + * CSS to apply. + */ + themeSource: ('system' | 'light' | 'dark'); + } + + interface Net { + + // Docs: https://electronjs.org/docs/api/net + + /** + * Whether there is currently internet connection. + * + * A return value of `false` is a pretty strong indicator that the user won't be + * able to connect to remote sites. However, a return value of `true` is + * inconclusive; even if some link is up, it is uncertain whether a particular + * connection attempt to a particular remote site will be successful. + */ + isOnline(): boolean; + /** + * Creates a `ClientRequest` instance using the provided `options` which are + * directly forwarded to the `ClientRequest` constructor. The `net.request` method + * would be used to issue both secure and insecure HTTP requests according to the + * specified protocol scheme in the `options` object. + */ + request(options: (ClientRequestConstructorOptions) | (string)): ClientRequest; + /** + * A `Boolean` property. Whether there is currently internet connection. + * + * A return value of `false` is a pretty strong indicator that the user won't be + * able to connect to remote sites. However, a return value of `true` is + * inconclusive; even if some link is up, it is uncertain whether a particular + * connection attempt to a particular remote site will be successful. + * + */ + readonly online: boolean; + } + + interface NetLog { + + // Docs: https://electronjs.org/docs/api/net-log + + /** + * resolves when the net log has begun recording. + * +Starts recording network events to `path`. + */ + startLogging(path: string, options?: StartLoggingOptions): Promise; + /** + * resolves when the net log has been flushed to disk. + * + * Stops recording network events. If not called, net logging will automatically + * end when app quits. + */ + stopLogging(): Promise; + /** + * A `Boolean` property that indicates whether network logs are currently being + * recorded. + * + */ + readonly currentlyLogging: boolean; + } + + interface NewWindowWebContentsEvent extends Event { + + // Docs: https://electronjs.org/docs/api/structures/new-window-web-contents-event + + newGuest?: BrowserWindow; + } + + class Notification extends NodeEventEmitter { + + // Docs: https://electronjs.org/docs/api/notification + + on(event: 'action', listener: (event: Event, + /** + * The index of the action that was activated. + */ + index: number) => void): this; + once(event: 'action', listener: (event: Event, + /** + * The index of the action that was activated. + */ + index: number) => void): this; + addListener(event: 'action', listener: (event: Event, + /** + * The index of the action that was activated. + */ + index: number) => void): this; + removeListener(event: 'action', listener: (event: Event, + /** + * The index of the action that was activated. + */ + index: number) => void): this; + /** + * Emitted when the notification is clicked by the user. + */ + on(event: 'click', listener: (event: Event) => void): this; + once(event: 'click', listener: (event: Event) => void): this; + addListener(event: 'click', listener: (event: Event) => void): this; + removeListener(event: 'click', listener: (event: Event) => void): this; + /** + * Emitted when the notification is closed by manual intervention from the user. + * + * This event is not guaranteed to be emitted in all cases where the notification + * is closed. + */ + on(event: 'close', listener: (event: Event) => void): this; + once(event: 'close', listener: (event: Event) => void): this; + addListener(event: 'close', listener: (event: Event) => void): this; + removeListener(event: 'close', listener: (event: Event) => void): this; + /** + * Emitted when an error is encountered while creating and showing the native + * notification. + * + * @platform win32 + */ + on(event: 'failed', listener: (event: Event, + /** + * The error encountered during execution of the `show()` method. + */ + error: string) => void): this; + once(event: 'failed', listener: (event: Event, + /** + * The error encountered during execution of the `show()` method. + */ + error: string) => void): this; + addListener(event: 'failed', listener: (event: Event, + /** + * The error encountered during execution of the `show()` method. + */ + error: string) => void): this; + removeListener(event: 'failed', listener: (event: Event, + /** + * The error encountered during execution of the `show()` method. + */ + error: string) => void): this; + /** + * Emitted when the user clicks the "Reply" button on a notification with + * `hasReply: true`. + * + * @platform darwin + */ + on(event: 'reply', listener: (event: Event, + /** + * The string the user entered into the inline reply field. + */ + reply: string) => void): this; + once(event: 'reply', listener: (event: Event, + /** + * The string the user entered into the inline reply field. + */ + reply: string) => void): this; + addListener(event: 'reply', listener: (event: Event, + /** + * The string the user entered into the inline reply field. + */ + reply: string) => void): this; + removeListener(event: 'reply', listener: (event: Event, + /** + * The string the user entered into the inline reply field. + */ + reply: string) => void): this; + /** + * Emitted when the notification is shown to the user, note this could be fired + * multiple times as a notification can be shown multiple times through the + * `show()` method. + */ + on(event: 'show', listener: (event: Event) => void): this; + once(event: 'show', listener: (event: Event) => void): this; + addListener(event: 'show', listener: (event: Event) => void): this; + removeListener(event: 'show', listener: (event: Event) => void): this; + /** + * Notification + */ + constructor(options?: NotificationConstructorOptions); + /** + * Whether or not desktop notifications are supported on the current system + */ + static isSupported(): boolean; + /** + * Dismisses the notification. + */ + close(): void; + /** + * Immediately shows the notification to the user, please note this means unlike + * the HTML5 Notification implementation, instantiating a `new Notification` does + * not immediately show it to the user, you need to call this method before the OS + * will display it. + * + * If the notification has been shown before, this method will dismiss the + * previously shown notification and create a new one with identical properties. + */ + show(): void; + actions: NotificationAction[]; + body: string; + closeButtonText: string; + hasReply: boolean; + replyPlaceholder: string; + silent: boolean; + sound: string; + subtitle: string; + timeoutType: ('default' | 'never'); + title: string; + toastXml: string; + urgency: ('normal' | 'critical' | 'low'); + } + + interface NotificationAction { + + // Docs: https://electronjs.org/docs/api/structures/notification-action + + /** + * The label for the given action. + */ + text?: string; + /** + * The type of action, can be `button`. + */ + type: ('button'); + } + + interface NotificationResponse { + + // Docs: https://electronjs.org/docs/api/structures/notification-response + + /** + * The identifier string of the action that the user selected. + */ + actionIdentifier: string; + /** + * The delivery date of the notification. + */ + date: number; + /** + * The unique identifier for this notification request. + */ + identifier: string; + /** + * A dictionary of custom information associated with the notification. + */ + userInfo: Record; + /** + * The text entered or chosen by the user. + */ + userText?: string; + } + + interface Point { + + // Docs: https://electronjs.org/docs/api/structures/point + + x: number; + y: number; + } + + interface PostBody { + + // Docs: https://electronjs.org/docs/api/structures/post-body + + /** + * The boundary used to separate multiple parts of the message. Only valid when + * `contentType` is `multipart/form-data`. + */ + boundary?: string; + /** + * The `content-type` header used for the data. One of + * `application/x-www-form-urlencoded` or `multipart/form-data`. Corresponds to the + * `enctype` attribute of the submitted HTML form. + */ + contentType: string; + /** + * The post data to be sent to the new window. + */ + data: Array<(UploadRawData) | (UploadFile)>; + } + + interface PowerMonitor extends NodeJS.EventEmitter { + + // Docs: https://electronjs.org/docs/api/power-monitor + + /** + * Emitted when the system is about to lock the screen. + * + * @platform darwin,win32 + */ + on(event: 'lock-screen', listener: Function): this; + once(event: 'lock-screen', listener: Function): this; + addListener(event: 'lock-screen', listener: Function): this; + removeListener(event: 'lock-screen', listener: Function): this; + /** + * Emitted when the system changes to AC power. + * + * @platform darwin,win32 + */ + on(event: 'on-ac', listener: Function): this; + once(event: 'on-ac', listener: Function): this; + addListener(event: 'on-ac', listener: Function): this; + removeListener(event: 'on-ac', listener: Function): this; + /** + * Emitted when system changes to battery power. + * + * @platform darwin + */ + on(event: 'on-battery', listener: Function): this; + once(event: 'on-battery', listener: Function): this; + addListener(event: 'on-battery', listener: Function): this; + removeListener(event: 'on-battery', listener: Function): this; + /** + * Emitted when system is resuming. + * + * @platform darwin,win32 + */ + on(event: 'resume', listener: Function): this; + once(event: 'resume', listener: Function): this; + addListener(event: 'resume', listener: Function): this; + removeListener(event: 'resume', listener: Function): this; + /** + * Emitted when the system is about to reboot or shut down. If the event handler + * invokes `e.preventDefault()`, Electron will attempt to delay system shutdown in + * order for the app to exit cleanly. If `e.preventDefault()` is called, the app + * should exit as soon as possible by calling something like `app.quit()`. + * + * @platform linux,darwin + */ + on(event: 'shutdown', listener: Function): this; + once(event: 'shutdown', listener: Function): this; + addListener(event: 'shutdown', listener: Function): this; + removeListener(event: 'shutdown', listener: Function): this; + /** + * Emitted when the system is suspending. + * + * @platform darwin,win32 + */ + on(event: 'suspend', listener: Function): this; + once(event: 'suspend', listener: Function): this; + addListener(event: 'suspend', listener: Function): this; + removeListener(event: 'suspend', listener: Function): this; + /** + * Emitted as soon as the systems screen is unlocked. + * + * @platform darwin,win32 + */ + on(event: 'unlock-screen', listener: Function): this; + once(event: 'unlock-screen', listener: Function): this; + addListener(event: 'unlock-screen', listener: Function): this; + removeListener(event: 'unlock-screen', listener: Function): this; + /** + * Emitted when a login session is activated. See documentation for more + * information. + * + * @platform darwin + */ + on(event: 'user-did-become-active', listener: Function): this; + once(event: 'user-did-become-active', listener: Function): this; + addListener(event: 'user-did-become-active', listener: Function): this; + removeListener(event: 'user-did-become-active', listener: Function): this; + /** + * Emitted when a login session is deactivated. See documentation for more + * information. + * + * @platform darwin + */ + on(event: 'user-did-resign-active', listener: Function): this; + once(event: 'user-did-resign-active', listener: Function): this; + addListener(event: 'user-did-resign-active', listener: Function): this; + removeListener(event: 'user-did-resign-active', listener: Function): this; + /** + * The system's current state. Can be `active`, `idle`, `locked` or `unknown`. + * + * Calculate the system idle state. `idleThreshold` is the amount of time (in + * seconds) before considered idle. `locked` is available on supported systems + * only. + */ + getSystemIdleState(idleThreshold: number): ('active' | 'idle' | 'locked' | 'unknown'); + /** + * Idle time in seconds + +Calculate system idle time in seconds. + */ + getSystemIdleTime(): number; + /** + * Whether the system is on battery power. + * + * To monitor for changes in this property, use the `on-battery` and `on-ac` + * events. + */ + isOnBatteryPower(): boolean; + /** + * A `Boolean` property. True if the system is on battery power. + * +See `powerMonitor.isOnBatteryPower()`. + */ + onBatteryPower: boolean; + } + + interface PowerSaveBlocker { + + // Docs: https://electronjs.org/docs/api/power-save-blocker + + /** + * Whether the corresponding `powerSaveBlocker` has started. + */ + isStarted(id: number): boolean; + /** + * The blocker ID that is assigned to this power blocker. + * + * Starts preventing the system from entering lower-power mode. Returns an integer + * identifying the power save blocker. + * + * **Note:** `prevent-display-sleep` has higher precedence over + * `prevent-app-suspension`. Only the highest precedence type takes effect. In + * other words, `prevent-display-sleep` always takes precedence over + * `prevent-app-suspension`. + * + * For example, an API calling A requests for `prevent-app-suspension`, and another + * calling B requests for `prevent-display-sleep`. `prevent-display-sleep` will be + * used until B stops its request. After that, `prevent-app-suspension` is used. + */ + start(type: 'prevent-app-suspension' | 'prevent-display-sleep'): number; + /** + * Stops the specified power save blocker. + */ + stop(id: number): void; + } + + interface PrinterInfo { + + // Docs: https://electronjs.org/docs/api/structures/printer-info + + /** + * a longer description of the printer's type. + */ + description: string; + /** + * the name of the printer as shown in Print Preview. + */ + displayName: string; + /** + * whether or not a given printer is set as the default printer on the OS. + */ + isDefault: boolean; + /** + * the name of the printer as understood by the OS. + */ + name: string; + /** + * an object containing a variable number of platform-specific printer information. + */ + options: Options; + /** + * the current status of the printer. + */ + status: number; + } + + interface ProcessMemoryInfo { + + // Docs: https://electronjs.org/docs/api/structures/process-memory-info + + /** + * The amount of memory not shared by other processes, such as JS heap or HTML + * content in Kilobytes. + */ + private: number; + /** + * The amount of memory currently pinned to actual physical RAM in Kilobytes. + * + * @platform linux,win32 + */ + residentSet: number; + /** + * The amount of memory shared between processes, typically memory consumed by the + * Electron code itself in Kilobytes. + */ + shared: number; + } + + interface ProcessMetric { + + // Docs: https://electronjs.org/docs/api/structures/process-metric + + /** + * CPU usage of the process. + */ + cpu: CPUUsage; + /** + * Creation time for this process. The time is represented as number of + * milliseconds since epoch. Since the `pid` can be reused after a process dies, it + * is useful to use both the `pid` and the `creationTime` to uniquely identify a + * process. + */ + creationTime: number; + /** + * One of the following values: + * + * @platform win32 + */ + integrityLevel?: ('untrusted' | 'low' | 'medium' | 'high' | 'unknown'); + /** + * Memory information for the process. + */ + memory: MemoryInfo; + /** + * The name of the process. Examples for utility: `Audio Service`, `Content + * Decryption Module Service`, `Network Service`, `Video Capture`, etc. + */ + name?: string; + /** + * Process id of the process. + */ + pid: number; + /** + * Whether the process is sandboxed on OS level. + * + * @platform darwin,win32 + */ + sandboxed?: boolean; + /** + * The non-localized name of the process. + */ + serviceName?: string; + /** + * Process type. One of the following values: + */ + type: ('Browser' | 'Tab' | 'Utility' | 'Zygote' | 'Sandbox helper' | 'GPU' | 'Pepper Plugin' | 'Pepper Plugin Broker' | 'Unknown'); + } + + interface Product { + + // Docs: https://electronjs.org/docs/api/structures/product + + /** + * The total size of the content, in bytes. + */ + contentLengths: number[]; + /** + * A string that identifies the version of the content. + */ + contentVersion: string; + /** + * 3 character code presenting a product's currency based on the ISO 4217 standard. + */ + currencyCode: string; + /** + * The locale formatted price of the product. + */ + formattedPrice: string; + /** + * A Boolean value that indicates whether the App Store has downloadable content + * for this product. `true` if at least one file has been associated with the + * product. + */ + isDownloadable: boolean; + /** + * A description of the product. + */ + localizedDescription: string; + /** + * The name of the product. + */ + localizedTitle: string; + /** + * The cost of the product in the local currency. + */ + price: number; + /** + * The string that identifies the product to the Apple App Store. + */ + productIdentifier: string; + } + + interface Protocol { + + // Docs: https://electronjs.org/docs/api/protocol + + /** + * Whether the protocol was successfully intercepted + * + * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler + * which sends a `Buffer` as a response. + */ + interceptBufferProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (Buffer) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether the protocol was successfully intercepted + * + * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler + * which sends a file as a response. + */ + interceptFileProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (string) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether the protocol was successfully intercepted + * + * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler + * which sends a new HTTP request as a response. + */ + interceptHttpProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: ProtocolResponse) => void) => void): boolean; + /** + * Whether the protocol was successfully intercepted + * + * Same as `protocol.registerStreamProtocol`, except that it replaces an existing + * protocol handler. + */ + interceptStreamProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (NodeJS.ReadableStream) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether the protocol was successfully intercepted + * + * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler + * which sends a `String` as a response. + */ + interceptStringProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (string) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether `scheme` is already intercepted. + */ + isProtocolIntercepted(scheme: string): boolean; + /** + * Whether `scheme` is already registered. + */ + isProtocolRegistered(scheme: string): boolean; + /** + * Whether the protocol was successfully registered + * + * Registers a protocol of `scheme` that will send a `Buffer` as a response. + * + * The usage is the same with `registerFileProtocol`, except that the `callback` + * should be called with either a `Buffer` object or an object that has the `data` + * property. + +Example: + */ + registerBufferProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (Buffer) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether the protocol was successfully registered + * + * Registers a protocol of `scheme` that will send a file as the response. The + * `handler` will be called with `request` and `callback` where `request` is an + * incoming request for the `scheme`. + * + * To handle the `request`, the `callback` should be called with either the file's + * path or an object that has a `path` property, e.g. `callback(filePath)` or + * `callback({ path: filePath })`. The `filePath` must be an absolute path. + * + * By default the `scheme` is treated like `http:`, which is parsed differently + * from protocols that follow the "generic URI syntax" like `file:`. + */ + registerFileProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: (string) | (ProtocolResponse)) => void) => void): boolean; + /** + * Whether the protocol was successfully registered + * + * Registers a protocol of `scheme` that will send an HTTP request as a response. + * + * The usage is the same with `registerFileProtocol`, except that the `callback` + * should be called with an object that has the `url` property. + */ + registerHttpProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: ProtocolResponse) => void) => void): boolean; + /** + * **Note:** This method can only be used before the `ready` event of the `app` + * module gets emitted and can be called only once. + * + * Registers the `scheme` as standard, secure, bypasses content security policy for + * resources, allows registering ServiceWorker, supports fetch API, and streaming + * video/audio. Specify a privilege with the value of `true` to enable the + * capability. + * + * An example of registering a privileged scheme, that bypasses Content Security + * Policy: + * + * A standard scheme adheres to what RFC 3986 calls generic URI syntax. For example + * `http` and `https` are standard schemes, while `file` is not. + * + * Registering a scheme as standard allows relative and absolute resources to be + * resolved correctly when served. Otherwise the scheme will behave like the `file` + * protocol, but without the ability to resolve relative URLs. + * + * For example when you load following page with custom protocol without + * registering it as standard scheme, the image will not be loaded because + * non-standard schemes can not recognize relative URLs: + * + * Registering a scheme as standard will allow access to files through the + * FileSystem API. Otherwise the renderer will throw a security error for the + * scheme. + * + * By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB, + * cookies) are disabled for non standard schemes. So in general if you want to + * register a custom protocol to replace the `http` protocol, you have to register + * it as a standard scheme. + * + * Protocols that use streams (http and stream protocols) should set `stream: + * true`. The `