diff --git a/doric-demo/LICENSE b/doric-demo/LICENSE new file mode 100644 index 00000000..97846020 --- /dev/null +++ b/doric-demo/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2019] [Doric.Pub] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/doric-demo/README.md b/doric-demo/README.md new file mode 100644 index 00000000..c5fb175e --- /dev/null +++ b/doric-demo/README.md @@ -0,0 +1 @@ +# Doric Demos \ No newline at end of file diff --git a/doric-demo/index.ts b/doric-demo/index.ts index bd7e494d..5f778ea2 100644 --- a/doric-demo/index.ts +++ b/doric-demo/index.ts @@ -1,21 +1,7 @@ export default [ 'src/Counter', 'src/Snake', - 'src/ListDemo', - 'src/ScrollerDemo', - 'src/SliderDemo', - 'src/LayoutDemo', - 'src/EffectsDemo', - 'src/ImageDemo', - 'src/ModalDemo', - 'src/NetworkDemo', - 'src/StorageDemo', - 'src/NavigatorDemo', - 'src/NavbarDemo', - 'src/RefreshableDemo', - 'src/FlowLayoutDemo', - 'src/PopoverDemo', - 'src/AnimatorDemo', 'src/ComplicatedAnimations', - 'src/ComplicatedDemo', + 'src/.*Demo', + 'src/Gobang', ] \ No newline at end of file diff --git a/doric-demo/package-lock.json b/doric-demo/package-lock.json index ed538db2..36c4f6a8 100644 --- a/doric-demo/package-lock.json +++ b/doric-demo/package-lock.json @@ -4,15 +4,35 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@rollup/plugin-node-resolve": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-6.0.0.tgz", + "integrity": "sha512-GqWz1CfXOsqpeVMcoM315+O7zMxpRsmhWyhJoxLFHVSp9S64/u02i7len/FnbTNbmgYs+sZyilasijH8UiuboQ==", + "requires": { + "@rollup/pluginutils": "^3.0.0", + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1" + } + }, + "@rollup/pluginutils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.0.tgz", + "integrity": "sha512-qBbGQQaUUiId/lBU9VMeYlVLOoRNvz1fV8HWY5tiGDpI2gdPZHbmOfCjzSdXPhdq3XOfyWvXEBlIPbnM3+9ogQ==", + "requires": { + "estree-walker": "^0.6.1" + } + }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + "version": "0.0.40", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz", + "integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==" }, "@types/node": { - "version": "12.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", - "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" + "version": "12.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.21.tgz", + "integrity": "sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA==" }, "@types/resolve": { "version": "0.0.8", @@ -33,26 +53,46 @@ "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" }, "doric": { - "version": "file:../js-framework", + "version": "file:../doric-js", "requires": { - "@types/ws": "^6.0.3", + "@rollup/plugin-node-resolve": "^6.0.0", + "@types/ws": "^6.0.4", "reflect-metadata": "^0.1.13", - "rollup": "^1.27.2", - "rollup-plugin-node-resolve": "^5.2.0", + "rollup": "^1.27.13", "tslib": "^1.10.0", - "typescript": "^3.7.2", - "ws": "^7.2.0" + "typescript": "^3.7.3", + "ws": "^7.2.1" }, "dependencies": { + "@rollup/plugin-node-resolve": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-6.0.0.tgz", + "integrity": "sha512-GqWz1CfXOsqpeVMcoM315+O7zMxpRsmhWyhJoxLFHVSp9S64/u02i7len/FnbTNbmgYs+sZyilasijH8UiuboQ==", + "requires": { + "@rollup/pluginutils": "^3.0.0", + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1" + } + }, + "@rollup/pluginutils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.0.tgz", + "integrity": "sha512-qBbGQQaUUiId/lBU9VMeYlVLOoRNvz1fV8HWY5tiGDpI2gdPZHbmOfCjzSdXPhdq3XOfyWvXEBlIPbnM3+9ogQ==", + "requires": { + "estree-walker": "^0.6.1" + } + }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + "version": "0.0.40", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz", + "integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==" }, "@types/node": { - "version": "12.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", - "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" + "version": "12.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.21.tgz", + "integrity": "sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA==" }, "@types/resolve": { "version": "0.0.8", @@ -63,9 +103,9 @@ } }, "@types/ws": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.3.tgz", - "integrity": "sha512-yBTM0P05Tx9iXGq00BbJPo37ox68R5vaGTXivs6RGh/BQ6QP5zqZDGWdAO6JbRE/iR1l80xeGAwCQS2nMV9S/w==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", "requires": { "@types/node": "*" } @@ -75,11 +115,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==" }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "builtin-modules": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", @@ -106,60 +141,37 @@ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", + "integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==", "requires": { "path-parse": "^1.0.6" } }, "rollup": { - "version": "1.26.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.26.5.tgz", - "integrity": "sha512-c6Pv0yWzjYNpy2DIhLFUnyP6e1UTGownr4IfpJcPY/k186RJjpaGGPRwKQ62KCauctG6dgtHt88pw1EGrPRkuA==", + "version": "1.27.13", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.13.tgz", + "integrity": "sha512-hDi7M07MpmNSDE8YVwGVFA8L7n8jTLJ4lG65nMAijAyqBe//rtu4JdxjUBE7JqXfdpqxqDTbCDys9WcqdpsQvw==", "requires": { "@types/estree": "*", "@types/node": "*", "acorn": "^7.1.0" } }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - } - }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "requires": { - "estree-walker": "^0.6.1" - } - }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==" }, "ws": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", - "integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==", - "requires": { - "async-limiter": "^1.0.0" - } + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" } } }, @@ -179,6 +191,13 @@ "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", "requires": { "@types/estree": "0.0.39" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + } } }, "magic-string": { @@ -200,17 +219,17 @@ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", + "integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==", "requires": { "path-parse": "^1.0.6" } }, "rollup": { - "version": "1.27.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.2.tgz", - "integrity": "sha512-sD3iyd0zlvgK1S3MmICi6F/Y+R/QWY5XxzsTGN4pAd+nCasDUizmAhgq2hdh1t2eLux974NHU2TW41fhuGPv+Q==", + "version": "1.27.13", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.13.tgz", + "integrity": "sha512-hDi7M07MpmNSDE8YVwGVFA8L7n8jTLJ4lG65nMAijAyqBe//rtu4JdxjUBE7JqXfdpqxqDTbCDys9WcqdpsQvw==", "requires": { "@types/estree": "*", "@types/node": "*", @@ -229,18 +248,6 @@ "rollup-pluginutils": "^2.8.1" } }, - "rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - } - }, "rollup-pluginutils": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", @@ -260,9 +267,9 @@ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==" } } } diff --git a/doric-demo/package.json b/doric-demo/package.json index 7c36fcc3..46e11717 100644 --- a/doric-demo/package.json +++ b/doric-demo/package.json @@ -10,12 +10,12 @@ }, "license": "Apache-2.0", "dependencies": { - "doric": "file:../js-framework", + "doric": "file:../doric-js", "reflect-metadata": "^0.1.13", - "rollup": "^1.27.2", + "rollup": "^1.27.13", "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-resolve": "^5.2.0", + "@rollup/plugin-node-resolve": "^6.0.0", "tslib": "^1.10.0", - "typescript": "^3.7.2" + "typescript": "^3.7.3" } } diff --git a/doric-demo/rollup.config.js b/doric-demo/rollup.config.js index 3e5b5b75..cc4cd96d 100644 --- a/doric-demo/rollup.config.js +++ b/doric-demo/rollup.config.js @@ -1,23 +1,58 @@ -import resolve from 'rollup-plugin-node-resolve' +import resolve from '@rollup/plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import bundles from './build/index' +import fs from 'fs' +import path from 'path' -export default bundles.map(bundle => { - return { - input: `build/${bundle}.js`, - output: { - format: "cjs", - file: `bundle/${bundle}.js`, - sourcemap: true, - }, - plugins: [ - resolve({ mainFields: ["jsnext"] }), - commonjs() - ], - external: ['reflect-metadata', 'doric'], - onwarn: function (warning) { - if (warning.code === 'THIS_IS_UNDEFINED') { return; } - console.warn(warning.message); +function readDirs(dirPath, files) { + if (fs.statSync(dirPath).isDirectory()) { + fs.readdirSync(dirPath).forEach(e => { + readDirs(path.join(dirPath, e), files) + }) + } else { + for (let bundle of bundles) { + if (dirPath.match(new RegExp(`^${bundle}`))) { + files.push(dirPath) + } } } -}) \ No newline at end of file +} + + +const dirs = fs.readdirSync('.') + .filter(e => { + for (let bundle of bundles) { + if (bundle.match(new RegExp(`^${e}/`))) { + return true + } + } + return false + }) + +const allFiles = [] + +dirs.forEach(e => { + readDirs(e, allFiles) +}) + +export default allFiles + .map(e => e.replace('.ts', '')) + .map(bundle => { + return { + input: `build/${bundle}.js`, + output: { + format: "cjs", + file: `bundle/${bundle}.js`, + sourcemap: true, + }, + plugins: [ + resolve({ mainFields: ["jsnext"] }), + commonjs() + ], + external: ['reflect-metadata', 'doric'], + onwarn: function (warning) { + if (warning.code === 'THIS_IS_UNDEFINED') { return; } + console.warn(warning.message); + } + } + }) \ No newline at end of file diff --git a/doric-demo/src/AnimatorDemo.ts b/doric-demo/src/AnimatorDemo.ts index 185acd51..d5335d0c 100644 --- a/doric-demo/src/AnimatorDemo.ts +++ b/doric-demo/src/AnimatorDemo.ts @@ -9,7 +9,7 @@ function thisLabel(str: string) { backgroundColor: colors[0], textSize: 15, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), }) } @@ -29,7 +29,7 @@ class AnimatorDemo extends Panel { hlayout([ thisLabel('Reset').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.width = view.height = 20 view.x = view.y = 0 @@ -54,7 +54,7 @@ class AnimatorDemo extends Panel { hlayout([ thisLabel('X').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.x = view.x || 0 view.x += 100 @@ -66,7 +66,7 @@ class AnimatorDemo extends Panel { }), thisLabel('Y').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.y = view.y || 0 view.y += 100 @@ -78,7 +78,7 @@ class AnimatorDemo extends Panel { }), thisLabel('Width').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.width += 100 }, @@ -88,7 +88,7 @@ class AnimatorDemo extends Panel { }), thisLabel('Height').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.height += 100 }, @@ -100,7 +100,7 @@ class AnimatorDemo extends Panel { hlayout([ thisLabel('BgColor').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { view.backgroundColor = colors[(idx++) % colors.length] }, @@ -110,7 +110,7 @@ class AnimatorDemo extends Panel { }), thisLabel('Rotation').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { if (view.rotation) { view.rotation += 0.5 @@ -124,7 +124,7 @@ class AnimatorDemo extends Panel { }), thisLabel('Corner').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { if (typeof view.corners === 'number') { view.corners += 10 @@ -141,7 +141,7 @@ class AnimatorDemo extends Panel { hlayout([ thisLabel('scaleX').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { if (view.scaleX) { view.scaleX += 0.1 @@ -155,7 +155,7 @@ class AnimatorDemo extends Panel { }), thisLabel('scaleY').apply({ onClick: () => { - animate(this)({ + animate(context)({ animations: () => { if (view.scaleY) { view.scaleY += 0.1 @@ -173,11 +173,11 @@ class AnimatorDemo extends Panel { stack([ view, ]).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), backgroundColor: colors[1].alpha(0.3 * 255), }), ]).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), gravity: gravity().center(), space: 10, } as IVLayout).in(rootView) diff --git a/doric-demo/src/ComplicatedAnimations.ts b/doric-demo/src/ComplicatedAnimations.ts index bc477830..bf437b59 100644 --- a/doric-demo/src/ComplicatedAnimations.ts +++ b/doric-demo/src/ComplicatedAnimations.ts @@ -9,7 +9,7 @@ function thisLabel(str: string) { backgroundColor: colors[0], textSize: 10, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), }) } @@ -190,11 +190,11 @@ class AnimationDemo extends Panel { v.scaleX = 1.5 }) ]).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), backgroundColor: colors[1].alpha(0.3 * 255), }), ]).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), gravity: gravity().center(), space: 10, } as IVLayout).in(rootView) diff --git a/doric-demo/src/ComplicatedDemo.ts b/doric-demo/src/ComplicatedDemo.ts index c4c4db2f..e5620aaf 100644 --- a/doric-demo/src/ComplicatedDemo.ts +++ b/doric-demo/src/ComplicatedDemo.ts @@ -1,5 +1,5 @@ -import { Panel, Group, vlayout, image, layoutConfig, ScaleType, refreshable, Color, pullable, stack, Image, Refreshable, TranslationAnimation, loge, log } from "doric"; -import { title, icon_refresh } from "./utils"; +import { Panel, Group, vlayout, image, layoutConfig, ScaleType, refreshable, Color, pullable, stack, Image, Refreshable, TranslationAnimation, loge, log, list, listItem, text } from "doric"; +import { title, icon_refresh, colors } from "./utils"; @Entry class MyDemo extends Panel { @@ -11,10 +11,10 @@ class MyDemo extends Panel { onRefresh: () => { refreshed.setRefreshing(context, false) }, - header: pullable(context, + header: pullable( stack([]).apply({ backgroundColor: Color.RED, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), width: 100, height: 30, }), @@ -25,21 +25,31 @@ class MyDemo extends Panel { }, setPullingDistance: (distance: number) => { headerImage.scaleX = headerImage.scaleY = (headerImage.height + distance * 2) / headerImage.height - log(`Header Image scaleY:${headerImage.scaleY},height:${headerImage.height},distance:${distance}`) }, }), - content: vlayout([]).apply({ - backgroundColor: Color.YELLOW, + content: list({ + itemCount: 20, + renderItem: (idx) => { + return listItem(text({ + text: `Item :${idx}`, + layoutConfig: layoutConfig().just(), + width: root.width, + height: 50, + textColor: Color.WHITE, + backgroundColor: colors[idx % colors.length], + })) + } + }).apply({ }), }).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).also(v => { v.top = 200 }), headerImage = image({ imageUrl: "https://img.zcool.cn/community/01e75b5da933daa801209e1ffa4649.jpg@1280w_1l_2o_100sh.jpg", - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), width: root.width, height: 200, scaleType: ScaleType.ScaleAspectFill, diff --git a/doric-demo/src/Counter.ts b/doric-demo/src/Counter.ts index 3b152919..96e9876e 100644 --- a/doric-demo/src/Counter.ts +++ b/doric-demo/src/Counter.ts @@ -3,9 +3,7 @@ import { text, vlayout, Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCa interface CountModel { count: number } - -class CounterView extends ViewHolder { - +class CounterView extends ViewHolder { number!: Text counter!: Text build(root: Group) { @@ -14,8 +12,8 @@ class CounterView extends ViewHolder { textSize: 40, layoutConfig: { alignment: Gravity.Center, - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, }, }).also(it => { this.number = it }), text({ @@ -28,8 +26,14 @@ class CounterView extends ViewHolder { corners: 5, layoutConfig: { alignment: Gravity.Center, - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, + }, + padding: { + left: 10, + right: 10, + top: 10, + bottom: 10, }, shadow: { color: Color.parse("#00ff00"), @@ -65,29 +69,24 @@ class CounterView extends ViewHolder { root.addChild((new Image).also(iv => { iv.imageUrl = "https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png" iv.layoutConfig = { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, } })) } - - bind(state: CountModel) { - this.number.text = `${state.count}` - } - - setCounter(v: Function) { - this.counter.onClick = v - } } class CounterVM extends ViewModel { - onAttached(s: CountModel, vh: CounterView): void { + onAttached(s: CountModel, vh: CounterView) { vh.counter.onClick = () => { this.updateState(state => { state.count++ }) } } + onBind(s: CountModel, vh: CounterView) { + vh.number.text = `${s.count}` + } } @Entry diff --git a/doric-demo/src/EffectsDemo.ts b/doric-demo/src/EffectsDemo.ts index 126d6728..1914e360 100644 --- a/doric-demo/src/EffectsDemo.ts +++ b/doric-demo/src/EffectsDemo.ts @@ -50,7 +50,7 @@ class EffectsDemo extends Panel { width: 5, color: colors[3] }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -65,7 +65,7 @@ class EffectsDemo extends Panel { width: 100, height: 100, corners: 10, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ bottom: 10 }) }),]).apply({ @@ -84,7 +84,7 @@ class EffectsDemo extends Panel { offsetY: 3, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ bottom: 10 }) }),]).apply({ @@ -103,7 +103,7 @@ class EffectsDemo extends Panel { color: colors[3] }, corners: 10, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -128,7 +128,7 @@ class EffectsDemo extends Panel { offsetY: 3, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ bottom: 10 }) }),]).apply({ @@ -148,7 +148,7 @@ class EffectsDemo extends Panel { offsetY: 3, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ bottom: 10 }) }),]).apply({ @@ -172,7 +172,7 @@ class EffectsDemo extends Panel { offsetY: 3, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -196,7 +196,7 @@ class EffectsDemo extends Panel { offsetY: 0, radius: 10, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 10, right: 10, bottom: 10, @@ -218,7 +218,7 @@ class EffectsDemo extends Panel { offsetY: 5, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 10, right: 10, bottom: 10, @@ -240,7 +240,7 @@ class EffectsDemo extends Panel { offsetY: 5, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 10, right: 10, bottom: 10, @@ -262,7 +262,7 @@ class EffectsDemo extends Panel { offsetY: 5, radius: 5, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 10, right: 10, bottom: 10, @@ -279,7 +279,7 @@ class EffectsDemo extends Panel { width: 100, height: 100, corners: 50, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -296,7 +296,7 @@ class EffectsDemo extends Panel { corners: { leftTop: 50, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -313,7 +313,7 @@ class EffectsDemo extends Panel { corners: { rightTop: 50, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -330,7 +330,7 @@ class EffectsDemo extends Panel { corners: { leftBottom: 50, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -347,7 +347,7 @@ class EffectsDemo extends Panel { corners: { rightBottom: 50, }, - layoutConfig: layoutConfig().exactly().m({ + layoutConfig: layoutConfig().just().configMargin({ left: 5, right: 5, bottom: 5, @@ -361,7 +361,7 @@ class EffectsDemo extends Panel { it.space = 20 }), ).also(it => { - it.layoutConfig = layoutConfig().atmost() + it.layoutConfig = layoutConfig().most() }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/FlowLayoutDemo.ts b/doric-demo/src/FlowLayoutDemo.ts index f668cc08..25b6415b 100644 --- a/doric-demo/src/FlowLayoutDemo.ts +++ b/doric-demo/src/FlowLayoutDemo.ts @@ -16,8 +16,8 @@ const imageUrls = [ class FlowDemo extends Panel { build(rootView: Group): void { flowlayout({ - layoutConfig: layoutConfig().atmost(), - itemCount: 500, + layoutConfig: layoutConfig().most(), + itemCount: 100, columnCount: 3, columnSpace: 10, rowSpace: 10, @@ -25,16 +25,35 @@ class FlowDemo extends Panel { return new FlowLayoutItem().apply({ backgroundColor: colors[idx % colors.length], height: 50 + (idx % 3) * 20, - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), }).also(it => { it.addChild(text({ text: `${idx}`, textColor: Color.WHITE, textSize: 20, - layoutConfig: layoutConfig().wrap().a(Gravity.Center) + layoutConfig: layoutConfig().fit().configAligmnet(Gravity.Center) })) }) }, + }).also(it => { + it.loadMore = true + it.onLoadMore = () => { + setTimeout(() => { + it.itemCount += 20 + }, 1000) + } + it.loadMoreView = new FlowLayoutItem().apply({ + backgroundColor: colors[500 % colors.length], + height: 50, + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), + }).also(it => { + it.addChild(text({ + text: 'load more', + textColor: Color.WHITE, + textSize: 20, + layoutConfig: layoutConfig().fit().configAligmnet(Gravity.Center) + })) + }) }) .in(rootView) } diff --git a/doric-demo/src/Gobang.ts b/doric-demo/src/Gobang.ts new file mode 100644 index 00000000..d1563c32 --- /dev/null +++ b/doric-demo/src/Gobang.ts @@ -0,0 +1,677 @@ +import { Stack, hlayout, Group, Color, stack, layoutConfig, LayoutSpec, vlayout, IVLayout, Text, ViewHolder, ViewModel, VMPanel, scroller, modal, text, gravity, Gravity, IHLayout, takeNonNull, View, log, popover } from "doric"; +import { colors } from "./utils"; + +enum State { + Unspecified, + BLACK, + WHITE, +} + +const count = 13 + + +class AIComputer { + wins: Array> = [] + winCount = 0 + matrix: Map + constructor(matrix: Map) { + this.matrix = matrix + for (let y = 0; y < count; y++) { + for (let x = 0; x < count - 4; x++) { + this.wins.push([]) + for (let k = 0; k < 5; k++) { + this.wins[this.winCount].push({ + x: x + k, + y, + }) + } + this.winCount++; + } + } + + for (let x = 0; x < count; x++) { + for (let y = 0; y < count - 4; y++) { + this.wins.push([]) + for (let k = 0; k < 5; k++) { + this.wins[this.winCount].push({ + x, + y: y + k, + }) + } + this.winCount++; + } + } + + for (let x = 0; x < count - 4; x++) { + for (let y = 0; y < count - 4; y++) { + this.wins.push([]) + for (let k = 0; k < 5; k++) { + this.wins[this.winCount].push({ + x: x + k, + y: y + k, + }) + } + this.winCount++; + } + } + + for (let x = 0; x < count - 4; x++) { + for (let y = count - 1; y > 3; y--) { + this.wins.push([]) + for (let k = 0; k < 5; k++) { + this.wins[this.winCount].push({ + x: x + k, + y: y - k, + }) + } + this.winCount++; + } + } + } + + get blackWins() { + return this.wins.map((win) => { + let idx = 0 + for (let e of win) { + switch (this.matrix.get(e.x + e.y * count)) { + case State.BLACK: + idx++ + break + case State.WHITE: + return 0 + default: + break + } + } + return idx + }) + } + + get whiteWins() { + return this.wins.map((win) => { + let idx = 0 + for (let e of win) { + switch (this.matrix.get(e.x + e.y * count)) { + case State.WHITE: + idx++ + break + case State.BLACK: + return 0 + default: + break + } + } + return idx + }) + } + + compute(matrix: State[], role: State.BLACK | State.WHITE) { + const myScore = new Array(matrix.length).fill(0) + const rivalScore = new Array(matrix.length).fill(0) + const myWins = role === State.BLACK ? this.blackWins : this.whiteWins + const rivalWins = role === State.BLACK ? this.whiteWins : this.blackWins + let max = 0 + let retIdx = 0 + matrix.forEach((state, idx) => { + if (state != State.Unspecified) { + return + } + this.wins.forEach((e, winIdx) => { + if (e.filter(e => (e.x + e.y * count) === idx).length === 0) { + return + } + switch (rivalWins[winIdx]) { + case 1: + rivalScore[idx] += 1 + break + case 2: + rivalScore[idx] += 10 + break + case 3: + rivalScore[idx] += 100 + break + case 4: + rivalScore[idx] += 10000 + break + default: + break + } + + switch (myWins[winIdx]) { + case 1: + myScore[idx] += 2 + break + case 2: + myScore[idx] += 20 + break + case 3: + myScore[idx] += 200 + break + case 4: + myScore[idx] += 20000 + break + default: + break + } + }) + if (rivalScore[idx] > max) { + max = rivalScore[idx]; + retIdx = idx + } else if (rivalScore[idx] == max) { + if (myScore[idx] > myScore[retIdx]) { + retIdx = idx + } + } + + if (myScore[idx] > max) { + max = myScore[idx] + retIdx = idx + } else if (myScore[idx] == max) { + if (rivalScore[idx] > rivalScore[retIdx]) { + retIdx = idx + } + } + }) + return retIdx + } +} +const lineColor = Color.BLACK +function columLine() { + return (new Stack).apply({ + layoutConfig: layoutConfig().most().configWidth(LayoutSpec.JUST), + width: 1, + backgroundColor: lineColor, + }) +} + +function rowLine() { + return (new Stack).apply({ + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST), + height: 1, + backgroundColor: lineColor, + }) +} + +function pointer(size: number) { + return (new Stack).apply({ + layoutConfig: layoutConfig().just(), + width: size, + height: size, + }) +} +enum GameMode { + P2P, + P2C, + C2P, +} + +interface GoBangState { + count: number + gap: number + role: "white" | "black" + matrix: Map + anchor?: number + gameMode: GameMode + gameState: "blackWin" | "whiteWin" | "idle" +} + +class GoBangVH extends ViewHolder { + root!: Group + gap = 0 + currentRole!: Text + result!: Text + targetZone: View[] = [] + gameMode!: Text + assistant!: Text + build(root: Group): void { + this.root = root + } + actualBuild(state: GoBangState): void { + const boardSize = state.gap * (state.count - 1) + const gap = state.gap + const borderWidth = gap + this.gap = state.gap + scroller( + vlayout([ + text({ + text: "五子棋", + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), + textSize: 30, + textColor: Color.WHITE, + backgroundColor: colors[0], + textAlignment: gravity().center(), + height: 50, + }), + stack([ + stack([ + ...(new Array(count - 2)).fill(0).map((_, idx) => { + return columLine().also(v => { + v.left = (idx + 1) * gap + }) + }), + ...(new Array(count - 2)).fill(0).map((_, idx) => { + return rowLine().also(v => { + v.top = (idx + 1) * gap + }) + }), + ]) + .apply({ + layoutConfig: layoutConfig().just() + .configMargin({ top: borderWidth, left: borderWidth }), + width: boardSize, + height: boardSize, + border: { + width: 1, + color: lineColor, + }, + }), + ...this.targetZone = (new Array(count * count)).fill(0).map((_, idx) => { + const row = Math.floor(idx / count) + const colum = idx % count + return pointer(gap).also(v => { + v.top = (row - 0.5) * gap + borderWidth + v.left = (colum - 0.5) * gap + borderWidth + }) + }), + ]).apply({ + layoutConfig: layoutConfig().just(), + width: boardSize + 2 * borderWidth, + height: boardSize + 2 * borderWidth, + backgroundColor: Color.parse("#E6B080"), + }), + + this.gameMode = text({ + text: "游戏模式", + textSize: 20, + textColor: Color.WHITE, + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST), + height: 50, + backgroundColor: colors[8], + }), + hlayout([ + this.currentRole = text({ + text: "当前:", + textSize: 20, + textColor: Color.WHITE, + layoutConfig: layoutConfig().just().configWeight(1), + height: 50, + backgroundColor: colors[1], + }), + this.result = text({ + text: "获胜方:", + textSize: 20, + textColor: Color.WHITE, + layoutConfig: layoutConfig().just().configWeight(1), + height: 50, + backgroundColor: colors[2], + }), + ]).apply({ + layoutConfig: layoutConfig().fit().configWidth(LayoutSpec.MOST), + } as IHLayout), + this.assistant = text({ + text: "提示", + textSize: 20, + textColor: Color.WHITE, + layoutConfig: layoutConfig().just().configWidth(LayoutSpec.MOST), + height: 50, + backgroundColor: colors[3], + }), + ]) + .apply({ + layoutConfig: layoutConfig().fit(), + backgroundColor: Color.parse('#ecf0f1'), + } as IVLayout) + ).in(this.root) + } +} + +class GoBangVM extends ViewModel{ + computer!: AIComputer + onAttached(state: GoBangState, vh: GoBangVH) { + if (!this.computer) { + this.computer = new AIComputer(state.matrix) + } + vh.actualBuild(state) + vh.targetZone.forEach((e, idx) => { + e.onClick = () => { + if (state.gameState !== 'idle') { + return + } + const zoneState = state.matrix.get(idx) + if (zoneState === State.BLACK || zoneState === State.WHITE) { + modal(context).toast('This position had been token.') + return + } + if (state.anchor === undefined || state.anchor != idx) { + this.updateState(it => { + it.anchor = idx + }) + } else { + this.updateState(it => { + if (it.role === 'black') { + it.matrix.set(idx, State.BLACK) + it.role = 'white' + } else { + it.matrix.set(idx, State.WHITE) + it.role = 'black' + } + it.anchor = undefined + if (this.checkResult(idx)) { + modal(context).toast(`恭喜获胜方${it.role === 'white' ? "黑方" : "白方"}`) + it.gameState = it.role === 'white' ? 'blackWin' : 'whiteWin' + } else { + if (it.role === 'black' && it.gameMode === GameMode.C2P) { + setTimeout(() => { + this.computeNextStep(it) + }, 0) + } else if (it.role === 'white' && it.gameMode === GameMode.P2C) { + setTimeout(() => { + this.computeNextStep(it) + }, 0) + } + } + }) + } + } + }) + vh.gameMode.onClick = () => { + popover(context).show(vlayout([ + ...[ + { + label: "黑方:人 白方:人", + mode: GameMode.P2P, + }, + { + label: "黑方:人 白方:机", + mode: GameMode.P2C, + }, + { + label: "黑方:机 白方:人", + mode: GameMode.C2P, + }, + ].map((e) => text({ + text: e.label, + textSize: 20, + textColor: Color.WHITE, + layoutConfig: layoutConfig().just(), + height: 50, + width: 300, + backgroundColor: (state.gameMode === e.mode) ? Color.parse('#636e72') : Color.parse('#b2bec3'), + onClick: () => { + this.updateState(s => { + s.gameMode = e.mode + this.reset(s) + }) + popover(context).dismiss() + }, + })) + ]) + .apply({ + layoutConfig: layoutConfig().most(), + onClick: () => { + popover(context).dismiss() + }, + gravity: Gravity.Center, + } as IVLayout) + ) + } + vh.result.onClick = () => { + switch (state.gameState) { + case "idle": + this.updateState(state => { + this.reset(state) + }) + break + case "blackWin": + case "whiteWin": + break + } + } + vh.currentRole.onClick = () => { + switch (state.gameState) { + case "idle": + break + case "blackWin": + case "whiteWin": + this.updateState(state => { + this.reset(state) + }) + break + } + } + vh.assistant.onClick = () => { + const it = this.getState() + if (it.gameState !== 'idle') { + return + } + this.computeNextStep(it) + if (it.gameState !== 'idle') { + return + } + if (it.role === 'black' && it.gameMode === GameMode.C2P) { + setTimeout(() => { + this.computeNextStep(it) + }, 0) + } else if (it.role === 'white' && it.gameMode === GameMode.P2C) { + setTimeout(() => { + this.computeNextStep(it) + }, 0) + } + } + } + computeNextStep(it: GoBangState) { + const tempMatrix: State[] = new Array(count * count).fill(0).map((_, idx) => { + return it.matrix.get(idx) || State.Unspecified + }) + let idx = 0 + do { + idx = this.computer.compute(tempMatrix, it.role === 'black' ? State.BLACK : State.WHITE) + } while (it.matrix.get(idx) === State.Unspecified) + this.updateState(state => { + state.matrix.set(idx, state.role === 'black' ? State.BLACK : State.WHITE) + state.role = state.role === 'black' ? 'white' : 'black' + if (this.checkResult(idx)) { + modal(context).toast(`恭喜获胜方${it.role === 'white' ? "黑方" : "白方"}`) + it.gameState = it.role === 'white' ? 'blackWin' : 'whiteWin' + } + }) + } + + reset(it: GoBangState) { + it.matrix.clear() + it.gameState = 'idle' + it.role = "black" + it.anchor = undefined + this.computer = new AIComputer(it.matrix) + if (it.gameMode === GameMode.C2P) { + const idx = Math.floor(Math.random() * count) * count + Math.floor(Math.random() * count) + it.matrix.set(idx, State.BLACK) + it.role = 'white' + } + } + onBind(state: GoBangState, vh: GoBangVH) { + vh.targetZone.forEach((v, idx) => { + const zoneState = state.matrix.get(idx) + switch (zoneState) { + case State.BLACK: + v.also(it => { + it.backgroundColor = Color.BLACK + it.corners = state.gap / 2 + it.border = { + color: Color.TRANSPARENT, + width: 0, + } + }) + break + case State.WHITE: + v.also(it => { + it.backgroundColor = Color.WHITE + it.corners = state.gap / 2 + it.border = { + color: Color.TRANSPARENT, + width: 0, + } + }) + break + default: + v.also(it => { + it.backgroundColor = Color.TRANSPARENT + it.corners = 0 + it.border = { + color: Color.TRANSPARENT, + width: 0, + } + }) + break + } + if (state.anchor === idx) { + v.also(it => { + it.backgroundColor = Color.RED.alpha(0.1) + it.corners = 0 + it.border = { + color: Color.RED, + width: 1, + } + }) + } + }) + vh.gameMode.text = `游戏模式: 黑方 ${state.gameMode === GameMode.C2P ? "机" : "人"} 白方 ${state.gameMode === GameMode.P2C ? "机" : "人"}` + switch (state.gameState) { + case "idle": + vh.result.text = "重新开始" + vh.currentRole.text = `当前: ${(state.role === 'black') ? "黑方" : "白方"}` + break + case "blackWin": + vh.result.text = "黑方获胜" + vh.currentRole.text = "重新开始" + break + case "whiteWin": + vh.result.text = "白方获胜" + vh.currentRole.text = "重新开始" + break + } + } + + checkResult(pos: number) { + const matrix = this.getState().matrix + const state = matrix.get(pos) + const y = Math.floor(pos / count) + const x = pos % count + const getState = (x: number, y: number) => matrix.get(y * count + x) + ///Horitonzal + { + let left = x + while (left >= 1) { + if (getState(left - 1, y) === state) { + left -= 1 + } else { + break + } + } + let right = x + while (right <= count - 2) { + if (getState(right + 1, y) === state) { + right += 1 + } else { + break + } + } + if (right - left >= 4) { + return true + } + } + ///Vertical + { + let top = y + while (top >= 1) { + if (getState(x, top - 1) === state) { + top -= 1 + } else { + break + } + } + let bottom = y + while (bottom <= count - 2) { + if (getState(x, bottom + 1) === state) { + bottom += 1 + } else { + break + } + } + if (bottom - top >= 4) { + return true + } + } + + ///LT-RB + { + let startX = x, startY = y + while (startX >= 1 && startY >= 1) { + if (getState(startX - 1, startY - 1) === state) { + startX -= 1 + startY -= 1 + } else { + break + } + } + let endX = x, endY = y + while (endX <= count - 2 && endY <= count - 2) { + if (getState(endX + 1, endY + 1) === state) { + endX += 1 + endY += 1 + } else { + break + } + } + if (endX - startX >= 4) { + return true + } + } + + ///LB-RT + { + let startX = x, startY = y + while (startX >= 1 && startY <= count + 2) { + if (getState(startX - 1, startY + 1) === state) { + startX -= 1 + startY += 1 + } else { + break + } + } + let endX = x, endY = y + while (endX <= count - 2 && endY >= 1) { + if (getState(endX + 1, endY - 1) === state) { + endX += 1 + endY -= 1 + } else { + break + } + } + if (endX - startX >= 4) { + return true + } + } + return false + } +} + +@Entry +class Gobang extends VMPanel { + getViewModelClass() { + return GoBangVM + } + getState(): GoBangState { + return { + count, + gap: this.getRootView().width / 14, + role: "black", + matrix: new Map, + gameMode: GameMode.P2C, + gameState: "idle" + } + } + getViewHolderClass() { + return GoBangVH + } +} \ No newline at end of file diff --git a/doric-demo/src/ImageDemo.ts b/doric-demo/src/ImageDemo.ts index 357a8e22..513f5d6b 100644 --- a/doric-demo/src/ImageDemo.ts +++ b/doric-demo/src/ImageDemo.ts @@ -10,7 +10,7 @@ class ImageDemo extends Panel { scroller(vlayout([ text({ text: "Image Demo", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[5], @@ -53,12 +53,13 @@ class ImageDemo extends Panel { imageUrl, width: 300, height: 300, + isBlur: true, border: { width: 2, color: Color.GRAY, }, scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), loadCallback: (ret) => { } }), @@ -72,7 +73,7 @@ class ImageDemo extends Panel { color: Color.GRAY, }, scaleType: ScaleType.ScaleAspectFit, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), }), label('ScaleAspectFill'), image({ @@ -84,7 +85,7 @@ class ImageDemo extends Panel { color: Color.GRAY, }, scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), }), label('ImageBase64'), image({ @@ -96,14 +97,14 @@ class ImageDemo extends Panel { color: Color.GRAY, }, scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), }), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/InputDemo.ts b/doric-demo/src/InputDemo.ts new file mode 100644 index 00000000..8b52c831 --- /dev/null +++ b/doric-demo/src/InputDemo.ts @@ -0,0 +1,47 @@ +import { Panel, Group, scroller, vlayout, layoutConfig, LayoutSpec, Input, Gravity, log } from "doric"; +import { title, colors } from "./utils"; +@Entry +class InputDemo extends Panel { + build(root: Group) { + scroller( + vlayout([ + title("Input Demo"), + (new Input).also(it => { + it.layoutConfig = layoutConfig().just().configHeight(LayoutSpec.FIT) + it.width = 300 + it.multiline = false + it.hintText = "HintText" + it.textAlignment = Gravity.Left + it.onTextChange = (s) => { + log(`onTextChange:${s}`) + } + it.onFocusChange = (f) => { + log(`onFocusChange:${f}`) + } + }), + (new Input).also(it => { + it.layoutConfig = layoutConfig().fit() + it.hintText = "HintText" + it.hintTextColor = colors[2] + it.textAlignment = Gravity.Left + it.textColor = colors[3] + it.onTextChange = (s) => { + log(`onTextChange:${s}`) + } + it.onFocusChange = (f) => { + log(`onFocusChange:${f}`) + } + it.backgroundColor = colors[1].alpha(0.3) + }), + ]) + .also(it => { + it.space = 10 + it.layoutConfig = layoutConfig().most().configHeight(LayoutSpec.FIT) + })) + .apply({ + layoutConfig: layoutConfig().most() + }) + .in(root) + } + +} \ No newline at end of file diff --git a/doric-demo/src/LayoutDemo.ts b/doric-demo/src/LayoutDemo.ts index b4762dbb..79027d39 100644 --- a/doric-demo/src/LayoutDemo.ts +++ b/doric-demo/src/LayoutDemo.ts @@ -1,6 +1,5 @@ import { Group, Panel, Text, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, slider, slideItem, scroller, IVLayout, IHLayout, layoutConfig } from "doric"; -import { O_TRUNC } from "constants"; const colors = [ "#f0932b", @@ -103,8 +102,8 @@ class LayoutDemo extends Panel { hlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -114,8 +113,8 @@ class LayoutDemo extends Panel { width: 200, height: 30, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -124,8 +123,8 @@ class LayoutDemo extends Panel { box(3), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -134,8 +133,8 @@ class LayoutDemo extends Panel { width: 200, height: 30, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -145,8 +144,8 @@ class LayoutDemo extends Panel { box(2), boxStr('weight=1', 4).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -154,8 +153,8 @@ class LayoutDemo extends Panel { width: 200, height: 30, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -163,15 +162,15 @@ class LayoutDemo extends Panel { hlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -180,8 +179,8 @@ class LayoutDemo extends Panel { width: 200, height: 30, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -189,22 +188,22 @@ class LayoutDemo extends Panel { hlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), boxStr('weight=1', 4).apply({ layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -212,8 +211,8 @@ class LayoutDemo extends Panel { width: 200, height: 30, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -291,29 +290,29 @@ class LayoutDemo extends Panel { vlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, }, }), box(2).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, } }), box(4).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, } }), ]).apply({ width: 100, height: 200, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -321,29 +320,29 @@ class LayoutDemo extends Panel { vlayout([ box(3).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, }, }), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), box(4).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, } }), ]).apply({ width: 100, height: 200, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -351,20 +350,20 @@ class LayoutDemo extends Panel { vlayout([ box(3).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, }, }), box(2).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, }, }), boxStr('weight=1', 4).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -372,8 +371,8 @@ class LayoutDemo extends Panel { width: 100, height: 200, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -381,30 +380,30 @@ class LayoutDemo extends Panel { vlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, }, }), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), box(4).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, } }), ]).apply({ width: 100, height: 200, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -412,22 +411,22 @@ class LayoutDemo extends Panel { vlayout([ boxStr('weight=1', 3).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, }, }), boxStr('weight=1', 2).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), boxStr('weight=1', 4).apply({ layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, weight: 1, } }), @@ -435,8 +434,8 @@ class LayoutDemo extends Panel { width: 100, height: 200, layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, backgroundColor: Color.parse('#eeeeee'), gravity: gravity().center(), @@ -453,7 +452,7 @@ class LayoutDemo extends Panel { it.space = 20 }), ).also(it => { - it.layoutConfig = layoutConfig().atmost() + it.layoutConfig = layoutConfig().most() }) .in(rootView) } diff --git a/doric-demo/src/ListDemo.ts b/doric-demo/src/ListDemo.ts index ebd5c186..71d4066c 100644 --- a/doric-demo/src/ListDemo.ts +++ b/doric-demo/src/ListDemo.ts @@ -1,4 +1,4 @@ -import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, Text, refreshable, Refreshable, ListItem } from "doric"; +import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, Text, refreshable, Refreshable, ListItem, layoutConfig } from "doric"; import { rotatedArrow, colors } from "./utils"; @Entry class ListPanel extends Panel { @@ -9,8 +9,8 @@ class ListPanel extends Panel { text({ text: "ListDemo", layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, }, textSize: 30, textColor: Color.parse("#535c68"), @@ -25,14 +25,25 @@ class ListPanel extends Panel { it.reset() offset = Math.ceil(Math.random() * colors.length) it.itemCount = 40 + it.loadMore = true + it.onLoadMore = () => { + setTimeout(() => { + it.itemCount += 10 + }, 1000) + } + it.loadMoreView = listItem(text({ + text: "Loading", + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST).configAligmnet(Gravity.Center), + height: 50, + })) it.renderItem = (idx: number) => { let counter!: Text return listItem( hlayout([ text({ layoutConfig: { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.JUST, alignment: gravity().center(), }, text: `Cell At Line ${idx}`, @@ -48,8 +59,8 @@ class ListPanel extends Panel { }).also(it => { counter = it it.layoutConfig = { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, margin: { left: 10, } @@ -57,8 +68,8 @@ class ListPanel extends Panel { }) ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.FIT, margin: { bottom: 2, } @@ -72,8 +83,8 @@ class ListPanel extends Panel { }) ).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.FIT, } it.onClick = () => { log(`Click item at ${idx}`) @@ -91,21 +102,21 @@ class ListPanel extends Panel { }) }) }, - header: rotatedArrow(context), + header: rotatedArrow(), content: list({ itemCount: 0, renderItem: () => new ListItem, layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.AT_MOST, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.MOST, }, }), }), ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.AT_MOST, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.MOST, } it.backgroundColor = Color.WHITE }).in(rootView) diff --git a/doric-demo/src/ModalDemo.ts b/doric-demo/src/ModalDemo.ts index 2086e1b0..f4756080 100644 --- a/doric-demo/src/ModalDemo.ts +++ b/doric-demo/src/ModalDemo.ts @@ -7,7 +7,7 @@ class ModalDemo extends Panel { scroller(vlayout([ text({ text: "Modal", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[1], @@ -21,7 +21,7 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).toast('This is a toast.') } @@ -33,7 +33,7 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).toast('This is a toast.', Gravity.Top) } @@ -46,14 +46,14 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).toast('This is a toast.', Gravity.Center) } } as IText), text({ text: "Alert", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[2], @@ -66,7 +66,7 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).alert({ msg: 'This is alert.', @@ -79,7 +79,7 @@ class ModalDemo extends Panel { } as IText), text({ text: "Confirm", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[3], @@ -92,7 +92,7 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).confirm({ msg: 'This is Confirm.', @@ -110,7 +110,7 @@ class ModalDemo extends Panel { } as IText), text({ text: "Prompt", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[4], @@ -123,7 +123,7 @@ class ModalDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { modal(context).prompt({ msg: 'This is Prompt.', @@ -140,11 +140,11 @@ class ModalDemo extends Panel { } } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: Gravity.Center, space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/NavbarDemo.ts b/doric-demo/src/NavbarDemo.ts index 43b743ca..b88fdc7e 100644 --- a/doric-demo/src/NavbarDemo.ts +++ b/doric-demo/src/NavbarDemo.ts @@ -12,7 +12,7 @@ class NavbarDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navbar(context).isHidden().then(e => modal(context).alert(`Navbar isHidden:${e}`)).catch(e => { modal(context).alert(e) @@ -25,7 +25,7 @@ class NavbarDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navbar(context).isHidden() .then(e => navbar(context).setHidden(!e)) @@ -40,7 +40,7 @@ class NavbarDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navbar(context).setTitle('Setted Title') .catch(e => { @@ -54,7 +54,7 @@ class NavbarDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navbar(context).setBgColor(Color.YELLOW) .catch(e => { @@ -68,17 +68,17 @@ class NavbarDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navigator(context).pop() } } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/NavigatorDemo.ts b/doric-demo/src/NavigatorDemo.ts index 03796ef5..3190be23 100644 --- a/doric-demo/src/NavigatorDemo.ts +++ b/doric-demo/src/NavigatorDemo.ts @@ -1,12 +1,15 @@ -import { Panel, scroller, vlayout, text, layoutConfig, LayoutSpec, Color, gravity, IVLayout, Group, IText, navigator } from "doric"; +import { Panel, scroller, vlayout, text, layoutConfig, LayoutSpec, Color, gravity, IVLayout, Group, IText, navigator, modal } from "doric"; import { colors, label } from "./utils"; @Entry class NaivgatorDemo extends Panel { build(root: Group) { + if (this.getInitData()) { + modal(context).alert(`Init Data :${JSON.stringify(this.getInitData())}`) + } scroller(vlayout([ text({ text: "Navigator Demo", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[1], @@ -23,9 +26,14 @@ class NaivgatorDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().just().configWidth(LayoutSpec.MOST), onClick: () => { - navigator(context).push(`assets://demo/${e}.js`, `${e}.js`) + navigator(context).push(`assets://demo/${e}.js`, { + alias: `${e}.js`, + extra: { + from: "navigatorDemo" + }, + }) }, } as IText) ), @@ -35,17 +43,17 @@ class NaivgatorDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { navigator(context).pop() }, } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(root) } diff --git a/doric-demo/src/NetworkDemo.ts b/doric-demo/src/NetworkDemo.ts index 851b5704..1515415a 100644 --- a/doric-demo/src/NetworkDemo.ts +++ b/doric-demo/src/NetworkDemo.ts @@ -12,7 +12,7 @@ class NetworkDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { network(context).get('https://m.baidu.com').then( e => { @@ -24,11 +24,11 @@ class NetworkDemo extends Panel { } } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/PopoverDemo.ts b/doric-demo/src/PopoverDemo.ts index fd0e4f99..8782578b 100644 --- a/doric-demo/src/PopoverDemo.ts +++ b/doric-demo/src/PopoverDemo.ts @@ -12,14 +12,14 @@ class PopoverDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { popover(context).show(text({ width: 200, height: 50, backgroundColor: colors[0], textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly().a(Gravity.Center), + layoutConfig: layoutConfig().just().configAligmnet(Gravity.Center), text: "This is PopOver Window", }).also(v => { let idx = 0 @@ -34,11 +34,11 @@ class PopoverDemo extends Panel { } } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(rootView) } } \ No newline at end of file diff --git a/doric-demo/src/RefreshableDemo.ts b/doric-demo/src/RefreshableDemo.ts index b91c7e02..a9e012c8 100644 --- a/doric-demo/src/RefreshableDemo.ts +++ b/doric-demo/src/RefreshableDemo.ts @@ -6,17 +6,17 @@ class RefreshableDemo extends Panel { build(rootView: Group): void { let refreshImage: Image let refreshView = refreshable({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), onRefresh: () => { log('onRefresh') setTimeout(() => { refreshView.setRefreshing(context, false) }, 5000) }, - header: pullable(context, + header: pullable( stack([ image({ - layoutConfig: layoutConfig().exactly().m({ top: 50, bottom: 10, }), + layoutConfig: layoutConfig().just().configMargin({ top: 50, bottom: 10, }), width: 30, height: 30, imageBase64: icon_refresh, @@ -43,7 +43,7 @@ class RefreshableDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { refreshView.setRefreshing(context, true) } @@ -54,7 +54,7 @@ class RefreshableDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { refreshView.setRefreshing(context, false) } @@ -66,7 +66,7 @@ class RefreshableDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { refreshView.setRefreshable(context, true) } @@ -78,13 +78,13 @@ class RefreshableDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { refreshView.setRefreshable(context, false) } } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().centerX(), space: 10, } as IVLayout)) diff --git a/doric-demo/src/ScrollerDemo.ts b/doric-demo/src/ScrollerDemo.ts index 9870d3d1..0f7a949d 100644 --- a/doric-demo/src/ScrollerDemo.ts +++ b/doric-demo/src/ScrollerDemo.ts @@ -9,7 +9,7 @@ class ScrollerPanel extends Panel { scroller( vlayout(new Array(100).fill(1).map(e => label('Scroll Content'))) ).apply({ - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), width: 300, height: 500, backgroundColor: Color.RED, @@ -17,7 +17,7 @@ class ScrollerPanel extends Panel { scroller( vlayout(new Array(100).fill(1).map(e => label('Scroll Content'))) ).apply({ - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), width: 300, height: 500, backgroundColor: Color.BLUE, @@ -25,7 +25,7 @@ class ScrollerPanel extends Panel { ]) ) .apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.EXACTLY), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST), height: 500, backgroundColor: Color.YELLOW, }) diff --git a/doric-demo/src/SliderDemo.ts b/doric-demo/src/SliderDemo.ts index 6ab55c38..100ab458 100644 --- a/doric-demo/src/SliderDemo.ts +++ b/doric-demo/src/SliderDemo.ts @@ -19,8 +19,8 @@ class SliderPanel extends Panel { text({ text: "Gallery", layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.JUST, }, textSize: 30, textColor: Color.WHITE, @@ -34,7 +34,7 @@ class SliderPanel extends Panel { return slideItem(image({ imageUrl: imageUrls[idx % imageUrls.length], scaleType: ScaleType.ScaleAspectFit, - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST).h(LayoutSpec.AT_MOST).a(gravity().center()), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST).configHeight(LayoutSpec.MOST).configAligmnet(gravity().center()), })).also(it => { let start = idx it.onClick = () => { @@ -43,15 +43,15 @@ class SliderPanel extends Panel { }) }, layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.FIT, weight: 1, }, }), ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.AT_MOST, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.MOST, } })) } diff --git a/doric-demo/src/Snake.ts b/doric-demo/src/Snake.ts index 05bcba33..1998f217 100644 --- a/doric-demo/src/Snake.ts +++ b/doric-demo/src/Snake.ts @@ -134,7 +134,7 @@ class SnakeModel { } } -class SnakeView extends ViewHolder { +class SnakeView extends ViewHolder { panel!: Stack start?: Text @@ -155,8 +155,8 @@ class SnakeView extends ViewHolder { margin: { top: 20 }, - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, }, }), (new Stack).also(panel => { @@ -169,14 +169,14 @@ class SnakeView extends ViewHolder { textSize: 30, textColor: Color.parse("#ffffff"), layoutConfig: { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, }, }).also(it => this.start = it), ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, } }), @@ -190,14 +190,14 @@ class SnakeView extends ViewHolder { textAlignment: new Gravity().center(), backgroundColor: Color.parse('#ffff00'), layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, }).also(it => this.up = it) ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, } }), hlayout([ @@ -209,8 +209,8 @@ class SnakeView extends ViewHolder { textAlignment: new Gravity().center(), backgroundColor: Color.parse('#ffff00'), layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, }).also(it => this.left = it), text({ @@ -221,8 +221,8 @@ class SnakeView extends ViewHolder { textAlignment: new Gravity().center(), backgroundColor: Color.parse('#ffff00'), layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, }).also(it => this.down = it), text({ @@ -233,14 +233,14 @@ class SnakeView extends ViewHolder { textAlignment: new Gravity().center(), backgroundColor: Color.parse('#ffff00'), layoutConfig: { - widthSpec: LayoutSpec.EXACTLY, - heightSpec: LayoutSpec.EXACTLY, + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, }, }).also(it => this.right = it), ]).also(it => { it.layoutConfig = { - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, } it.space = 10 }), @@ -249,16 +249,16 @@ class SnakeView extends ViewHolder { controlArea.space = 10 controlArea.layoutConfig = { alignment: new Gravity().centerX(), - widthSpec: LayoutSpec.WRAP_CONTENT, - heightSpec: LayoutSpec.WRAP_CONTENT, + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, } }), ]).also(it => { it.space = 20 it.layoutConfig = { alignment: new Gravity().centerX().top(), - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.AT_MOST, + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.MOST, } it.gravity = new Gravity().centerX() }).in(root) @@ -346,14 +346,16 @@ class SnakeVM extends ViewModel{ this.updateState(it => it.direction = Direction.down) } - onAttached(state: SnakeModel, v: SnakeView): void { + onAttached(state: SnakeModel, v: SnakeView) { takeNonNull(v.start)(it => it.onClick = this.start) takeNonNull(v.left)(it => it.onClick = this.left) takeNonNull(v.right)(it => it.onClick = this.right) takeNonNull(v.up)(it => it.onClick = this.up) takeNonNull(v.down)(it => it.onClick = this.down) } - + onBind(state: SnakeModel, v: SnakeView) { + v.bind(state) + } } @Entry class SnakePanel extends VMPanel{ diff --git a/doric-demo/src/StickDemo.ts b/doric-demo/src/StickDemo.ts new file mode 100644 index 00000000..3fc1b14c --- /dev/null +++ b/doric-demo/src/StickDemo.ts @@ -0,0 +1,131 @@ +import { Panel, Group, scroller, vlayout, image, layoutConfig, LayoutSpec, Input, Gravity, log, stack, hlayout, text, IHLayout, CENTER, slider, slideItem, modal, Slider, Text, Color, View, Stack, animate, flowlayout, FlowLayoutItem, NestedSlider, ScaleType } from "doric"; +import { title, colors } from "./utils"; + +function tab(idx: number, title: string, sliderView: Slider) { + return text({ + text: title, + layoutConfig: layoutConfig().just().configWeight(1), + height: 41, + onClick: () => { + sliderView.slidePage(context, 0, true) + }, + }) +} + +@Entry +class StickDemo extends Panel { + private tabs!: Text[] + private indicator!: View + private sliderView!: NestedSlider + build(root: Group) { + this.indicator = new Stack + this.indicator.backgroundColor = colors[0] + this.indicator.width = 20 + this.indicator.height = 2 + + scroller( + vlayout([ + stack([ + image({ + layoutConfig: layoutConfig().most(), + imageUrl: "https://p.upyun.com/demo/webp/webp/jpg-0.webp", + scaleType: ScaleType.ScaleAspectFill, + }), + + ]).apply({ + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST), + height: 200, + backgroundColor: colors[0], + }), + stack([ + hlayout([ + ...this.tabs = [0, 1, 2].map(idx => { + return text({ + text: `Tab ${idx}`, + layoutConfig: layoutConfig().just().configWeight(1), + height: 41, + onClick: () => { + this.sliderView.slidePage(context, idx, true) + }, + }) + }) + ]).apply({ + layoutConfig: layoutConfig().most(), + gravity: Gravity.Center, + } as IHLayout), + this.indicator, + ]).apply({ + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.JUST), + height: 57, + }), + + (new NestedSlider).also(v => { + this.sliderView = v; + v.onPageSlided = (idx) => { + this.refreshTabs(idx) + } + [0, 1, 2].map(idx => { + return flowlayout({ + layoutConfig: layoutConfig().just(), + width: root.width, + height: root.height - 57, + itemCount: 100, + columnCount: 2, + columnSpace: 10, + rowSpace: 10, + renderItem: (itemIdx) => { + return new FlowLayoutItem().apply({ + backgroundColor: colors[itemIdx % colors.length], + height: 50, + layoutConfig: layoutConfig().configWidth(LayoutSpec.JUST), + }).also(it => { + it.addChild(text({ + text: `In Page ${idx},${itemIdx}`, + textColor: Color.WHITE, + textSize: 20, + layoutConfig: layoutConfig().fit().configAligmnet(Gravity.Center) + }).also(v => { + v.onClick = () => { + v.text = "Clicked" + } + })) + }) + }, + }) + }).forEach(e => { + v.addSlideItem(e) + }) + }).apply({ + layoutConfig: layoutConfig().just(), + width: root.width, + height: root.height - 57, + }), + ]) + .also(it => { + it.layoutConfig = layoutConfig().most().configHeight(LayoutSpec.FIT) + })) + .apply({ + layoutConfig: layoutConfig().most() + }) + .in(root) + this.indicator.centerX = this.getRootView().width / this.tabs.length / 2 + this.refreshTabs(0) + } + + refreshTabs(page: number) { + this.tabs.forEach((e, idx) => { + if (idx == page) { + e.textColor = colors[0] + } else { + e.textColor = Color.BLACK + } + }) + this.indicator.layoutConfig = layoutConfig().just().configAligmnet(Gravity.Bottom).configMargin({ bottom: 13 }) + animate(context)({ + animations: () => { + this.indicator.centerX = this.getRootView().width / this.tabs.length * (page + 0.5) + }, + duration: 300, + }) + } +} \ No newline at end of file diff --git a/doric-demo/src/StorageDemo.ts b/doric-demo/src/StorageDemo.ts index f13db93b..fa814397 100644 --- a/doric-demo/src/StorageDemo.ts +++ b/doric-demo/src/StorageDemo.ts @@ -17,7 +17,7 @@ class StorageDemo extends Panel { scroller(vlayout([ text({ text: "Storage Demo", - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[1], @@ -26,7 +26,7 @@ class StorageDemo extends Panel { }), label('Stored'), text({ - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 20, textColor: Color.WHITE, backgroundColor: colors[3], @@ -39,7 +39,7 @@ class StorageDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { storage(context).getItem(storedKey, zone).then(e => { modal(context).prompt({ @@ -60,7 +60,7 @@ class StorageDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { storage(context).remove(storedKey, zone).then(e => { this.update() @@ -73,7 +73,7 @@ class StorageDemo extends Panel { backgroundColor: colors[0], textSize: 30, textColor: Color.WHITE, - layoutConfig: layoutConfig().exactly(), + layoutConfig: layoutConfig().just(), onClick: () => { storage(context).clear(zone).then(e => { this.update() @@ -81,11 +81,11 @@ class StorageDemo extends Panel { }, } as IText), ]).apply({ - layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), gravity: gravity().center(), space: 10, } as IVLayout)).apply({ - layoutConfig: layoutConfig().atmost(), + layoutConfig: layoutConfig().most(), }).in(root) this.update() } diff --git a/doric-demo/src/utils.ts b/doric-demo/src/utils.ts index 9e7e7610..96e1847d 100644 --- a/doric-demo/src/utils.ts +++ b/doric-demo/src/utils.ts @@ -39,7 +39,7 @@ export function boxStr(str: string, idx = 0) { export function title(str: string) { return text({ text: str, - layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), textSize: 30, textColor: Color.WHITE, backgroundColor: colors[1], @@ -48,12 +48,12 @@ export function title(str: string) { }) } -export function rotatedArrow(context: BridgeContext) { +export function rotatedArrow() { let refreshImage: Image - return pullable(context, + return pullable( stack([ image({ - layoutConfig: layoutConfig().exactly().m({ top: 50, bottom: 10, }), + layoutConfig: layoutConfig().just().configMargin({ top: 50, bottom: 10, }), width: 30, height: 30, imageBase64: icon_refresh,